| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2006 The WebRTC Project Authors. All rights reserved. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license | |
| 5 * that can be found in the LICENSE file in the root of the source | |
| 6 * tree. An additional intellectual property rights grant can be found | |
| 7 * in the file PATENTS. All contributing project authors may | |
| 8 * be found in the AUTHORS file in the root of the source tree. | |
| 9 */ | |
| 10 | |
| 11 // Most of this was borrowed (with minor modifications) from V8's and Chromium's | |
| 12 // src/base/logging.cc. | |
| 13 | |
| 14 // Use the C++ version to provide __GLIBCXX__. | |
| 15 #include <cstdarg> | |
| 16 #include <cstdio> | |
| 17 #include <cstdlib> | |
| 18 | |
| 19 #if defined(__GLIBCXX__) && !defined(__UCLIBC__) | |
| 20 #include <cxxabi.h> | |
| 21 #include <execinfo.h> | |
| 22 #endif | |
| 23 | |
| 24 #if defined(WEBRTC_ANDROID) | |
| 25 #define RTC_LOG_TAG "rtc" | |
| 26 #include <android/log.h> // NOLINT | |
| 27 #endif | |
| 28 | |
| 29 #if defined(WEBRTC_WIN) | |
| 30 #include <windows.h> | |
| 31 #endif | |
| 32 | |
| 33 #include "webrtc/base/checks.h" | |
| 34 #include "webrtc/base/logging.h" | |
| 35 | |
| 36 #if defined(_MSC_VER) | |
| 37 // Warning C4722: destructor never returns, potential memory leak. | |
| 38 // FatalMessage's dtor very intentionally aborts. | |
| 39 #pragma warning(disable:4722) | |
| 40 #endif | |
| 41 | |
| 42 namespace rtc { | |
| 43 | |
| 44 void VPrintError(const char* format, va_list args) { | |
| 45 #if defined(WEBRTC_ANDROID) | |
| 46 __android_log_vprint(ANDROID_LOG_ERROR, RTC_LOG_TAG, format, args); | |
| 47 #else | |
| 48 vfprintf(stderr, format, args); | |
| 49 #endif | |
| 50 } | |
| 51 | |
| 52 void PrintError(const char* format, ...) { | |
| 53 va_list args; | |
| 54 va_start(args, format); | |
| 55 VPrintError(format, args); | |
| 56 va_end(args); | |
| 57 } | |
| 58 | |
| 59 // TODO(ajm): This works on Mac (although the parsing fails) but I don't seem | |
| 60 // to get usable symbols on Linux. This is copied from V8. Chromium has a more | |
| 61 // advanced stace trace system; also more difficult to copy. | |
| 62 void DumpBacktrace() { | |
| 63 #if defined(__GLIBCXX__) && !defined(__UCLIBC__) | |
| 64 void* trace[100]; | |
| 65 int size = backtrace(trace, sizeof(trace) / sizeof(*trace)); | |
| 66 char** symbols = backtrace_symbols(trace, size); | |
| 67 PrintError("\n==== C stack trace ===============================\n\n"); | |
| 68 if (size == 0) { | |
| 69 PrintError("(empty)\n"); | |
| 70 } else if (symbols == nullptr) { | |
| 71 PrintError("(no symbols)\n"); | |
| 72 } else { | |
| 73 for (int i = 1; i < size; ++i) { | |
| 74 char mangled[201]; | |
| 75 if (sscanf(symbols[i], "%*[^(]%*[(]%200[^)+]", mangled) == 1) { // NOLINT | |
| 76 PrintError("%2d: ", i); | |
| 77 int status; | |
| 78 size_t length; | |
| 79 char* demangled = | |
| 80 abi::__cxa_demangle(mangled, nullptr, &length, &status); | |
| 81 PrintError("%s\n", demangled != nullptr ? demangled : mangled); | |
| 82 free(demangled); | |
| 83 } else { | |
| 84 // If parsing failed, at least print the unparsed symbol. | |
| 85 PrintError("%s\n", symbols[i]); | |
| 86 } | |
| 87 } | |
| 88 } | |
| 89 free(symbols); | |
| 90 #endif | |
| 91 } | |
| 92 | |
| 93 FatalMessage::FatalMessage(const char* file, int line) { | |
| 94 Init(file, line); | |
| 95 } | |
| 96 | |
| 97 FatalMessage::FatalMessage(const char* file, int line, std::string* result) { | |
| 98 Init(file, line); | |
| 99 stream_ << "Check failed: " << *result << std::endl << "# "; | |
| 100 delete result; | |
| 101 } | |
| 102 | |
| 103 NO_RETURN FatalMessage::~FatalMessage() { | |
| 104 fflush(stdout); | |
| 105 fflush(stderr); | |
| 106 stream_ << std::endl << "#" << std::endl; | |
| 107 PrintError(stream_.str().c_str()); | |
| 108 DumpBacktrace(); | |
| 109 fflush(stderr); | |
| 110 abort(); | |
| 111 } | |
| 112 | |
| 113 void FatalMessage::Init(const char* file, int line) { | |
| 114 stream_ << std::endl << std::endl | |
| 115 << "#" << std::endl | |
| 116 << "# Fatal error in " << file << ", line " << line << std::endl | |
| 117 << "# last system error: " << LAST_SYSTEM_ERROR << std::endl | |
| 118 << "# "; | |
| 119 } | |
| 120 | |
| 121 // MSVC doesn't like complex extern templates and DLLs. | |
| 122 #if !defined(COMPILER_MSVC) | |
| 123 // Explicit instantiations for commonly used comparisons. | |
| 124 template std::string* MakeCheckOpString<int, int>( | |
| 125 const int&, const int&, const char* names); | |
| 126 template std::string* MakeCheckOpString<unsigned long, unsigned long>( | |
| 127 const unsigned long&, const unsigned long&, const char* names); | |
| 128 template std::string* MakeCheckOpString<unsigned long, unsigned int>( | |
| 129 const unsigned long&, const unsigned int&, const char* names); | |
| 130 template std::string* MakeCheckOpString<unsigned int, unsigned long>( | |
| 131 const unsigned int&, const unsigned long&, const char* names); | |
| 132 template std::string* MakeCheckOpString<std::string, std::string>( | |
| 133 const std::string&, const std::string&, const char* name); | |
| 134 #endif | |
| 135 | |
| 136 } // namespace rtc | |
| 137 | |
| 138 // Function to call from the C version of the RTC_CHECK and RTC_DCHECK macros. | |
| 139 NO_RETURN void rtc_FatalMessage(const char* file, int line, const char* msg) { | |
| 140 rtc::FatalMessage(file, line).stream() << msg; | |
| 141 } | |
| OLD | NEW |