tor-browser

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

abort.cc (3140B)


      1 // Copyright 2019 Google LLC
      2 // Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
      3 // SPDX-License-Identifier: Apache-2.0
      4 // SPDX-License-Identifier: BSD-3-Clause
      5 
      6 #include "hwy/abort.h"
      7 
      8 #include <stdarg.h>
      9 #include <stdio.h>
     10 #include <stdlib.h>
     11 
     12 #include <atomic>
     13 #include <string>
     14 
     15 #include "hwy/base.h"
     16 
     17 #if HWY_IS_ASAN || HWY_IS_MSAN || HWY_IS_TSAN
     18 #include "sanitizer/common_interface_defs.h"  // __sanitizer_print_stack_trace
     19 #endif
     20 
     21 namespace hwy {
     22 
     23 namespace {
     24 
     25 std::atomic<WarnFunc>& AtomicWarnFunc() {
     26  static std::atomic<WarnFunc> func;
     27  return func;
     28 }
     29 
     30 std::atomic<AbortFunc>& AtomicAbortFunc() {
     31  static std::atomic<AbortFunc> func;
     32  return func;
     33 }
     34 
     35 std::string GetBaseName(std::string const& file_name) {
     36  auto last_slash = file_name.find_last_of("/\\");
     37  return file_name.substr(last_slash + 1);
     38 }
     39 
     40 }  // namespace
     41 
     42 // Returning a reference is unfortunately incompatible with `std::atomic`, which
     43 // is required to safely implement `SetWarnFunc`. As a workaround, we store a
     44 // copy here, update it when called, and return a reference to the copy. This
     45 // has the added benefit of protecting the actual pointer from modification.
     46 HWY_DLLEXPORT WarnFunc& GetWarnFunc() {
     47  static WarnFunc func;
     48  func = AtomicWarnFunc().load();
     49  return func;
     50 }
     51 
     52 HWY_DLLEXPORT AbortFunc& GetAbortFunc() {
     53  static AbortFunc func;
     54  func = AtomicAbortFunc().load();
     55  return func;
     56 }
     57 
     58 HWY_DLLEXPORT WarnFunc SetWarnFunc(WarnFunc func) {
     59  return AtomicWarnFunc().exchange(func);
     60 }
     61 
     62 HWY_DLLEXPORT AbortFunc SetAbortFunc(AbortFunc func) {
     63  return AtomicAbortFunc().exchange(func);
     64 }
     65 
     66 HWY_DLLEXPORT void HWY_FORMAT(3, 4)
     67    Warn(const char* file, int line, const char* format, ...) {
     68  char buf[800];
     69  va_list args;
     70  va_start(args, format);
     71  vsnprintf(buf, sizeof(buf), format, args);
     72  va_end(args);
     73 
     74  WarnFunc handler = AtomicWarnFunc().load();
     75  if (handler != nullptr) {
     76    handler(file, line, buf);
     77  } else {
     78    fprintf(stderr, "Warn at %s:%d: %s\n", GetBaseName(file).data(), line, buf);
     79  }
     80 }
     81 
     82 HWY_DLLEXPORT HWY_NORETURN void HWY_FORMAT(3, 4)
     83    Abort(const char* file, int line, const char* format, ...) {
     84  char buf[800];
     85  va_list args;
     86  va_start(args, format);
     87  vsnprintf(buf, sizeof(buf), format, args);
     88  va_end(args);
     89 
     90  AbortFunc handler = AtomicAbortFunc().load();
     91  if (handler != nullptr) {
     92    handler(file, line, buf);
     93  } else {
     94    fprintf(stderr, "Abort at %s:%d: %s\n", GetBaseName(file).data(), line,
     95            buf);
     96  }
     97 
     98 // If compiled with any sanitizer, they can also print a stack trace.
     99 #if HWY_IS_ASAN || HWY_IS_MSAN || HWY_IS_TSAN
    100  __sanitizer_print_stack_trace();
    101 #endif  // HWY_IS_*
    102  fflush(stderr);
    103 
    104 // Now terminate the program:
    105 #if HWY_ARCH_RISCV
    106  exit(1);  // trap/abort just freeze Spike.
    107 #elif HWY_IS_DEBUG_BUILD && !HWY_COMPILER_MSVC && !HWY_ARCH_ARM
    108  // Facilitates breaking into a debugger, but don't use this in non-debug
    109  // builds because it looks like "illegal instruction", which is misleading.
    110  // Also does not work on Arm.
    111  __builtin_trap();
    112 #else
    113  abort();  // Compile error without this due to HWY_NORETURN.
    114 #endif
    115 }
    116 
    117 }  // namespace hwy