mfbt/Assertions.cpp
author Petru Lingurar <petru.lingurar@softvision.ro>
Fri, 21 Dec 2018 08:56:47 +0000
changeset 501492 65621d0fe1262af0643cec37c23b2d9ec42588ad
parent 485418 ef7ed9b4ee4957960bbfe6370a0282f7e362a77e
child 505342 bfb4ee856c7115899960e3bd1fcf72b5e764314d
permissions -rw-r--r--
Bug 1513938 - Enforce a Bundle size limit and drop `privateSession` if exceeds it. r=JanH, a=jcristau The `privateSession` key would normally allow persisting the Private Browsing session across OOMs in Activity's Bundle. We need to do that to avoid storing private, sensible data on disk like we do with the normal browsing session. In some cases `privateSession` would contain a lot of data which, along with other possible concurrent transactions could overflow Binder's buffer which has a limited fixed size, currently 1Mb. To avoid this, we will drop `privateSession` from the Bundle if the resulting size is greater than a _speculative_ size of 300KBs which would mean that in the case of an OOM all Private Browsing state would be lost. Bug 1515592 is filed to investigate for a better solution. Differential Revision: https://phabricator.services.mozilla.com/D15067

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"

#include <stdarg.h>

MOZ_BEGIN_EXTERN_C

/*
 * The crash reason is defined as a global variable here rather than in the
 * crash reporter itself to make it available to all code, even libraries like
 * JS that don't link with the crash reporter directly. This value will only
 * be consumed if the crash reporter is used by the target application.
 */
MFBT_DATA const char* gMozCrashReason = nullptr;

#ifndef DEBUG
MFBT_API MOZ_COLD MOZ_NORETURN MOZ_NEVER_INLINE void
MOZ_CrashOOL(int aLine, const char* aReason)
#else
MFBT_API MOZ_COLD MOZ_NORETURN MOZ_NEVER_INLINE void
MOZ_CrashOOL(const char* aFilename, int aLine, const char* aReason)
#endif
{
#ifdef DEBUG
  MOZ_ReportCrash(aReason, aFilename, aLine);
#endif
  gMozCrashReason = aReason;
  MOZ_REALLY_CRASH(aLine);
}

static char sPrintfCrashReason[sPrintfCrashReasonSize] = {};

// Accesses to this atomic are not included in web replay recordings, so that
// if we crash in an area where recorded events are not allowed the true reason
// for the crash is not obscured by a record/replay error.
static mozilla::Atomic<bool, mozilla::SequentiallyConsistent,
                       mozilla::recordreplay::Behavior::DontPreserve> sCrashing(false);

#ifndef DEBUG
MFBT_API MOZ_COLD MOZ_NORETURN MOZ_NEVER_INLINE MOZ_FORMAT_PRINTF(2, 3) void
MOZ_CrashPrintf(int aLine, const char* aFormat, ...)
#else
MFBT_API MOZ_COLD MOZ_NORETURN MOZ_NEVER_INLINE MOZ_FORMAT_PRINTF(3, 4) void
MOZ_CrashPrintf(const char* aFilename, int aLine, const char* aFormat, ...)
#endif
{
  if (!sCrashing.compareExchange(false, true)) {
    // In the unlikely event of a race condition, skip
    // setting the crash reason and just crash safely.
    MOZ_REALLY_CRASH(aLine);
  }
  va_list aArgs;
  va_start(aArgs, aFormat);
  int ret = vsnprintf(sPrintfCrashReason, sPrintfCrashReasonSize,
                      aFormat, aArgs);
  va_end(aArgs);
  MOZ_RELEASE_ASSERT(ret >= 0 && size_t(ret) < sPrintfCrashReasonSize,
    "Could not write the explanation string to the supplied buffer!");
#ifdef DEBUG
  MOZ_ReportCrash(sPrintfCrashReason, aFilename, aLine);
#endif
  gMozCrashReason = sPrintfCrashReason;
  MOZ_REALLY_CRASH(aLine);
}

MOZ_END_EXTERN_C