summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'debuggerd/libdebuggerd/backtrace.cpp')
-rw-r--r--debuggerd/libdebuggerd/backtrace.cpp81
1 files changed, 31 insertions, 50 deletions
diff --git a/debuggerd/libdebuggerd/backtrace.cpp b/debuggerd/libdebuggerd/backtrace.cpp
index f616e1ba0..f0a01f41c 100644
--- a/debuggerd/libdebuggerd/backtrace.cpp
+++ b/debuggerd/libdebuggerd/backtrace.cpp
@@ -30,12 +30,15 @@
30#include <time.h> 30#include <time.h>
31#include <unistd.h> 31#include <unistd.h>
32 32
33#include <map>
33#include <memory> 34#include <memory>
34#include <string> 35#include <string>
35 36
37#include <android-base/unique_fd.h>
36#include <backtrace/Backtrace.h> 38#include <backtrace/Backtrace.h>
37#include <log/log.h> 39#include <log/log.h>
38 40
41#include "libdebuggerd/types.h"
39#include "libdebuggerd/utility.h" 42#include "libdebuggerd/utility.h"
40 43
41static void dump_process_header(log_t* log, pid_t pid, const char* process_name) { 44static void dump_process_header(log_t* log, pid_t pid, const char* process_name) {
@@ -56,62 +59,46 @@ static void dump_process_footer(log_t* log, pid_t pid) {
56 _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid); 59 _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid);
57} 60}
58 61
59static void log_thread_name(log_t* log, pid_t tid, const char* thread_name) { 62void dump_backtrace_thread(int output_fd, BacktraceMap* map, const ThreadInfo& thread) {
60 _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", thread_name, tid);
61}
62
63static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid,
64 const std::string& thread_name) {
65 log_thread_name(log, tid, thread_name.c_str());
66
67 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
68 if (backtrace->Unwind(0)) {
69 dump_backtrace_to_log(backtrace.get(), log, " ");
70 } else {
71 ALOGE("Unwind failed: tid = %d: %s", tid,
72 backtrace->GetErrorString(backtrace->GetError()).c_str());
73 }
74}
75
76void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, const std::string& process_name,
77 const std::map<pid_t, std::string>& threads, std::string* amfd_data) {
78 log_t log; 63 log_t log;
79 log.tfd = fd; 64 log.tfd = output_fd;
80 log.amfd_data = amfd_data; 65 log.amfd_data = nullptr;
81 66
82 dump_process_header(&log, pid, process_name.c_str()); 67 _LOG(&log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", thread.thread_name.c_str(), thread.tid);
83 dump_thread(&log, map, pid, tid, threads.find(tid)->second.c_str());
84 68
85 for (const auto& it : threads) { 69 std::vector<backtrace_frame_data_t> frames;
86 pid_t thread_tid = it.first; 70 if (!Backtrace::Unwind(thread.registers.get(), map, &frames, 0, nullptr)) {
87 const std::string& thread_name = it.second; 71 _LOG(&log, logtype::THREAD, "Unwind failed: tid = %d", thread.tid);
88 if (thread_tid != tid) { 72 return;
89 dump_thread(&log, map, pid, thread_tid, thread_name.c_str());
90 }
91 } 73 }
92 74
93 dump_process_footer(&log, pid); 75 for (auto& frame : frames) {
76 _LOG(&log, logtype::BACKTRACE, " %s\n", Backtrace::FormatFrameData(&frame).c_str());
77 }
94} 78}
95 79
96void dump_backtrace_ucontext(int output_fd, ucontext_t* ucontext) { 80void dump_backtrace(android::base::unique_fd output_fd, BacktraceMap* map,
97 pid_t pid = getpid(); 81 const std::map<pid_t, ThreadInfo>& thread_info, pid_t target_thread) {
98 pid_t tid = gettid();
99
100 log_t log; 82 log_t log;
101 log.tfd = output_fd; 83 log.tfd = output_fd.get();
102 log.amfd_data = nullptr; 84 log.amfd_data = nullptr;
103 85
104 char thread_name[16]; 86 auto target = thread_info.find(target_thread);
105 read_with_default("/proc/self/comm", thread_name, sizeof(thread_name), "<unknown>"); 87 if (target == thread_info.end()) {
106 log_thread_name(&log, tid, thread_name); 88 ALOGE("failed to find target thread in thread info");
89 return;
90 }
107 91
108 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid)); 92 dump_process_header(&log, target->second.pid, target->second.process_name.c_str());
109 if (backtrace->Unwind(0, ucontext)) { 93
110 dump_backtrace_to_log(backtrace.get(), &log, " "); 94 dump_backtrace_thread(output_fd.get(), map, target->second);
111 } else { 95 for (const auto& [tid, info] : thread_info) {
112 ALOGE("Unwind failed: tid = %d: %s", tid, 96 if (tid != target_thread) {
113 backtrace->GetErrorString(backtrace->GetError()).c_str()); 97 dump_backtrace_thread(output_fd.get(), map, info);
98 }
114 } 99 }
100
101 dump_process_footer(&log, target->second.pid);
115} 102}
116 103
117void dump_backtrace_header(int output_fd) { 104void dump_backtrace_header(int output_fd) {
@@ -131,9 +118,3 @@ void dump_backtrace_footer(int output_fd) {
131 118
132 dump_process_footer(&log, getpid()); 119 dump_process_footer(&log, getpid());
133} 120}
134
135void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix) {
136 for (size_t i = 0; i < backtrace->NumFrames(); i++) {
137 _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str());
138 }
139}