diff options
| author | Christopher Ferris <cferris@google.com> | 2014-01-17 19:26:16 +0000 |
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2014-01-17 19:26:16 +0000 |
| commit | 47fa90641e5321f853d50de1e129b6233fa183e1 (patch) | |
| tree | 3acaca6f4ca2e83b0bd7a9a50b9d38e95cbe31bb /libbacktrace/Backtrace.cpp | |
| parent | b1091958bdb4bc42f66631fdf4105cbc2faec98a (diff) | |
| parent | 0cf5d96c43a11e150941202961bcedcbce9bb294 (diff) | |
| download | system_core-47fa90641e5321f853d50de1e129b6233fa183e1.zip system_core-47fa90641e5321f853d50de1e129b6233fa183e1.tar.gz system_core-47fa90641e5321f853d50de1e129b6233fa183e1.tar.bz2 | |
am 0cf5d96c: am 237fdb4a: am eb8d73b6: Merge "Rewrite libbacktrace to be all C++."
* commit '0cf5d96c43a11e150941202961bcedcbce9bb294':
Rewrite libbacktrace to be all C++.
Diffstat (limited to 'libbacktrace/Backtrace.cpp')
| -rw-r--r-- | libbacktrace/Backtrace.cpp | 208 |
1 files changed, 57 insertions, 151 deletions
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp index 20667e0..d7b40ab 100644 --- a/libbacktrace/Backtrace.cpp +++ b/libbacktrace/Backtrace.cpp @@ -27,46 +27,28 @@ #include <string> #include <backtrace/Backtrace.h> -#include <cutils/log.h> +#include <backtrace/BacktraceMap.h> #include "Backtrace.h" #include "thread_utils.h" //------------------------------------------------------------------------- -// BacktraceImpl functions. -//------------------------------------------------------------------------- -backtrace_t* BacktraceImpl::GetBacktraceData() { - return &backtrace_obj_->backtrace_; -} - -//------------------------------------------------------------------------- // Backtrace functions. //------------------------------------------------------------------------- -Backtrace::Backtrace(BacktraceImpl* impl, pid_t pid, backtrace_map_info_t* map_info) - : impl_(impl), map_info_(map_info), map_info_requires_delete_(false) { +Backtrace::Backtrace(BacktraceImpl* impl, pid_t pid, BacktraceMap* map) + : pid_(pid), tid_(-1), map_(map), map_shared_(true), impl_(impl) { impl_->SetParent(this); - backtrace_.num_frames = 0; - backtrace_.pid = pid; - backtrace_.tid = -1; - if (map_info_ == NULL) { - // Create the map and manage it internally. - map_info_ = backtrace_create_map_info_list(pid); - map_info_requires_delete_ = true; + if (map_ == NULL) { + // The map will be created when needed. + map_shared_ = false; } } Backtrace::~Backtrace() { - for (size_t i = 0; i < NumFrames(); i++) { - if (backtrace_.frames[i].func_name) { - free(backtrace_.frames[i].func_name); - backtrace_.frames[i].func_name = NULL; - } - } - - if (map_info_ && map_info_requires_delete_) { - backtrace_destroy_map_info_list(map_info_); - map_info_ = NULL; + if (map_ && !map_shared_) { + delete map_; + map_ = NULL; } if (impl_) { @@ -109,47 +91,36 @@ bool Backtrace::VerifyReadWordArgs(uintptr_t ptr, uint32_t* out_value) { return true; } -const char* Backtrace::GetMapName(uintptr_t pc, uintptr_t* map_start) { - const backtrace_map_info_t* map_info = FindMapInfo(pc); - if (map_info) { - if (map_start) { - *map_start = map_info->start; - } - return map_info->name; - } - return NULL; -} - -const backtrace_map_info_t* Backtrace::FindMapInfo(uintptr_t ptr) { - return backtrace_find_map_info(map_info_, ptr); -} - std::string Backtrace::FormatFrameData(size_t frame_num) { - return FormatFrameData(&backtrace_.frames[frame_num]); + if (frame_num >= frames_.size()) { + return ""; + } + return FormatFrameData(&frames_[frame_num]); } std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) { const char* map_name; - if (frame->map_name) { - map_name = frame->map_name; + if (frame->map && !frame->map->name.empty()) { + map_name = frame->map->name.c_str(); } else { map_name = "<unknown>"; } + uintptr_t relative_pc; - if (frame->map_offset) { - relative_pc = frame->map_offset; + if (frame->map) { + relative_pc = frame->pc - frame->map->start; } else { relative_pc = frame->pc; } char buf[512]; - if (frame->func_name && frame->func_offset) { + if (!frame->func_name.empty() && frame->func_offset) { snprintf(buf, sizeof(buf), "#%02zu pc %0*" PRIxPTR " %s (%s+%" PRIuPTR ")", frame->num, (int)sizeof(uintptr_t)*2, relative_pc, map_name, - frame->func_name, frame->func_offset); - } else if (frame->func_name) { + frame->func_name.c_str(), frame->func_offset); + } else if (!frame->func_name.empty()) { snprintf(buf, sizeof(buf), "#%02zu pc %0*" PRIxPTR " %s (%s)", frame->num, - (int)sizeof(uintptr_t)*2, relative_pc, map_name, frame->func_name); + (int)sizeof(uintptr_t)*2, relative_pc, map_name, frame->func_name.c_str()); } else { snprintf(buf, sizeof(buf), "#%02zu pc %0*" PRIxPTR " %s", frame->num, (int)sizeof(uintptr_t)*2, relative_pc, map_name); @@ -158,13 +129,35 @@ std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) { return buf; } +bool Backtrace::BuildMap() { + map_ = impl_->CreateBacktraceMap(pid_); + if (!map_->Build()) { + BACK_LOGW("Failed to build map for process %d", pid_); + return false; + } + return true; +} + +const backtrace_map_t* Backtrace::FindMap(uintptr_t pc) { + if (map_ == NULL) { + // Lazy eval, time to build the map. + if (!BuildMap()) { + return NULL; + } + } + return map_->Find(pc); +} + +BacktraceMap* Backtrace::TakeMapOwnership() { + map_shared_ = true; + return map_; +} + //------------------------------------------------------------------------- // BacktraceCurrent functions. //------------------------------------------------------------------------- BacktraceCurrent::BacktraceCurrent( - BacktraceImpl* impl, backtrace_map_info_t *map_info) : Backtrace(impl, getpid(), map_info) { - - backtrace_.pid = getpid(); + BacktraceImpl* impl, BacktraceMap* map) : Backtrace(impl, getpid(), map) { } BacktraceCurrent::~BacktraceCurrent() { @@ -175,8 +168,8 @@ bool BacktraceCurrent::ReadWord(uintptr_t ptr, uint32_t* out_value) { return false; } - const backtrace_map_info_t* map_info = FindMapInfo(ptr); - if (map_info && map_info->is_readable) { + const backtrace_map_t* map = FindMap(ptr); + if (map && map->flags & PROT_READ) { *out_value = *reinterpret_cast<uint32_t*>(ptr); return true; } else { @@ -190,9 +183,9 @@ bool BacktraceCurrent::ReadWord(uintptr_t ptr, uint32_t* out_value) { // BacktracePtrace functions. //------------------------------------------------------------------------- BacktracePtrace::BacktracePtrace( - BacktraceImpl* impl, pid_t pid, pid_t tid, backtrace_map_info_t* map_info) - : Backtrace(impl, pid, map_info) { - backtrace_.tid = tid; + BacktraceImpl* impl, pid_t pid, pid_t tid, BacktraceMap* map) + : Backtrace(impl, pid, map) { + tid_ = tid; } BacktracePtrace::~BacktracePtrace() { @@ -220,103 +213,16 @@ bool BacktracePtrace::ReadWord(uintptr_t ptr, uint32_t* out_value) { #endif } -Backtrace* Backtrace::Create(pid_t pid, pid_t tid, backtrace_map_info_t* map_info) { +Backtrace* Backtrace::Create(pid_t pid, pid_t tid, BacktraceMap* map) { if (pid == BACKTRACE_CURRENT_PROCESS || pid == getpid()) { if (tid == BACKTRACE_CURRENT_THREAD || tid == gettid()) { - return CreateCurrentObj(map_info); + return CreateCurrentObj(map); } else { - return CreateThreadObj(tid, map_info); + return CreateThreadObj(tid, map); } } else if (tid == BACKTRACE_CURRENT_THREAD) { - return CreatePtraceObj(pid, pid, map_info); + return CreatePtraceObj(pid, pid, map); } else { - return CreatePtraceObj(pid, tid, map_info); - } -} - -//------------------------------------------------------------------------- -// Common interface functions. -//------------------------------------------------------------------------- -bool backtrace_create_context_with_map( - backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames, - backtrace_map_info_t* map_info) { - Backtrace* backtrace = Backtrace::Create(pid, tid, map_info); - if (!backtrace) { - return false; - } - if (!backtrace->Unwind(num_ignore_frames)) { - delete backtrace; - return false; - } - - context->data = backtrace; - context->backtrace = backtrace->GetBacktrace(); - return true; -} - -bool backtrace_create_context( - backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames) { - return backtrace_create_context_with_map(context, pid, tid, num_ignore_frames, NULL); -} - - -void backtrace_destroy_context(backtrace_context_t* context) { - if (context->data) { - Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data); - delete backtrace; - context->data = NULL; - } - context->backtrace = NULL; -} - -const backtrace_t* backtrace_get_data(backtrace_context_t* context) { - if (context && context->data) { - Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data); - return backtrace->GetBacktrace(); - } - return NULL; -} - -bool backtrace_read_word(const backtrace_context_t* context, uintptr_t ptr, uint32_t* value) { - if (context->data) { - Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data); - return backtrace->ReadWord(ptr, value); - } - return true; -} - -const char* backtrace_get_map_name(const backtrace_context_t* context, uintptr_t pc, uintptr_t* map_start) { - if (context->data) { - Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data); - return backtrace->GetMapName(pc, map_start); - } - return NULL; -} - -char* backtrace_get_func_name(const backtrace_context_t* context, uintptr_t pc, uintptr_t* func_offset) { - if (context->data) { - Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data); - std::string func_name = backtrace->GetFunctionName(pc, func_offset); - if (!func_name.empty()) { - return strdup(func_name.c_str()); - } - } - return NULL; -} - -void backtrace_format_frame_data( - const backtrace_context_t* context, size_t frame_num, char* buf, - size_t buf_size) { - if (buf_size == 0 || buf == NULL) { - BACK_LOGW("bad call buf %p buf_size %zu", buf, buf_size); - } else if (context->data) { - Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data); - std::string line = backtrace->FormatFrameData(frame_num); - if (line.size() > buf_size) { - memcpy(buf, line.c_str(), buf_size-1); - buf[buf_size] = '\0'; - } else { - memcpy(buf, line.c_str(), line.size()+1); - } + return CreatePtraceObj(pid, tid, map); } } |
