mfbt/Assertions.cpp
author Narcis Beleuzu <nbeleuzu@mozilla.com>
Thu, 21 Jun 2018 16:51:55 +0300
changeset 477502 59322b179c0fdb4423d42b624da7bf64ee5a2327
parent 391081 294c257938dcf6c401bbe2ba5f282a51941399ce
child 482776 ef7ed9b4ee4957960bbfe6370a0282f7e362a77e
permissions -rw-r--r--
Backed out 4 changesets (bug 1268889) for Windows GTest failures. CLOSED TREE Backed out changeset da427a67372e (bug 1268889) Backed out changeset 97528847b7b7 (bug 1268889) Backed out changeset b2320061fbcb (bug 1268889) Backed out changeset dd3b7047ea6f (bug 1268889)

/* -*- 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] = {};
static mozilla::Atomic<bool> 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