tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Assertions.cpp (2719B)


      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 #include "mozilla/Sprintf.h"
      9 
     10 #include <stdarg.h>
     11 #include <string.h>
     12 #include "fmt/format.h"
     13 
     14 MOZ_BEGIN_EXTERN_C
     15 
     16 /*
     17 * The crash reason is defined as a global variable here rather than in the
     18 * crash reporter itself to make it available to all code, even libraries like
     19 * JS that don't link with the crash reporter directly. This value will only
     20 * be consumed if the crash reporter is used by the target application.
     21 */
     22 MFBT_DATA const char* gMozCrashReason = nullptr;
     23 
     24 static char sPrintfCrashReason[sPrintfCrashReasonSize] = {};
     25 
     26 // Accesses to this atomic are not included in web replay recordings, so that
     27 // if we crash in an area where recorded events are not allowed the true reason
     28 // for the crash is not obscured by a record/replay error.
     29 static mozilla::Atomic<bool, mozilla::SequentiallyConsistent> sCrashing(false);
     30 
     31 MFBT_API MOZ_COLD MOZ_NEVER_INLINE MOZ_FORMAT_PRINTF(1, 2) const
     32    char* MOZ_CrashPrintf(const char* aFormat, ...) {
     33  if (!sCrashing.compareExchange(false, true)) {
     34    // In the unlikely event of a race condition, skip
     35    // setting the crash reason and just crash safely.
     36    MOZ_RELEASE_ASSERT(false);
     37  }
     38  va_list aArgs;
     39  va_start(aArgs, aFormat);
     40  int ret = VsprintfLiteral(sPrintfCrashReason, aFormat, aArgs);
     41  va_end(aArgs);
     42  MOZ_RELEASE_ASSERT(
     43      ret >= 0 && size_t(ret) < sPrintfCrashReasonSize,
     44      "Could not write the explanation string to the supplied buffer!");
     45  return sPrintfCrashReason;
     46 }
     47 
     48 MOZ_END_EXTERN_C
     49 
     50 #ifdef __cplusplus
     51 
     52 namespace mozilla::detail {
     53 
     54 template <typename... Args>
     55 const char* CrashFmtImpl(const char* format, Args&&... args) {
     56  if (!sCrashing.compareExchange(false, true)) {
     57    // In the unlikely event of a race condition, skip
     58    // setting the crash reason and just crash safely.
     59    MOZ_RELEASE_ASSERT(false);
     60  }
     61 
     62  // This will silently truncate the string if it's too long.
     63  auto result =
     64      fmt::vformat_to_n(sPrintfCrashReason, sPrintfCrashReasonSize - 1, format,
     65                        fmt::make_format_args(args...));
     66  sPrintfCrashReason[result.size] = '\0';
     67 
     68  return sPrintfCrashReason;
     69 }
     70 
     71 }  // namespace mozilla::detail
     72 
     73 #endif
     74 
     75 [[noreturn]] MFBT_API MOZ_COLD void mozilla::detail::InvalidArrayIndex_CRASH(
     76    size_t aIndex, size_t aLength) {
     77  MOZ_CRASH_UNSAFE_PRINTF("ElementAt(aIndex = %zu, aLength = %zu)", aIndex,
     78                          aLength);
     79 }