X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Ftrace_backtrace.cpp;h=ba2a3739a6082b48a03e036bd0f4976c23c56f55;hb=dfd413a5f54bd450850b5e84886949bcdf85b1e7;hp=831de680c0aa1759b793ff89d1143b964e5f0777;hpb=1beb93552d7dab96e4e2dd1b84d831c019ae7fb9;p=apitrace diff --git a/common/trace_backtrace.cpp b/common/trace_backtrace.cpp index 831de68..ba2a373 100644 --- a/common/trace_backtrace.cpp +++ b/common/trace_backtrace.cpp @@ -33,7 +33,7 @@ #include "trace_backtrace.hpp" -#if defined(ANDROID) or defined(__linux__) +#if defined(ANDROID) || defined(__ELF__) #include #include "os.hpp" @@ -112,7 +112,7 @@ bool backtrace_is_needed(const char* fname) { } /* namespace trace */ -#ifdef ANDROID +#if defined(ANDROID) #include #include "os.hpp" @@ -270,18 +270,15 @@ std::vector get_backtrace() { } /* end ANDROID */ -#elif defined __linux__ +#elif defined(__ELF__) #include #include -#include -#include -#include #include #include -#include +#include -#include "backtrace.h" +#include namespace trace { @@ -334,6 +331,9 @@ class libbacktraceProvider { frame.linenumber = line; if (func) frame.function = func; + int status; + if (func && (func = abi::__cxa_demangle(func, NULL, NULL, &status))) + frame.function = func; this_->current_frames->push_back(frame); return 0; } @@ -378,116 +378,8 @@ public: } }; -class GlibcBacktraceProvider { -private: - std::map cache; - /* - * Backtrace being returned by glibc backtrace() contains stack frames - * belonging to apitrace wrapper module. We count the number of apitrace - * functions on the stack to avoid recording these frames. - */ - int numOfNestedFunctions; - Id nextFrameId; -private: -/* - * Parse a stack frame, expecting: - * /lib/libc.so.6.1(__libc_start_main+0x50308) [0x2000000000097630] - * or - * /lib/libc.so.6.1(+0x50308) [0x2000000000097630] - * or - * /lib/libc.so.6.1() [0x2000000000097630] - */ - RawStackFrame* parseFrame(void* frame, char* frame_symbol) { - if (cache.find(frame) == cache.end()) { - char* frame_symbol_copy = new char[strlen(frame_symbol) + 1]; - strcpy(frame_symbol_copy, frame_symbol); - RawStackFrame* parsedFrame = new RawStackFrame; - parsedFrame->id = nextFrameId++; - char* frame_it = frame_symbol_copy; - parsedFrame->module = frame_it; - char* offset = NULL; - while (true) { - switch (*frame_it) { - case '(': - *frame_it = '\0'; - frame_it++; - if (*frame_it != ')' && *frame_it != '+') { - parsedFrame->function = frame_it; - while (*frame_it != '+' && *frame_it != ')') { - frame_it++; - } - *frame_it = '\0'; - frame_it++; - } - break; - case '[': - *frame_it = '\0'; - frame_it++; - offset = frame_it; - break; - case ']': - *frame_it = '\0'; - sscanf(offset, "%llx", &parsedFrame->offset); - cache[frame] = parsedFrame; - return parsedFrame; - case '\0': - cache[frame] = NULL; - delete[] frame_symbol_copy; - delete[] parsedFrame; - return NULL; - default: - frame_it++; - } - } - } - else { - return cache[frame]; - } - } -public: - GlibcBacktraceProvider() : - numOfNestedFunctions(0), - nextFrameId(0) - {} - - std::vector getParsedBacktrace() { - std::vector parsedBacktrace; - void *array[numOfNestedFunctions + BT_DEPTH]; - size_t size; - char **strings; - size_t i; - const char* firstModule; - size = backtrace(array, numOfNestedFunctions + BT_DEPTH); - strings = backtrace_symbols(array, size); - for (i = numOfNestedFunctions; i < size; i++) { - RawStackFrame* parsedFrame = parseFrame(array[i], strings[i]); - if (numOfNestedFunctions == 0) { - if (i == 0) { - firstModule = parsedFrame->module; - } - else { - if (strcmp(firstModule, parsedFrame->module)) { - numOfNestedFunctions = i; - free(strings); - parsedBacktrace = getParsedBacktrace(); - numOfNestedFunctions--; - return parsedBacktrace; - } - } - } else { - if (parsedFrame != NULL) { - parsedBacktrace.push_back(*parsedFrame); - } - } - } - free(strings); - return parsedBacktrace; - } -}; - - std::vector get_backtrace() { - static GlibcBacktraceProvider backtraceProvider; + static libbacktraceProvider backtraceProvider; return backtraceProvider.getParsedBacktrace(); }