From: Alexander Monakov Date: Fri, 12 Jul 2013 17:26:25 +0000 (+0400) Subject: common: rename trace_backtrace.* -> os_backtrace.* X-Git-Url: https://git.cworth.org/git?p=apitrace;a=commitdiff_plain;h=cad5d619dcb5e1c6349bfff69176660668402622 common: rename trace_backtrace.* -> os_backtrace.* --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 0775119..b2de6bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,7 +331,7 @@ add_library (common STATIC common/trace_profiler.cpp common/trace_option.cpp common/${os} - common/trace_backtrace.cpp + common/os_backtrace.cpp ) set_target_properties (common PROPERTIES diff --git a/common/os_backtrace.cpp b/common/os_backtrace.cpp new file mode 100644 index 0000000..eb809e0 --- /dev/null +++ b/common/os_backtrace.cpp @@ -0,0 +1,390 @@ +/************************************************************************** + * + * Copyright 2013 Samsung + * Contributed by Eugene Velesevich + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +/* + * Wrapper for platform-specific code for obtaining symbolic backtraces + * on Android and Linux + */ + + + +#include "os_backtrace.hpp" + +#if defined(ANDROID) || defined(__ELF__) + +#include +#include "os.hpp" + + +namespace trace { + +/* + * Pascal string (with zero terminator optionally omitted) + * This is a helper class for storing a set of exact strings or prefixes + * to match a zero-terminated string against later. + * Two zero-terminated pstrings compare equal iff they are the same. + * Otherwise, they compare equal iff one is a prefix of the other + * (a zero-terminated pstring cannot be a prefix) + */ + +struct pstring { + const char* s; + int n; + pstring(const char* s, int n) + { + this->s = s; + this->n = n; + } + bool operator<(const pstring q2) const + { + return memcmp(s, q2.s, n < q2.n? n : q2.n) < 0; + } +}; + + +class StringPrefixes { +private: + std::set pset; + + void addPrefix(char* startbuf, int n) { + std::set::iterator elem = pset.find(pstring(startbuf, n)); + bool replace = elem != pset.end() && n < elem->n; + if (replace) { + pset.erase(elem); + } + if (replace || elem == pset.end()) { + pset.insert(pstring(startbuf, n)); + } + } +public: + StringPrefixes(); + + bool contain(const char* s) { + return pset.find(pstring(s, strlen(s) + 1)) != pset.end(); + } +}; + +StringPrefixes::StringPrefixes() { + char *list = getenv("APITRACE_BACKTRACE"); + if (!list) + return; + for (char *t = strdup(list); ; t = NULL) { + char *tok = strtok(t, " \t\r\n"); + if (!tok) + break; + if (tok[0] == '#') + continue; + if (tok[strlen(tok) - 1] == '*') + addPrefix(tok, strlen(tok) - 1); + else + addPrefix(tok, strlen(tok) + 1); + } +} + + +bool backtrace_is_needed(const char* fname) { + static StringPrefixes backtraceFunctionNamePrefixes; + return backtraceFunctionNamePrefixes.contain(fname); +} + +} /* namespace trace */ + +#if defined(ANDROID) + +#include +#include "os.hpp" +#include + +namespace trace { + +/* The following two declarations are copied from Android sources */ + +enum DebugTargetKind { + kDebugTargetUnknown = 0, + kDebugTargetLog, + kDebugTargetFile, +}; + +struct DebugOutputTarget { + DebugTargetKind which; + + union { + struct { + int priority; + const char* tag; + } log; + struct { + FILE* fp; + } file; + } data; +}; + +#define THREAD_SELF_NAME "_Z13dvmThreadSelfv" +#define CREATE_DEBUG_TARGET_NAME "_Z25dvmCreateFileOutputTargetP17DebugOutputTargetP7__sFILE" +#define DUMP_BACKTRACE_NAME "_Z18dvmDumpThreadStackPK17DebugOutputTargetP6Thread" + + +class DalvikBacktraceProvider { +private: + bool errorOccured; + void* (*threadself)(void); + FILE* streamInMemory; + char* buf; + size_t bufSize; + void (*dumpBacktrace)(const DebugOutputTarget*, void*); + DebugOutputTarget debugTarget; + Id nextFrameId; +public: + DalvikBacktraceProvider() { + nextFrameId = 0; + FILE* (*open_memstream_exp)(char**, size_t*); + void (*createDebugTarget)(DebugOutputTarget*, FILE*); + void* handle = dlopen("/system/lib/libdvm.so", 0); + errorOccured = true; + if (!handle) { + os::log("dlopen failed\n"); + return; + } + threadself = (void* (*)())dlsym(handle, THREAD_SELF_NAME); + if (threadself == NULL) { + os::log("dlsym ThreadSelf failed\n"); + return; + } + createDebugTarget = (void (*)(DebugOutputTarget*, FILE*))dlsym(handle, CREATE_DEBUG_TARGET_NAME); + if (createDebugTarget == NULL) { + os::log("dlsym CreateFileOutput failed\n"); + return; + } + dumpBacktrace = (void (*)(const DebugOutputTarget*, void*))dlsym(handle, DUMP_BACKTRACE_NAME); + if (dumpBacktrace == NULL) { + os::log("dlsym DumpThreadStack failed\n"); + return; + } + void* handle2 = dlopen("/system/lib/libcutils.so", 0); + if (!handle2) { + os::log("dlopen failed\n"); + return; + } + open_memstream_exp = (FILE* (*)(char**, size_t*))dlsym(handle2, "open_memstream"); + if (open_memstream_exp == NULL) { + os::log("dlsym open_memstream failed\n"); + return; + } + streamInMemory = open_memstream_exp(&buf, &bufSize); + if (streamInMemory == NULL) { + os::log("open_memstream failed\n"); + return; + } + createDebugTarget(&debugTarget, streamInMemory); + errorOccured = false; + } + + inline char* getBacktrace() { + if (errorOccured) { + return NULL; + } + rewind(streamInMemory); + dumpBacktrace(&debugTarget, threadself()); + fflush(streamInMemory); + return buf; + } +/* + * Parse a stack frame, expecting: + * " at android.view.HardwareRenderer$GlRenderer.initializeEgl(HardwareRenderer.java:547)" + * or + * " at android.view.HardwareRenderer$GlRenderer.initializeEgl(Native Method)" + */ + std::vector parseBacktrace(char *rawBacktrace) { + std::vector parsedBacktrace; + char* rawBacktrace_it = rawBacktrace; + while (*rawBacktrace_it != '\0') { + RawStackFrame stackFrame; + // TODO: Keep a cache of stack frames + stackFrame.id = nextFrameId++; + /* skip leading space */ + while (*rawBacktrace_it == ' ') { + rawBacktrace_it++; + } + /* Skip "at " */ + rawBacktrace_it += 3; + stackFrame.function = rawBacktrace_it; + while (*rawBacktrace_it != '(') { + rawBacktrace_it++; + } + *rawBacktrace_it = '\0'; + stackFrame.filename = rawBacktrace_it + 1; + while (*rawBacktrace_it != ':' && *rawBacktrace_it != ')') { + rawBacktrace_it++; + } + if (*rawBacktrace_it == ':') { + const char *linenumber = rawBacktrace_it + 1; + *rawBacktrace_it = '\0'; + while (*rawBacktrace_it != ')') { + rawBacktrace_it++; + } + *rawBacktrace_it = '\0'; + rawBacktrace_it++; + stackFrame.linenumber = atoi(linenumber); + } + else { + stackFrame.filename = NULL; + while (*rawBacktrace_it != '\n') { + rawBacktrace_it++; + } + } + while (*rawBacktrace_it == '\n' || *rawBacktrace_it == ' ') { + rawBacktrace_it++; + } + parsedBacktrace.push_back(stackFrame); /* module */ + } + return parsedBacktrace; + } +}; + +std::vector get_backtrace() { + static DalvikBacktraceProvider backtraceProvider; + return backtraceProvider.parseBacktrace(backtraceProvider.getBacktrace()); +} + +/* end ANDROID */ +#elif defined(__ELF__) + +#include +#include +#include +#include +#include + +#include + +namespace trace { + + + + +#define BT_DEPTH 10 + +class libbacktraceProvider { + struct backtrace_state *state; + int skipFrames; + Id nextFrameId; + std::map > cache; + std::vector *current, *current_frames; + RawStackFrame *current_frame; + + static void bt_err_callback(void *vdata, const char *msg, int errnum) + { + if (errnum == -1) + return;// no debug/sym info + else if (errnum) + os::log("libbacktrace: %s: %s\n", msg, strerror(errnum)); + else + os::log("libbacktrace: %s\n", msg); + } + + static int bt_countskip(void *vdata, uintptr_t pc) + { + libbacktraceProvider *this_ = (libbacktraceProvider*)vdata; + Dl_info info1, info2; + if (!dladdr((void*)bt_countskip, &info2)) { + os::log("dladdr failed, cannot cull stack traces\n"); + return 1; + } + if (!dladdr((void*)pc, &info1)) + return 1; + if (info1.dli_fbase != info2.dli_fbase) + return 1; + this_->skipFrames++; + return 0; + } + + static int bt_full_callback(void *vdata, uintptr_t pc, + const char *file, int line, const char *func) + { + libbacktraceProvider *this_ = (libbacktraceProvider*)vdata; + RawStackFrame frame = *this_->current_frame; + frame.id = this_->nextFrameId++; + frame.filename = file; + 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; + } + + static int bt_callback(void *vdata, uintptr_t pc) + { + libbacktraceProvider *this_ = (libbacktraceProvider*)vdata; + std::vector &frames = this_->cache[pc]; + if (!frames.size()) { + RawStackFrame frame; + Dl_info info = {0}; + dladdr((void*)pc, &info); + frame.module = info.dli_fname; + frame.function = info.dli_sname; + frame.offset = info.dli_saddr ? pc - (uintptr_t)info.dli_saddr + : pc - (uintptr_t)info.dli_fbase; + this_->current_frame = &frame; + this_->current_frames = &frames; + backtrace_pcinfo(this_->state, pc, bt_full_callback, bt_err_callback, vdata); + if (!frames.size()) { + frame.id = this_->nextFrameId++; + frames.push_back(frame); + } + } + this_->current->insert(this_->current->end(), frames.begin(), frames.end()); + return this_->current->size() >= BT_DEPTH; + } + +public: + libbacktraceProvider(): + state(backtrace_create_state(NULL, 0, bt_err_callback, NULL)) + { + backtrace_simple(state, 0, bt_countskip, bt_err_callback, this); + } + + std::vector getParsedBacktrace() + { + std::vector parsedBacktrace; + current = &parsedBacktrace; + backtrace_simple(state, skipFrames, bt_callback, bt_err_callback, this); + return parsedBacktrace; + } +}; + +std::vector get_backtrace() { + static libbacktraceProvider backtraceProvider; + return backtraceProvider.getParsedBacktrace(); +} + +#endif /* LINUX */ + +} /* namespace trace */ + +#endif /* ANDROID or LINUX */ diff --git a/common/os_backtrace.hpp b/common/os_backtrace.hpp new file mode 100644 index 0000000..bfb0ffd --- /dev/null +++ b/common/os_backtrace.hpp @@ -0,0 +1,56 @@ +/************************************************************************** + * + * Copyright 2013 Samsung + * Contributed by Eugene Velesevich + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _OS_BACKTRACE_HPP_ +#define _OS_BACKTRACE_HPP_ + +#include + +#include "trace_model.hpp" + +namespace trace { + + +#if defined(ANDROID) || defined(__ELF__) + +std::vector get_backtrace(); +bool backtrace_is_needed(const char* fname); + +#else + +static inline std::vector get_backtrace() { + return std::vector(); +} + +static inline bool backtrace_is_needed(const char*) { + return false; +} + +#endif + +} /* namespace trace */ + +#endif diff --git a/common/trace_backtrace.cpp b/common/trace_backtrace.cpp deleted file mode 100644 index ba2a373..0000000 --- a/common/trace_backtrace.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/************************************************************************** - * - * Copyright 2013 Samsung - * Contributed by Eugene Velesevich - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - -/* - * Wrapper for platform-specific code for obtaining symbolic backtraces - * on Android and Linux - */ - - - -#include "trace_backtrace.hpp" - -#if defined(ANDROID) || defined(__ELF__) - -#include -#include "os.hpp" - - -namespace trace { - -/* - * Pascal string (with zero terminator optionally omitted) - * This is a helper class for storing a set of exact strings or prefixes - * to match a zero-terminated string against later. - * Two zero-terminated pstrings compare equal iff they are the same. - * Otherwise, they compare equal iff one is a prefix of the other - * (a zero-terminated pstring cannot be a prefix) - */ - -struct pstring { - const char* s; - int n; - pstring(const char* s, int n) - { - this->s = s; - this->n = n; - } - bool operator<(const pstring q2) const - { - return memcmp(s, q2.s, n < q2.n? n : q2.n) < 0; - } -}; - - -class StringPrefixes { -private: - std::set pset; - - void addPrefix(char* startbuf, int n) { - std::set::iterator elem = pset.find(pstring(startbuf, n)); - bool replace = elem != pset.end() && n < elem->n; - if (replace) { - pset.erase(elem); - } - if (replace || elem == pset.end()) { - pset.insert(pstring(startbuf, n)); - } - } -public: - StringPrefixes(); - - bool contain(const char* s) { - return pset.find(pstring(s, strlen(s) + 1)) != pset.end(); - } -}; - -StringPrefixes::StringPrefixes() { - char *list = getenv("APITRACE_BACKTRACE"); - if (!list) - return; - for (char *t = strdup(list); ; t = NULL) { - char *tok = strtok(t, " \t\r\n"); - if (!tok) - break; - if (tok[0] == '#') - continue; - if (tok[strlen(tok) - 1] == '*') - addPrefix(tok, strlen(tok) - 1); - else - addPrefix(tok, strlen(tok) + 1); - } -} - - -bool backtrace_is_needed(const char* fname) { - static StringPrefixes backtraceFunctionNamePrefixes; - return backtraceFunctionNamePrefixes.contain(fname); -} - -} /* namespace trace */ - -#if defined(ANDROID) - -#include -#include "os.hpp" -#include - -namespace trace { - -/* The following two declarations are copied from Android sources */ - -enum DebugTargetKind { - kDebugTargetUnknown = 0, - kDebugTargetLog, - kDebugTargetFile, -}; - -struct DebugOutputTarget { - DebugTargetKind which; - - union { - struct { - int priority; - const char* tag; - } log; - struct { - FILE* fp; - } file; - } data; -}; - -#define THREAD_SELF_NAME "_Z13dvmThreadSelfv" -#define CREATE_DEBUG_TARGET_NAME "_Z25dvmCreateFileOutputTargetP17DebugOutputTargetP7__sFILE" -#define DUMP_BACKTRACE_NAME "_Z18dvmDumpThreadStackPK17DebugOutputTargetP6Thread" - - -class DalvikBacktraceProvider { -private: - bool errorOccured; - void* (*threadself)(void); - FILE* streamInMemory; - char* buf; - size_t bufSize; - void (*dumpBacktrace)(const DebugOutputTarget*, void*); - DebugOutputTarget debugTarget; - Id nextFrameId; -public: - DalvikBacktraceProvider() { - nextFrameId = 0; - FILE* (*open_memstream_exp)(char**, size_t*); - void (*createDebugTarget)(DebugOutputTarget*, FILE*); - void* handle = dlopen("/system/lib/libdvm.so", 0); - errorOccured = true; - if (!handle) { - os::log("dlopen failed\n"); - return; - } - threadself = (void* (*)())dlsym(handle, THREAD_SELF_NAME); - if (threadself == NULL) { - os::log("dlsym ThreadSelf failed\n"); - return; - } - createDebugTarget = (void (*)(DebugOutputTarget*, FILE*))dlsym(handle, CREATE_DEBUG_TARGET_NAME); - if (createDebugTarget == NULL) { - os::log("dlsym CreateFileOutput failed\n"); - return; - } - dumpBacktrace = (void (*)(const DebugOutputTarget*, void*))dlsym(handle, DUMP_BACKTRACE_NAME); - if (dumpBacktrace == NULL) { - os::log("dlsym DumpThreadStack failed\n"); - return; - } - void* handle2 = dlopen("/system/lib/libcutils.so", 0); - if (!handle2) { - os::log("dlopen failed\n"); - return; - } - open_memstream_exp = (FILE* (*)(char**, size_t*))dlsym(handle2, "open_memstream"); - if (open_memstream_exp == NULL) { - os::log("dlsym open_memstream failed\n"); - return; - } - streamInMemory = open_memstream_exp(&buf, &bufSize); - if (streamInMemory == NULL) { - os::log("open_memstream failed\n"); - return; - } - createDebugTarget(&debugTarget, streamInMemory); - errorOccured = false; - } - - inline char* getBacktrace() { - if (errorOccured) { - return NULL; - } - rewind(streamInMemory); - dumpBacktrace(&debugTarget, threadself()); - fflush(streamInMemory); - return buf; - } -/* - * Parse a stack frame, expecting: - * " at android.view.HardwareRenderer$GlRenderer.initializeEgl(HardwareRenderer.java:547)" - * or - * " at android.view.HardwareRenderer$GlRenderer.initializeEgl(Native Method)" - */ - std::vector parseBacktrace(char *rawBacktrace) { - std::vector parsedBacktrace; - char* rawBacktrace_it = rawBacktrace; - while (*rawBacktrace_it != '\0') { - RawStackFrame stackFrame; - // TODO: Keep a cache of stack frames - stackFrame.id = nextFrameId++; - /* skip leading space */ - while (*rawBacktrace_it == ' ') { - rawBacktrace_it++; - } - /* Skip "at " */ - rawBacktrace_it += 3; - stackFrame.function = rawBacktrace_it; - while (*rawBacktrace_it != '(') { - rawBacktrace_it++; - } - *rawBacktrace_it = '\0'; - stackFrame.filename = rawBacktrace_it + 1; - while (*rawBacktrace_it != ':' && *rawBacktrace_it != ')') { - rawBacktrace_it++; - } - if (*rawBacktrace_it == ':') { - const char *linenumber = rawBacktrace_it + 1; - *rawBacktrace_it = '\0'; - while (*rawBacktrace_it != ')') { - rawBacktrace_it++; - } - *rawBacktrace_it = '\0'; - rawBacktrace_it++; - stackFrame.linenumber = atoi(linenumber); - } - else { - stackFrame.filename = NULL; - while (*rawBacktrace_it != '\n') { - rawBacktrace_it++; - } - } - while (*rawBacktrace_it == '\n' || *rawBacktrace_it == ' ') { - rawBacktrace_it++; - } - parsedBacktrace.push_back(stackFrame); /* module */ - } - return parsedBacktrace; - } -}; - -std::vector get_backtrace() { - static DalvikBacktraceProvider backtraceProvider; - return backtraceProvider.parseBacktrace(backtraceProvider.getBacktrace()); -} - -/* end ANDROID */ -#elif defined(__ELF__) - -#include -#include -#include -#include -#include - -#include - -namespace trace { - - - - -#define BT_DEPTH 10 - -class libbacktraceProvider { - struct backtrace_state *state; - int skipFrames; - Id nextFrameId; - std::map > cache; - std::vector *current, *current_frames; - RawStackFrame *current_frame; - - static void bt_err_callback(void *vdata, const char *msg, int errnum) - { - if (errnum == -1) - return;// no debug/sym info - else if (errnum) - os::log("libbacktrace: %s: %s\n", msg, strerror(errnum)); - else - os::log("libbacktrace: %s\n", msg); - } - - static int bt_countskip(void *vdata, uintptr_t pc) - { - libbacktraceProvider *this_ = (libbacktraceProvider*)vdata; - Dl_info info1, info2; - if (!dladdr((void*)bt_countskip, &info2)) { - os::log("dladdr failed, cannot cull stack traces\n"); - return 1; - } - if (!dladdr((void*)pc, &info1)) - return 1; - if (info1.dli_fbase != info2.dli_fbase) - return 1; - this_->skipFrames++; - return 0; - } - - static int bt_full_callback(void *vdata, uintptr_t pc, - const char *file, int line, const char *func) - { - libbacktraceProvider *this_ = (libbacktraceProvider*)vdata; - RawStackFrame frame = *this_->current_frame; - frame.id = this_->nextFrameId++; - frame.filename = file; - 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; - } - - static int bt_callback(void *vdata, uintptr_t pc) - { - libbacktraceProvider *this_ = (libbacktraceProvider*)vdata; - std::vector &frames = this_->cache[pc]; - if (!frames.size()) { - RawStackFrame frame; - Dl_info info = {0}; - dladdr((void*)pc, &info); - frame.module = info.dli_fname; - frame.function = info.dli_sname; - frame.offset = info.dli_saddr ? pc - (uintptr_t)info.dli_saddr - : pc - (uintptr_t)info.dli_fbase; - this_->current_frame = &frame; - this_->current_frames = &frames; - backtrace_pcinfo(this_->state, pc, bt_full_callback, bt_err_callback, vdata); - if (!frames.size()) { - frame.id = this_->nextFrameId++; - frames.push_back(frame); - } - } - this_->current->insert(this_->current->end(), frames.begin(), frames.end()); - return this_->current->size() >= BT_DEPTH; - } - -public: - libbacktraceProvider(): - state(backtrace_create_state(NULL, 0, bt_err_callback, NULL)) - { - backtrace_simple(state, 0, bt_countskip, bt_err_callback, this); - } - - std::vector getParsedBacktrace() - { - std::vector parsedBacktrace; - current = &parsedBacktrace; - backtrace_simple(state, skipFrames, bt_callback, bt_err_callback, this); - return parsedBacktrace; - } -}; - -std::vector get_backtrace() { - static libbacktraceProvider backtraceProvider; - return backtraceProvider.getParsedBacktrace(); -} - -#endif /* LINUX */ - -} /* namespace trace */ - -#endif /* ANDROID or LINUX */ diff --git a/common/trace_backtrace.hpp b/common/trace_backtrace.hpp deleted file mode 100644 index 60281f7..0000000 --- a/common/trace_backtrace.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/************************************************************************** - * - * Copyright 2013 Samsung - * Contributed by Eugene Velesevich - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - -#ifndef _TRACE_BACKTRACE_HPP_ -#define _TRACE_BACKTRACE_HPP_ - -#include - -#include "trace_model.hpp" - -namespace trace { - - -#if defined(ANDROID) || defined(__ELF__) - -std::vector get_backtrace(); -bool backtrace_is_needed(const char* fname); - -#else - -static inline std::vector get_backtrace() { - return std::vector(); -} - -static inline bool backtrace_is_needed(const char*) { - return false; -} - -#endif - -} /* namespace trace */ - -#endif diff --git a/common/trace_writer.cpp b/common/trace_writer.cpp index 46e6392..e7e3df2 100644 --- a/common/trace_writer.cpp +++ b/common/trace_writer.cpp @@ -35,7 +35,6 @@ #include "trace_file.hpp" #include "trace_writer.hpp" #include "trace_format.hpp" -#include "trace_backtrace.hpp" namespace trace { diff --git a/common/trace_writer.hpp b/common/trace_writer.hpp index a75d5ac..4c95477 100644 --- a/common/trace_writer.hpp +++ b/common/trace_writer.hpp @@ -36,7 +36,6 @@ #include #include "trace_model.hpp" -#include "trace_backtrace.hpp" namespace trace { class File; diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp index c5a5c44..a592cb8 100644 --- a/common/trace_writer_local.cpp +++ b/common/trace_writer_local.cpp @@ -36,7 +36,7 @@ #include "trace_file.hpp" #include "trace_writer_local.hpp" #include "trace_format.hpp" -#include "trace_backtrace.hpp" +#include "os_backtrace.hpp" namespace trace {