diff options
author | Christopher Ferris <cferris@google.com> | 2014-01-08 23:43:53 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-01-08 23:43:53 +0000 |
commit | 5ca7d87fe47ad18594b5c5f79d00aa86ed1435cb (patch) | |
tree | 299dac6eb1dc74fd6f4eb3af2e2e338e7aa49d2a | |
parent | df8d0ffd73f8359def90d2f79d25059023018213 (diff) | |
parent | f1f150d0e6e27588d0b15a53e7fac4984bf6ccd8 (diff) | |
download | system_core-5ca7d87fe47ad18594b5c5f79d00aa86ed1435cb.zip system_core-5ca7d87fe47ad18594b5c5f79d00aa86ed1435cb.tar.gz system_core-5ca7d87fe47ad18594b5c5f79d00aa86ed1435cb.tar.bz2 |
am f1f150d0: am 0c863cb5: Merge "Refactor to share map_info amongst threads."
* commit 'f1f150d0e6e27588d0b15a53e7fac4984bf6ccd8':
Refactor to share map_info amongst threads.
-rw-r--r-- | debuggerd/tombstone.c | 13 | ||||
-rw-r--r-- | include/backtrace/Backtrace.h | 8 | ||||
-rw-r--r-- | include/backtrace/backtrace.h | 8 | ||||
-rw-r--r-- | libbacktrace/Backtrace.cpp | 48 | ||||
-rw-r--r-- | libbacktrace/Backtrace.h | 10 | ||||
-rw-r--r-- | libbacktrace/BacktraceThread.cpp | 5 | ||||
-rw-r--r-- | libbacktrace/BacktraceThread.h | 3 | ||||
-rw-r--r-- | libbacktrace/Corkscrew.cpp | 12 | ||||
-rw-r--r-- | libbacktrace/UnwindCurrent.cpp | 8 | ||||
-rw-r--r-- | libbacktrace/UnwindPtrace.cpp | 4 |
10 files changed, 75 insertions, 44 deletions
diff --git a/debuggerd/tombstone.c b/debuggerd/tombstone.c index aa63547..1b08e8e 100644 --- a/debuggerd/tombstone.c +++ b/debuggerd/tombstone.c @@ -415,7 +415,7 @@ static void dump_thread(const backtrace_context_t* context, log_t* log, /* Return true if some thread is not detached cleanly */ static bool dump_sibling_thread_report( - log_t* log, pid_t pid, pid_t tid, int* total_sleep_time_usec) { + log_t* log, pid_t pid, pid_t tid, int* total_sleep_time_usec, backtrace_map_info_t* map_info) { char task_path[64]; snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid); @@ -449,7 +449,7 @@ static bool dump_sibling_thread_report( _LOG(log, 0, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n"); dump_thread_info(log, pid, new_tid, 0); backtrace_context_t new_context; - if (backtrace_create_context(&new_context, pid, new_tid, 0)) { + if (backtrace_create_context_with_map(&new_context, pid, new_tid, 0, map_info)) { dump_thread(&new_context, log, 0, total_sleep_time_usec); backtrace_destroy_context(&new_context); } @@ -676,7 +676,9 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t a } backtrace_context_t context; - if (backtrace_create_context(&context, pid, tid, 0)) { + /* Gather the map info once for all this process' threads. */ + backtrace_map_info_t* map_info = backtrace_create_map_info_list(pid); + if (backtrace_create_context_with_map(&context, pid, tid, 0, map_info)) { dump_abort_message(&context, log, abort_msg_address); dump_thread(&context, log, SCOPE_AT_FAULT, total_sleep_time_usec); backtrace_destroy_context(&context); @@ -688,9 +690,12 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t a bool detach_failed = false; if (dump_sibling_threads) { - detach_failed = dump_sibling_thread_report(log, pid, tid, total_sleep_time_usec); + detach_failed = dump_sibling_thread_report(log, pid, tid, total_sleep_time_usec, map_info); } + /* Destroy the previously created map info. */ + backtrace_destroy_map_info_list(map_info); + if (want_logs) { dump_logs(log, pid, false); } diff --git a/include/backtrace/Backtrace.h b/include/backtrace/Backtrace.h index b15678c..bf4efd3 100644 --- a/include/backtrace/Backtrace.h +++ b/include/backtrace/Backtrace.h @@ -33,7 +33,9 @@ public: // If pid >= 0 and tid < 0, then the Backtrace object corresponds to a // different process. // Tracing a thread in a different process is not supported. - static Backtrace* Create(pid_t pid, pid_t tid); + // If map_info is NULL, then create the map and manage it internally. + // If map_info is not NULL, the map is still owned by the caller. + static Backtrace* Create(pid_t pid, pid_t tid, backtrace_map_info_t* map_info = NULL); virtual ~Backtrace(); @@ -70,7 +72,7 @@ public: } protected: - Backtrace(BacktraceImpl* impl); + Backtrace(BacktraceImpl* impl, pid_t pid, backtrace_map_info_t* map_info); virtual bool VerifyReadWordArgs(uintptr_t ptr, uint32_t* out_value); @@ -78,6 +80,8 @@ protected: backtrace_map_info_t* map_info_; + bool map_info_requires_delete_; + backtrace_t backtrace_; friend class BacktraceImpl; diff --git a/include/backtrace/backtrace.h b/include/backtrace/backtrace.h index 8a45690..186d327 100644 --- a/include/backtrace/backtrace.h +++ b/include/backtrace/backtrace.h @@ -73,6 +73,14 @@ typedef struct { bool backtrace_create_context( backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames); +/* The same as backtrace_create_context, except that it is assumed that + * the pid map has already been acquired and the caller will handle freeing + * the map data. + */ +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); + /* Gather the backtrace data for a pthread instead of a process. */ bool backtrace_create_thread_context( backtrace_context_t* context, pid_t tid, size_t num_ignore_frames); diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp index b22d301..ccfce81 100644 --- a/libbacktrace/Backtrace.cpp +++ b/libbacktrace/Backtrace.cpp @@ -42,11 +42,18 @@ backtrace_t* BacktraceImpl::GetBacktraceData() { //------------------------------------------------------------------------- // Backtrace functions. //------------------------------------------------------------------------- -Backtrace::Backtrace(BacktraceImpl* impl) : impl_(impl), map_info_(NULL) { +Backtrace::Backtrace(BacktraceImpl* impl, pid_t pid, backtrace_map_info_t* map_info) + : impl_(impl), map_info_(map_info), map_info_requires_delete_(false) { impl_->SetParent(this); backtrace_.num_frames = 0; - backtrace_.pid = -1; + 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; + } } Backtrace::~Backtrace() { @@ -57,7 +64,7 @@ Backtrace::~Backtrace() { } } - if (map_info_) { + if (map_info_ && map_info_requires_delete_) { backtrace_destroy_map_info_list(map_info_); map_info_ = NULL; } @@ -151,8 +158,8 @@ std::string Backtrace::FormatFrameData(size_t frame_num) { //------------------------------------------------------------------------- // BacktraceCurrent functions. //------------------------------------------------------------------------- -BacktraceCurrent::BacktraceCurrent(BacktraceImpl* impl) : Backtrace(impl) { - map_info_ = backtrace_create_map_info_list(-1); +BacktraceCurrent::BacktraceCurrent( + BacktraceImpl* impl, backtrace_map_info_t *map_info) : Backtrace(impl, getpid(), map_info) { backtrace_.pid = getpid(); } @@ -179,11 +186,9 @@ bool BacktraceCurrent::ReadWord(uintptr_t ptr, uint32_t* out_value) { //------------------------------------------------------------------------- // BacktracePtrace functions. //------------------------------------------------------------------------- -BacktracePtrace::BacktracePtrace(BacktraceImpl* impl, pid_t pid, pid_t tid) - : Backtrace(impl) { - map_info_ = backtrace_create_map_info_list(tid); - - backtrace_.pid = pid; +BacktracePtrace::BacktracePtrace( + BacktraceImpl* impl, pid_t pid, pid_t tid, backtrace_map_info_t* map_info) + : Backtrace(impl, pid, map_info) { backtrace_.tid = tid; } @@ -212,26 +217,27 @@ bool BacktracePtrace::ReadWord(uintptr_t ptr, uint32_t* out_value) { #endif } -Backtrace* Backtrace::Create(pid_t pid, pid_t tid) { +Backtrace* Backtrace::Create(pid_t pid, pid_t tid, backtrace_map_info_t* map_info) { if (pid == BACKTRACE_CURRENT_PROCESS || pid == getpid()) { if (tid == BACKTRACE_NO_TID || tid == gettid()) { - return CreateCurrentObj(); + return CreateCurrentObj(map_info); } else { - return CreateThreadObj(tid); + return CreateThreadObj(tid, map_info); } } else if (tid == BACKTRACE_NO_TID) { - return CreatePtraceObj(pid, pid); + return CreatePtraceObj(pid, pid, map_info); } else { - return CreatePtraceObj(pid, tid); + return CreatePtraceObj(pid, tid, map_info); } } //------------------------------------------------------------------------- // Common interface functions. //------------------------------------------------------------------------- -bool backtrace_create_context( - backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames) { - Backtrace* backtrace = Backtrace::Create(pid, tid); +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; } @@ -245,6 +251,12 @@ bool backtrace_create_context( 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); diff --git a/libbacktrace/Backtrace.h b/libbacktrace/Backtrace.h index 00f0a10..d741ef1 100644 --- a/libbacktrace/Backtrace.h +++ b/libbacktrace/Backtrace.h @@ -45,7 +45,7 @@ protected: class BacktraceCurrent : public Backtrace { public: - BacktraceCurrent(BacktraceImpl* impl); + BacktraceCurrent(BacktraceImpl* impl, backtrace_map_info_t* map_info); virtual ~BacktraceCurrent(); bool ReadWord(uintptr_t ptr, uint32_t* out_value); @@ -53,14 +53,14 @@ public: class BacktracePtrace : public Backtrace { public: - BacktracePtrace(BacktraceImpl* impl, pid_t pid, pid_t tid); + BacktracePtrace(BacktraceImpl* impl, pid_t pid, pid_t tid, backtrace_map_info_t* map_info); virtual ~BacktracePtrace(); bool ReadWord(uintptr_t ptr, uint32_t* out_value); }; -Backtrace* CreateCurrentObj(); -Backtrace* CreatePtraceObj(pid_t pid, pid_t tid); -Backtrace* CreateThreadObj(pid_t tid); +Backtrace* CreateCurrentObj(backtrace_map_info_t* map_info); +Backtrace* CreatePtraceObj(pid_t pid, pid_t tid, backtrace_map_info_t* map_info); +Backtrace* CreateThreadObj(pid_t tid, backtrace_map_info_t* map_info); #endif // _LIBBACKTRACE_BACKTRACE_H diff --git a/libbacktrace/BacktraceThread.cpp b/libbacktrace/BacktraceThread.cpp index 8e664c4..70616b0 100644 --- a/libbacktrace/BacktraceThread.cpp +++ b/libbacktrace/BacktraceThread.cpp @@ -114,8 +114,9 @@ static void SignalHandler(int n __attribute__((unused)), siginfo_t* siginfo, } BacktraceThread::BacktraceThread( - BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid) - : BacktraceCurrent(impl), thread_intf_(thread_intf) { + BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid, + backtrace_map_info_t* map_info) + : BacktraceCurrent(impl, map_info), thread_intf_(thread_intf) { backtrace_.tid = tid; } diff --git a/libbacktrace/BacktraceThread.h b/libbacktrace/BacktraceThread.h index 8ed1122..bcb56c9 100644 --- a/libbacktrace/BacktraceThread.h +++ b/libbacktrace/BacktraceThread.h @@ -71,7 +71,8 @@ public: // the compiler to catch if an implementation does not properly // subclass both. BacktraceThread( - BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid); + BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid, + backtrace_map_info_t* map_info); virtual ~BacktraceThread(); virtual bool Unwind(size_t num_ignore_frames); diff --git a/libbacktrace/Corkscrew.cpp b/libbacktrace/Corkscrew.cpp index 2be5930..eae13c6 100644 --- a/libbacktrace/Corkscrew.cpp +++ b/libbacktrace/Corkscrew.cpp @@ -204,15 +204,15 @@ std::string CorkscrewPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) //------------------------------------------------------------------------- // C++ object creation functions. //------------------------------------------------------------------------- -Backtrace* CreateCurrentObj() { - return new BacktraceCurrent(new CorkscrewCurrent()); +Backtrace* CreateCurrentObj(backtrace_map_info_t* map_info) { + return new BacktraceCurrent(new CorkscrewCurrent(), map_info); } -Backtrace* CreatePtraceObj(pid_t pid, pid_t tid) { - return new BacktracePtrace(new CorkscrewPtrace(), pid, tid); +Backtrace* CreatePtraceObj(pid_t pid, pid_t tid, backtrace_map_info_t* map_info) { + return new BacktracePtrace(new CorkscrewPtrace(), pid, tid, map_info); } -Backtrace* CreateThreadObj(pid_t tid) { +Backtrace* CreateThreadObj(pid_t tid, backtrace_map_info_t* map_info) { CorkscrewThread* thread_obj = new CorkscrewThread(); - return new BacktraceThread(thread_obj, thread_obj, tid); + return new BacktraceThread(thread_obj, thread_obj, tid, map_info); } diff --git a/libbacktrace/UnwindCurrent.cpp b/libbacktrace/UnwindCurrent.cpp index 6c0cad6..94a82fe 100644 --- a/libbacktrace/UnwindCurrent.cpp +++ b/libbacktrace/UnwindCurrent.cpp @@ -194,11 +194,11 @@ void UnwindThread::ThreadUnwind( //------------------------------------------------------------------------- // C++ object creation function. //------------------------------------------------------------------------- -Backtrace* CreateCurrentObj() { - return new BacktraceCurrent(new UnwindCurrent()); +Backtrace* CreateCurrentObj(backtrace_map_info_t* map_info) { + return new BacktraceCurrent(new UnwindCurrent(), map_info); } -Backtrace* CreateThreadObj(pid_t tid) { +Backtrace* CreateThreadObj(pid_t tid, backtrace_map_info_t* map_info) { UnwindThread* thread_obj = new UnwindThread(); - return new BacktraceThread(thread_obj, thread_obj, tid); + return new BacktraceThread(thread_obj, thread_obj, tid, map_info); } diff --git a/libbacktrace/UnwindPtrace.cpp b/libbacktrace/UnwindPtrace.cpp index a734a24..7a9bbdd 100644 --- a/libbacktrace/UnwindPtrace.cpp +++ b/libbacktrace/UnwindPtrace.cpp @@ -131,6 +131,6 @@ std::string UnwindPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { //------------------------------------------------------------------------- // C++ object creation function. //------------------------------------------------------------------------- -Backtrace* CreatePtraceObj(pid_t pid, pid_t tid) { - return new BacktracePtrace(new UnwindPtrace(), pid, tid); +Backtrace* CreatePtraceObj(pid_t pid, pid_t tid, backtrace_map_info_t* map_info) { + return new BacktracePtrace(new UnwindPtrace(), pid, tid, map_info); } |