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 LOG_TAG "rtc" 26#include <android/log.h> // NOLINT 27#endif 28 29#include "webrtc/base/checks.h" 30 31#if defined(_MSC_VER) 32// Warning C4722: destructor never returns, potential memory leak. 33// FatalMessage's dtor very intentionally aborts. 34#pragma warning(disable:4722) 35#endif 36 37namespace rtc { 38 39void VPrintError(const char* format, va_list args) { 40#if defined(WEBRTC_ANDROID) 41 __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, format, args); 42#else 43 vfprintf(stderr, format, args); 44#endif 45} 46 47void PrintError(const char* format, ...) { 48 va_list args; 49 va_start(args, format); 50 VPrintError(format, args); 51 va_end(args); 52} 53 54// TODO(ajm): This works on Mac (although the parsing fails) but I don't seem 55// to get usable symbols on Linux. This is copied from V8. Chromium has a more 56// advanced stace trace system; also more difficult to copy. 57void DumpBacktrace() { 58#if defined(__GLIBCXX__) && !defined(__UCLIBC__) 59 void* trace[100]; 60 int size = backtrace(trace, sizeof(trace) / sizeof(*trace)); 61 char** symbols = backtrace_symbols(trace, size); 62 PrintError("\n==== C stack trace ===============================\n\n"); 63 if (size == 0) { 64 PrintError("(empty)\n"); 65 } else if (symbols == NULL) { 66 PrintError("(no symbols)\n"); 67 } else { 68 for (int i = 1; i < size; ++i) { 69 char mangled[201]; 70 if (sscanf(symbols[i], "%*[^(]%*[(]%200[^)+]", mangled) == 1) { // NOLINT 71 PrintError("%2d: ", i); 72 int status; 73 size_t length; 74 char* demangled = abi::__cxa_demangle(mangled, NULL, &length, &status); 75 PrintError("%s\n", demangled != NULL ? demangled : mangled); 76 free(demangled); 77 } else { 78 // If parsing failed, at least print the unparsed symbol. 79 PrintError("%s\n", symbols[i]); 80 } 81 } 82 } 83 free(symbols); 84#endif 85} 86 87FatalMessage::FatalMessage(const char* file, int line) { 88 Init(file, line); 89} 90 91FatalMessage::FatalMessage(const char* file, int line, std::string* result) { 92 Init(file, line); 93 stream_ << "Check failed: " << *result << std::endl << "# "; 94 delete result; 95} 96 97NO_RETURN FatalMessage::~FatalMessage() { 98 fflush(stdout); 99 fflush(stderr); 100 stream_ << std::endl << "#" << std::endl; 101 PrintError(stream_.str().c_str()); 102 DumpBacktrace(); 103 fflush(stderr); 104 abort(); 105} 106 107void FatalMessage::Init(const char* file, int line) { 108 stream_ << std::endl << std::endl << "#" << std::endl << "# Fatal error in " 109 << file << ", line " << line << std::endl << "# "; 110} 111 112// Refer to comments in checks.h. 113#ifndef WEBRTC_CHROMIUM_BUILD 114 115// MSVC doesn't like complex extern templates and DLLs. 116#if !defined(COMPILER_MSVC) 117// Explicit instantiations for commonly used comparisons. 118template std::string* MakeCheckOpString<int, int>( 119 const int&, const int&, const char* names); 120template std::string* MakeCheckOpString<unsigned long, unsigned long>( 121 const unsigned long&, const unsigned long&, const char* names); 122template std::string* MakeCheckOpString<unsigned long, unsigned int>( 123 const unsigned long&, const unsigned int&, const char* names); 124template std::string* MakeCheckOpString<unsigned int, unsigned long>( 125 const unsigned int&, const unsigned long&, const char* names); 126template std::string* MakeCheckOpString<std::string, std::string>( 127 const std::string&, const std::string&, const char* name); 128#endif 129 130#endif // WEBRTC_CHROMIUM_BUILD 131 132} // namespace rtc 133