summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Gao2017-03-16 12:45:18 -0500
committerGerrit Code Review2017-03-16 12:45:18 -0500
commit7390d96ff2f42305addfaf32388d9f7d3be509f4 (patch)
treeb7fc1ce6500953ded49caad46723da49a4e6c3dc
parent54e7365feed2ea2c209417c8a96d4aa5a9e5b028 (diff)
parent57f58f8e4a143f1208593c8b397b9a17d055dad0 (diff)
downloadplatform-system-core-android-n-mr2-preview-2.tar.gz
platform-system-core-android-n-mr2-preview-2.tar.xz
platform-system-core-android-n-mr2-preview-2.zip
Merge "crash_dump: fetch process/thread names before dropping privileges."android-n-mr2-preview-2
-rw-r--r--debuggerd/crash_dump.cpp29
-rw-r--r--debuggerd/libdebuggerd/backtrace.cpp66
-rw-r--r--debuggerd/libdebuggerd/include/backtrace.h6
-rw-r--r--debuggerd/libdebuggerd/include/tombstone.h9
-rw-r--r--debuggerd/libdebuggerd/include/utility.h2
-rw-r--r--debuggerd/libdebuggerd/tombstone.cpp79
-rw-r--r--debuggerd/libdebuggerd/utility.cpp18
7 files changed, 109 insertions, 100 deletions
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 38b711ff4..88f390b0e 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -27,6 +27,7 @@
27#include <unistd.h> 27#include <unistd.h>
28 28
29#include <limits> 29#include <limits>
30#include <map>
30#include <memory> 31#include <memory>
31#include <set> 32#include <set>
32#include <vector> 33#include <vector>
@@ -36,6 +37,7 @@
36#include <android-base/parseint.h> 37#include <android-base/parseint.h>
37#include <android-base/properties.h> 38#include <android-base/properties.h>
38#include <android-base/stringprintf.h> 39#include <android-base/stringprintf.h>
40#include <android-base/strings.h>
39#include <android-base/unique_fd.h> 41#include <android-base/unique_fd.h>
40#include <cutils/sockets.h> 42#include <cutils/sockets.h>
41#include <log/log.h> 43#include <log/log.h>
@@ -52,7 +54,21 @@
52#include "debuggerd/util.h" 54#include "debuggerd/util.h"
53 55
54using android::base::unique_fd; 56using android::base::unique_fd;
57using android::base::ReadFileToString;
55using android::base::StringPrintf; 58using android::base::StringPrintf;
59using android::base::Trim;
60
61static std::string get_process_name(pid_t pid) {
62 std::string result = "<unknown>";
63 ReadFileToString(StringPrintf("/proc/%d/cmdline", pid), &result);
64 return result;
65}
66
67static std::string get_thread_name(pid_t tid) {
68 std::string result = "<unknown>";
69 ReadFileToString(StringPrintf("/proc/%d/comm", tid), &result);
70 return Trim(result);
71}
56 72
57static bool pid_contains_tid(int pid_proc_fd, pid_t tid) { 73static bool pid_contains_tid(int pid_proc_fd, pid_t tid) {
58 struct stat st; 74 struct stat st;
@@ -253,7 +269,7 @@ int main(int argc, char** argv) {
253 } 269 }
254 270
255 // Seize the siblings. 271 // Seize the siblings.
256 std::set<pid_t> attached_siblings; 272 std::map<pid_t, std::string> threads;
257 { 273 {
258 std::set<pid_t> siblings; 274 std::set<pid_t> siblings;
259 if (!android::procinfo::GetProcessTids(target, &siblings)) { 275 if (!android::procinfo::GetProcessTids(target, &siblings)) {
@@ -269,12 +285,12 @@ int main(int argc, char** argv) {
269 if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) { 285 if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
270 LOG(WARNING) << attach_error; 286 LOG(WARNING) << attach_error;
271 } else { 287 } else {
272 attached_siblings.insert(sibling_tid); 288 threads.emplace(sibling_tid, get_thread_name(sibling_tid));
273 } 289 }
274 } 290 }
275 } 291 }
276 292
277 // Collect the backtrace map and open files, while the process still has PR_GET_DUMPABLE=1 293 // Collect the backtrace map, open files, and process/thread names, while we still have caps.
278 std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(main_tid)); 294 std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(main_tid));
279 if (!backtrace_map) { 295 if (!backtrace_map) {
280 LOG(FATAL) << "failed to create backtrace map"; 296 LOG(FATAL) << "failed to create backtrace map";
@@ -284,6 +300,9 @@ int main(int argc, char** argv) {
284 OpenFilesList open_files; 300 OpenFilesList open_files;
285 populate_open_files_list(target, &open_files); 301 populate_open_files_list(target, &open_files);
286 302
303 std::string process_name = get_process_name(main_tid);
304 threads.emplace(main_tid, get_thread_name(main_tid));
305
287 // Drop our capabilities now that we've attached to the threads we care about. 306 // Drop our capabilities now that we've attached to the threads we care about.
288 drop_capabilities(); 307 drop_capabilities();
289 308
@@ -341,10 +360,10 @@ int main(int argc, char** argv) {
341 360
342 std::string amfd_data; 361 std::string amfd_data;
343 if (backtrace) { 362 if (backtrace) {
344 dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, attached_siblings, 0); 363 dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, process_name, threads, 0);
345 } else { 364 } else {
346 engrave_tombstone(output_fd.get(), backtrace_map.get(), &open_files, target, main_tid, 365 engrave_tombstone(output_fd.get(), backtrace_map.get(), &open_files, target, main_tid,
347 &attached_siblings, abort_address, fatal_signal ? &amfd_data : nullptr); 366 process_name, threads, abort_address, fatal_signal ? &amfd_data : nullptr);
348 } 367 }
349 368
350 // We don't actually need to PTRACE_DETACH, as long as our tracees aren't in 369 // We don't actually need to PTRACE_DETACH, as long as our tracees aren't in
diff --git a/debuggerd/libdebuggerd/backtrace.cpp b/debuggerd/libdebuggerd/backtrace.cpp
index df49aef37..334d97f33 100644
--- a/debuggerd/libdebuggerd/backtrace.cpp
+++ b/debuggerd/libdebuggerd/backtrace.cpp
@@ -38,18 +38,7 @@
38 38
39#include "utility.h" 39#include "utility.h"
40 40
41static void dump_process_header(log_t* log, pid_t pid) { 41static void dump_process_header(log_t* log, pid_t pid, const char* process_name) {
42 char path[PATH_MAX];
43 char procnamebuf[1024];
44 char* procname = NULL;
45 FILE* fp;
46
47 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
48 if ((fp = fopen(path, "r"))) {
49 procname = fgets(procnamebuf, sizeof(procnamebuf), fp);
50 fclose(fp);
51 }
52
53 time_t t = time(NULL); 42 time_t t = time(NULL);
54 struct tm tm; 43 struct tm tm;
55 localtime_r(&t, &tm); 44 localtime_r(&t, &tm);
@@ -57,8 +46,8 @@ static void dump_process_header(log_t* log, pid_t pid) {
57 strftime(timestr, sizeof(timestr), "%F %T", &tm); 46 strftime(timestr, sizeof(timestr), "%F %T", &tm);
58 _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, timestr); 47 _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, timestr);
59 48
60 if (procname) { 49 if (process_name) {
61 _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", procname); 50 _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", process_name);
62 } 51 }
63 _LOG(log, logtype::BACKTRACE, "ABI: '%s'\n", ABI_STRING); 52 _LOG(log, logtype::BACKTRACE, "ABI: '%s'\n", ABI_STRING);
64} 53}
@@ -67,28 +56,13 @@ static void dump_process_footer(log_t* log, pid_t pid) {
67 _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid); 56 _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid);
68} 57}
69 58
70static void log_thread_name(log_t* log, pid_t tid) { 59static void log_thread_name(log_t* log, pid_t tid, const char* thread_name) {
71 FILE* fp; 60 _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", thread_name, tid);
72 char buf[1024];
73 char path[PATH_MAX];
74 char* threadname = NULL;
75
76 snprintf(path, sizeof(path), "/proc/%d/comm", tid);
77 if ((fp = fopen(path, "r"))) {
78 threadname = fgets(buf, sizeof(buf), fp);
79 fclose(fp);
80 if (threadname) {
81 size_t len = strlen(threadname);
82 if (len && threadname[len - 1] == '\n') {
83 threadname[len - 1] = '\0';
84 }
85 }
86 }
87 _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid);
88} 61}
89 62
90static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) { 63static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid,
91 log_thread_name(log, tid); 64 const std::string& thread_name) {
65 log_thread_name(log, tid, thread_name.c_str());
92 66
93 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map)); 67 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
94 if (backtrace->Unwind(0)) { 68 if (backtrace->Unwind(0)) {
@@ -99,17 +73,21 @@ static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) {
99 } 73 }
100} 74}
101 75
102void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, 76void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, const std::string& process_name,
103 const std::set<pid_t>& siblings, std::string* amfd_data) { 77 const std::map<pid_t, std::string>& threads, std::string* amfd_data) {
104 log_t log; 78 log_t log;
105 log.tfd = fd; 79 log.tfd = fd;
106 log.amfd_data = amfd_data; 80 log.amfd_data = amfd_data;
107 81
108 dump_process_header(&log, pid); 82 dump_process_header(&log, pid, process_name.c_str());
109 dump_thread(&log, map, pid, tid); 83 dump_thread(&log, map, pid, tid, threads.find(tid)->second.c_str());
110 84
111 for (pid_t sibling : siblings) { 85 for (const auto& it : threads) {
112 dump_thread(&log, map, pid, sibling); 86 pid_t thread_tid = it.first;
87 const std::string& thread_name = it.second;
88 if (thread_tid != tid) {
89 dump_thread(&log, map, pid, thread_tid, thread_name.c_str());
90 }
113 } 91 }
114 92
115 dump_process_footer(&log, pid); 93 dump_process_footer(&log, pid);
@@ -123,7 +101,9 @@ void dump_backtrace_ucontext(int output_fd, ucontext_t* ucontext) {
123 log.tfd = output_fd; 101 log.tfd = output_fd;
124 log.amfd_data = nullptr; 102 log.amfd_data = nullptr;
125 103
126 log_thread_name(&log, tid); 104 char thread_name[16];
105 read_with_default("/proc/self/comm", thread_name, sizeof(thread_name), "<unknown>");
106 log_thread_name(&log, tid, thread_name);
127 107
128 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid)); 108 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid));
129 if (backtrace->Unwind(0, ucontext)) { 109 if (backtrace->Unwind(0, ucontext)) {
@@ -139,7 +119,9 @@ void dump_backtrace_header(int output_fd) {
139 log.tfd = output_fd; 119 log.tfd = output_fd;
140 log.amfd_data = nullptr; 120 log.amfd_data = nullptr;
141 121
142 dump_process_header(&log, getpid()); 122 char process_name[128];
123 read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), "<unknown>");
124 dump_process_header(&log, getpid(), process_name);
143} 125}
144 126
145void dump_backtrace_footer(int output_fd) { 127void dump_backtrace_footer(int output_fd) {
diff --git a/debuggerd/libdebuggerd/include/backtrace.h b/debuggerd/libdebuggerd/include/backtrace.h
index 5bfdac8fc..fe738f1c7 100644
--- a/debuggerd/libdebuggerd/include/backtrace.h
+++ b/debuggerd/libdebuggerd/include/backtrace.h
@@ -20,7 +20,7 @@
20#include <sys/types.h> 20#include <sys/types.h>
21#include <sys/ucontext.h> 21#include <sys/ucontext.h>
22 22
23#include <set> 23#include <map>
24#include <string> 24#include <string>
25 25
26#include "utility.h" 26#include "utility.h"
@@ -30,8 +30,8 @@ class BacktraceMap;
30 30
31// Dumps a backtrace using a format similar to what Dalvik uses so that the result 31// Dumps a backtrace using a format similar to what Dalvik uses so that the result
32// can be intermixed in a bug report. 32// can be intermixed in a bug report.
33void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, 33void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, const std::string& process_name,
34 const std::set<pid_t>& siblings, std::string* amfd_data); 34 const std::map<pid_t, std::string>& threads, std::string* amfd_data);
35 35
36/* Dumps the backtrace in the backtrace data structure to the log. */ 36/* Dumps the backtrace in the backtrace data structure to the log. */
37void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix); 37void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix);
diff --git a/debuggerd/libdebuggerd/include/tombstone.h b/debuggerd/libdebuggerd/include/tombstone.h
index d2a4a4bb7..79743b61c 100644
--- a/debuggerd/libdebuggerd/include/tombstone.h
+++ b/debuggerd/libdebuggerd/include/tombstone.h
@@ -20,7 +20,8 @@
20#include <stdbool.h> 20#include <stdbool.h>
21#include <stddef.h> 21#include <stddef.h>
22#include <sys/types.h> 22#include <sys/types.h>
23#include <set> 23
24#include <map>
24#include <string> 25#include <string>
25 26
26#include "open_files_list.h" 27#include "open_files_list.h"
@@ -34,9 +35,9 @@ class BacktraceMap;
34int open_tombstone(std::string* path); 35int open_tombstone(std::string* path);
35 36
36/* Creates a tombstone file and writes the crash dump to it. */ 37/* Creates a tombstone file and writes the crash dump to it. */
37void engrave_tombstone(int tombstone_fd, BacktraceMap* map, 38void engrave_tombstone(int tombstone_fd, BacktraceMap* map, const OpenFilesList* open_files,
38 const OpenFilesList* open_files, pid_t pid, pid_t tid, 39 pid_t pid, pid_t tid, const std::string& process_name,
39 const std::set<pid_t>* siblings, uintptr_t abort_msg_address, 40 const std::map<pid_t, std::string>& threads, uintptr_t abort_msg_address,
40 std::string* amfd_data); 41 std::string* amfd_data);
41 42
42void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, siginfo_t* siginfo, 43void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, siginfo_t* siginfo,
diff --git a/debuggerd/libdebuggerd/include/utility.h b/debuggerd/libdebuggerd/include/utility.h
index bbc45468b..e5e510634 100644
--- a/debuggerd/libdebuggerd/include/utility.h
+++ b/debuggerd/libdebuggerd/include/utility.h
@@ -83,4 +83,6 @@ bool wait_for_signal(pid_t tid, siginfo_t* siginfo);
83 83
84void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* fmt, ...); 84void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* fmt, ...);
85 85
86void read_with_default(const char* path, char* buf, size_t len, const char* default_value);
87
86#endif // _DEBUGGERD_UTILITY_H 88#endif // _DEBUGGERD_UTILITY_H
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index c05ccc358..c23da4415 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -32,8 +32,10 @@
32#include <memory> 32#include <memory>
33#include <string> 33#include <string>
34 34
35#include <android/log.h> 35#include <android-base/file.h>
36#include <android-base/stringprintf.h> 36#include <android-base/stringprintf.h>
37#include <android-base/unique_fd.h>
38#include <android/log.h>
37#include <backtrace/Backtrace.h> 39#include <backtrace/Backtrace.h>
38#include <backtrace/BacktraceMap.h> 40#include <backtrace/BacktraceMap.h>
39#include <cutils/properties.h> 41#include <cutils/properties.h>
@@ -247,41 +249,16 @@ static void dump_signal_info(log_t* log, pid_t tid) {
247 dump_signal_info(log, &si); 249 dump_signal_info(log, &si);
248} 250}
249 251
250static void dump_thread_info(log_t* log, pid_t pid, pid_t tid) { 252static void dump_thread_info(log_t* log, pid_t pid, pid_t tid, const char* process_name,
251 char path[64]; 253 const char* thread_name) {
252 char threadnamebuf[1024];
253 char* threadname = nullptr;
254 FILE *fp;
255
256 snprintf(path, sizeof(path), "/proc/%d/comm", tid);
257 if ((fp = fopen(path, "r"))) {
258 threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp);
259 fclose(fp);
260 if (threadname) {
261 size_t len = strlen(threadname);
262 if (len && threadname[len - 1] == '\n') {
263 threadname[len - 1] = '\0';
264 }
265 }
266 }
267 // Blacklist logd, logd.reader, logd.writer, logd.auditd, logd.control ... 254 // Blacklist logd, logd.reader, logd.writer, logd.auditd, logd.control ...
268 static const char logd[] = "logd"; 255 // TODO: Why is this controlled by thread name?
269 if (threadname != nullptr && !strncmp(threadname, logd, sizeof(logd) - 1) 256 if (strcmp(thread_name, "logd") == 0 || strncmp(thread_name, "logd.", 4) == 0) {
270 && (!threadname[sizeof(logd) - 1] || (threadname[sizeof(logd) - 1] == '.'))) {
271 log->should_retrieve_logcat = false; 257 log->should_retrieve_logcat = false;
272 } 258 }
273 259
274 char procnamebuf[1024]; 260 _LOG(log, logtype::HEADER, "pid: %d, tid: %d, name: %s >>> %s <<<\n", pid, tid, thread_name,
275 char* procname = nullptr; 261 process_name);
276
277 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
278 if ((fp = fopen(path, "r"))) {
279 procname = fgets(procnamebuf, sizeof(procnamebuf), fp);
280 fclose(fp);
281 }
282
283 _LOG(log, logtype::HEADER, "pid: %d, tid: %d, name: %s >>> %s <<<\n", pid, tid,
284 threadname ? threadname : "UNKNOWN", procname ? procname : "UNKNOWN");
285} 262}
286 263
287static void dump_stack_segment( 264static void dump_stack_segment(
@@ -493,13 +470,14 @@ static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log) {
493 } 470 }
494} 471}
495 472
496static void dump_thread(log_t* log, pid_t pid, pid_t tid, BacktraceMap* map, 473static void dump_thread(log_t* log, pid_t pid, pid_t tid, const std::string& process_name,
474 const std::string& thread_name, BacktraceMap* map,
497 uintptr_t abort_msg_address, bool primary_thread) { 475 uintptr_t abort_msg_address, bool primary_thread) {
498 log->current_tid = tid; 476 log->current_tid = tid;
499 if (!primary_thread) { 477 if (!primary_thread) {
500 _LOG(log, logtype::THREAD, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n"); 478 _LOG(log, logtype::THREAD, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n");
501 } 479 }
502 dump_thread_info(log, pid, tid); 480 dump_thread_info(log, pid, tid, process_name.c_str(), thread_name.c_str());
503 dump_signal_info(log, tid); 481 dump_signal_info(log, tid);
504 482
505 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map)); 483 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
@@ -654,9 +632,9 @@ static void dump_logs(log_t* log, pid_t pid, unsigned int tail) {
654} 632}
655 633
656// Dumps all information about the specified pid to the tombstone. 634// Dumps all information about the specified pid to the tombstone.
657static void dump_crash(log_t* log, BacktraceMap* map, 635static void dump_crash(log_t* log, BacktraceMap* map, const OpenFilesList* open_files, pid_t pid,
658 const OpenFilesList* open_files, pid_t pid, pid_t tid, 636 pid_t tid, const std::string& process_name,
659 const std::set<pid_t>* siblings, uintptr_t abort_msg_address) { 637 const std::map<pid_t, std::string>& threads, uintptr_t abort_msg_address) {
660 // don't copy log messages to tombstone unless this is a dev device 638 // don't copy log messages to tombstone unless this is a dev device
661 char value[PROPERTY_VALUE_MAX]; 639 char value[PROPERTY_VALUE_MAX];
662 property_get("ro.debuggable", value, "0"); 640 property_get("ro.debuggable", value, "0");
@@ -665,14 +643,17 @@ static void dump_crash(log_t* log, BacktraceMap* map,
665 _LOG(log, logtype::HEADER, 643 _LOG(log, logtype::HEADER,
666 "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"); 644 "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
667 dump_header_info(log); 645 dump_header_info(log);
668 dump_thread(log, pid, tid, map, abort_msg_address, true); 646 dump_thread(log, pid, tid, process_name, threads.find(tid)->second, map, abort_msg_address, true);
669 if (want_logs) { 647 if (want_logs) {
670 dump_logs(log, pid, 5); 648 dump_logs(log, pid, 5);
671 } 649 }
672 650
673 if (siblings && !siblings->empty()) { 651 for (const auto& it : threads) {
674 for (pid_t sibling : *siblings) { 652 pid_t thread_tid = it.first;
675 dump_thread(log, pid, sibling, map, 0, false); 653 const std::string& thread_name = it.second;
654
655 if (thread_tid != tid) {
656 dump_thread(log, pid, thread_tid, process_name, thread_name, map, 0, false);
676 } 657 }
677 } 658 }
678 659
@@ -739,16 +720,16 @@ int open_tombstone(std::string* out_path) {
739 return fd; 720 return fd;
740} 721}
741 722
742void engrave_tombstone(int tombstone_fd, BacktraceMap* map, 723void engrave_tombstone(int tombstone_fd, BacktraceMap* map, const OpenFilesList* open_files,
743 const OpenFilesList* open_files, pid_t pid, pid_t tid, 724 pid_t pid, pid_t tid, const std::string& process_name,
744 const std::set<pid_t>* siblings, uintptr_t abort_msg_address, 725 const std::map<pid_t, std::string>& threads, uintptr_t abort_msg_address,
745 std::string* amfd_data) { 726 std::string* amfd_data) {
746 log_t log; 727 log_t log;
747 log.current_tid = tid; 728 log.current_tid = tid;
748 log.crashed_tid = tid; 729 log.crashed_tid = tid;
749 log.tfd = tombstone_fd; 730 log.tfd = tombstone_fd;
750 log.amfd_data = amfd_data; 731 log.amfd_data = amfd_data;
751 dump_crash(&log, map, open_files, pid, tid, siblings, abort_msg_address); 732 dump_crash(&log, map, open_files, pid, tid, process_name, threads, abort_msg_address);
752} 733}
753 734
754void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, siginfo_t* siginfo, 735void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, siginfo_t* siginfo,
@@ -762,7 +743,13 @@ void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, s
762 log.tfd = tombstone_fd; 743 log.tfd = tombstone_fd;
763 log.amfd_data = nullptr; 744 log.amfd_data = nullptr;
764 745
765 dump_thread_info(&log, pid, tid); 746 char thread_name[16];
747 char process_name[128];
748
749 read_with_default("/proc/self/comm", thread_name, sizeof(thread_name), "<unknown>");
750 read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), "<unknown>");
751
752 dump_thread_info(&log, pid, tid, thread_name, process_name);
766 dump_signal_info(&log, siginfo); 753 dump_signal_info(&log, siginfo);
767 754
768 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid)); 755 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid));
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index 744cd72af..22fde5ea4 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -28,6 +28,7 @@
28#include <string> 28#include <string>
29 29
30#include <android-base/stringprintf.h> 30#include <android-base/stringprintf.h>
31#include <android-base/unique_fd.h>
31#include <backtrace/Backtrace.h> 32#include <backtrace/Backtrace.h>
32#include <log/log.h> 33#include <log/log.h>
33 34
@@ -202,3 +203,20 @@ void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* f
202 _LOG(log, logtype::MEMORY, "%s %s\n", logline.c_str(), ascii.c_str()); 203 _LOG(log, logtype::MEMORY, "%s %s\n", logline.c_str(), ascii.c_str());
203 } 204 }
204} 205}
206
207void read_with_default(const char* path, char* buf, size_t len, const char* default_value) {
208 android::base::unique_fd fd(open(path, O_RDONLY));
209 if (fd != -1) {
210 int rc = TEMP_FAILURE_RETRY(read(fd.get(), buf, len - 1));
211 if (rc != -1) {
212 buf[rc] = '\0';
213
214 // Trim trailing newlines.
215 if (rc > 0 && buf[rc - 1] == '\n') {
216 buf[rc - 1] = '\0';
217 }
218 return;
219 }
220 }
221 strcpy(buf, default_value);
222}