24 #include <glog/logging.h> 39 typedef StackTraceStack* (*GetExceptionStackTraceStackType)();
40 GetExceptionStackTraceStackType getExceptionStackTraceStackFn;
46 namespace exception_tracer {
57 out <<
"Exception type: ";
61 out <<
"(unknown type)";
63 out <<
" (" << info.
frames.size()
64 << (info.
frames.size() == 1 ?
" frame" :
" frames") <<
")\n";
66 size_t frameCount = info.
frames.size();
69 static constexpr
size_t kInternalFramesNumber = 3;
70 if (frameCount > kInternalFramesNumber) {
71 auto addresses = info.
frames.data() + kInternalFramesNumber;
72 frameCount -= kInternalFramesNumber;
74 std::vector<SymbolizedFrame> frames;
75 frames.resize(frameCount);
77 Symbolizer symbolizer(
78 (options & SymbolizePrinter::NO_FILE_AND_LINE)
79 ? Dwarf::LocationInfoMode::DISABLED
80 : Symbolizer::kDefaultLocationInfoMode);
81 symbolizer.symbolize(addresses, frames.data(), frameCount);
83 OStreamSymbolizePrinter osp(out, options);
84 osp.println(addresses, frames.data(), frameCount);
86 }
catch (
const std::exception& e) {
89 out <<
"\n !!! caught unexpected exception\n";
107 return (exc->
unwindHeader.exception_class & 0xffffffff) == cppClass;
118 if (!getExceptionStackTraceStackFn) {
120 getExceptionStackTraceStackFn = (GetExceptionStackTraceStackType)dlsym(
121 RTLD_NEXT,
"getExceptionStackTraceStack");
127 std::vector<ExceptionInfo> exceptions;
129 if (!currentException) {
134 if (!getExceptionStackTraceStackFn) {
135 static bool logged =
false;
138 <<
"Exception tracer library not linked, stack traces not available";
141 }
else if ((traceStack = getExceptionStackTraceStackFn()) ==
nullptr) {
142 static bool logged =
false;
145 <<
"Exception stack trace invalid, stack traces not available";
150 StackTrace* trace = traceStack ? traceStack->
top() :
nullptr;
151 while (currentException) {
157 info.
type = isAbiCppException(currentException)
158 ? currentException->exceptionType
163 <<
"Invalid trace stack for exception of type: " 172 trace = traceStack->
next(trace);
174 currentException = currentException->nextException;
178 LOG_IF(
DFATAL, trace) <<
"Invalid trace stack!";
185 std::terminate_handler origTerminate = abort;
186 std::unexpected_handler origUnexpected = abort;
188 void dumpExceptionStack(
const char*
prefix) {
190 if (exceptions.empty()) {
193 LOG(ERROR) << prefix <<
", exception stack follows";
194 for (
auto& exc : exceptions) {
195 LOG(ERROR) << exc <<
"\n";
197 LOG(ERROR) <<
"exception stack complete";
200 void terminateHandler() {
201 dumpExceptionStack(
"terminate() called");
205 void unexpectedHandler() {
206 dumpExceptionStack(
"Unexpected exception");
215 origTerminate = std::set_terminate(terminateHandler);
216 origUnexpected = std::set_unexpected(unexpectedHandler);
_Unwind_Exception unwindHeader
const std::type_info * type
fbstring exceptionStr(const std::exception &e)
constexpr detail::Map< Move > move
std::vector< uintptr_t > frames
—— Concurrent Priority Queue Implementation ——
bool prefix(Cursor &c, uint32_t expected)
uintptr_t addresses[kMaxFrames]
std::ostream & operator<<(std::ostream &out, const ExceptionInfo &info)
StackTrace * next(StackTrace *p)
StackTraceStack * getExceptionStackTraceStack()
std::vector< ExceptionInfo > getCurrentExceptions()
__cxa_eh_globals * __cxa_get_globals(void) noexcept
__attribute__((noinline, noclone)) VirtualBase *makeVirtual()
__cxa_exception * caughtExceptions
void printExceptionInfo(std::ostream &out, const ExceptionInfo &info, int options)
fbstring demangle(const char *name)