Loading debuggerd/tombstone.c +9 −4 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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); Loading @@ -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); } Loading include/backtrace/Backtrace.h +6 −2 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); Loading @@ -78,6 +80,8 @@ protected: backtrace_map_info_t* map_info_; bool map_info_requires_delete_; backtrace_t backtrace_; friend class BacktraceImpl; Loading include/backtrace/backtrace.h +8 −0 Original line number Diff line number Diff line Loading @@ -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); Loading libbacktrace/Backtrace.cpp +30 −18 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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; } Loading Loading @@ -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(); } Loading @@ -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; } Loading Loading @@ -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; } Loading @@ -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); Loading libbacktrace/Backtrace.h +5 −5 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 Loading
debuggerd/tombstone.c +9 −4 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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); Loading @@ -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); } Loading
include/backtrace/Backtrace.h +6 −2 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); Loading @@ -78,6 +80,8 @@ protected: backtrace_map_info_t* map_info_; bool map_info_requires_delete_; backtrace_t backtrace_; friend class BacktraceImpl; Loading
include/backtrace/backtrace.h +8 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
libbacktrace/Backtrace.cpp +30 −18 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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; } Loading Loading @@ -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(); } Loading @@ -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; } Loading Loading @@ -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; } Loading @@ -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); Loading
libbacktrace/Backtrace.h +5 −5 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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