Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "mozilla/Assertions.h"
7 : #include "mozilla/Atomics.h"
8 :
9 : #include <stdarg.h>
10 :
11 : MOZ_BEGIN_EXTERN_C
12 :
13 : /*
14 : * The crash reason is defined as a global variable here rather than in the
15 : * crash reporter itself to make it available to all code, even libraries like
16 : * JS that don't link with the crash reporter directly. This value will only
17 : * be consumed if the crash reporter is used by the target application.
18 : */
19 : MFBT_DATA const char* gMozCrashReason = nullptr;
20 :
21 : #ifndef DEBUG
22 : MFBT_API MOZ_COLD MOZ_NORETURN MOZ_NEVER_INLINE void
23 : MOZ_CrashOOL(int aLine, const char* aReason)
24 : #else
25 : MFBT_API MOZ_COLD MOZ_NORETURN MOZ_NEVER_INLINE void
26 0 : MOZ_CrashOOL(const char* aFilename, int aLine, const char* aReason)
27 : #endif
28 : {
29 : #ifdef DEBUG
30 0 : MOZ_ReportCrash(aReason, aFilename, aLine);
31 : #endif
32 0 : gMozCrashReason = aReason;
33 0 : MOZ_REALLY_CRASH(aLine);
34 : }
35 :
36 : static char sPrintfCrashReason[sPrintfCrashReasonSize] = {};
37 : static mozilla::Atomic<bool> sCrashing(false);
38 :
39 : #ifndef DEBUG
40 : MFBT_API MOZ_COLD MOZ_NORETURN MOZ_NEVER_INLINE MOZ_FORMAT_PRINTF(2, 3) void
41 : MOZ_CrashPrintf(int aLine, const char* aFormat, ...)
42 : #else
43 : MFBT_API MOZ_COLD MOZ_NORETURN MOZ_NEVER_INLINE MOZ_FORMAT_PRINTF(3, 4) void
44 0 : MOZ_CrashPrintf(const char* aFilename, int aLine, const char* aFormat, ...)
45 : #endif
46 : {
47 0 : if (!sCrashing.compareExchange(false, true)) {
48 : // In the unlikely event of a race condition, skip
49 : // setting the crash reason and just crash safely.
50 0 : MOZ_REALLY_CRASH(aLine);
51 : }
52 : va_list aArgs;
53 0 : va_start(aArgs, aFormat);
54 : int ret = vsnprintf(sPrintfCrashReason, sPrintfCrashReasonSize,
55 0 : aFormat, aArgs);
56 0 : va_end(aArgs);
57 0 : MOZ_RELEASE_ASSERT(ret >= 0 && size_t(ret) < sPrintfCrashReasonSize,
58 : "Could not write the explanation string to the supplied buffer!");
59 : #ifdef DEBUG
60 0 : MOZ_ReportCrash(sPrintfCrashReason, aFilename, aLine);
61 : #endif
62 0 : gMozCrashReason = sPrintfCrashReason;
63 0 : MOZ_REALLY_CRASH(aLine);
64 : }
65 :
66 : MOZ_END_EXTERN_C
|