debuggerd_handler: implement missing fallback functionality.
Allow the fallback implementation to dump traces and create tombstones
in seccomped processes.
Bug: http://b/35858739
Test: debuggerd -b `pidof media.codec`; killall -ABRT media.codec
Change-Id: I381b283de39a66d8900f1c320d32497d6f2b4ec4
diff --git a/debuggerd/libdebuggerd/backtrace.cpp b/debuggerd/libdebuggerd/backtrace.cpp
index 0664442..df49aef 100644
--- a/debuggerd/libdebuggerd/backtrace.cpp
+++ b/debuggerd/libdebuggerd/backtrace.cpp
@@ -67,15 +67,15 @@
_LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid);
}
-static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) {
- char path[PATH_MAX];
- char threadnamebuf[1024];
- char* threadname = NULL;
+static void log_thread_name(log_t* log, pid_t tid) {
FILE* fp;
+ char buf[1024];
+ char path[PATH_MAX];
+ char* threadname = NULL;
snprintf(path, sizeof(path), "/proc/%d/comm", tid);
if ((fp = fopen(path, "r"))) {
- threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp);
+ threadname = fgets(buf, sizeof(buf), fp);
fclose(fp);
if (threadname) {
size_t len = strlen(threadname);
@@ -84,8 +84,11 @@
}
}
}
-
_LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid);
+}
+
+static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) {
+ log_thread_name(log, tid);
std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
if (backtrace->Unwind(0)) {
@@ -112,6 +115,41 @@
dump_process_footer(&log, pid);
}
+void dump_backtrace_ucontext(int output_fd, ucontext_t* ucontext) {
+ pid_t pid = getpid();
+ pid_t tid = gettid();
+
+ log_t log;
+ log.tfd = output_fd;
+ log.amfd_data = nullptr;
+
+ log_thread_name(&log, tid);
+
+ std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid));
+ if (backtrace->Unwind(0, ucontext)) {
+ dump_backtrace_to_log(backtrace.get(), &log, " ");
+ } else {
+ ALOGE("Unwind failed: tid = %d: %s", tid,
+ backtrace->GetErrorString(backtrace->GetError()).c_str());
+ }
+}
+
+void dump_backtrace_header(int output_fd) {
+ log_t log;
+ log.tfd = output_fd;
+ log.amfd_data = nullptr;
+
+ dump_process_header(&log, getpid());
+}
+
+void dump_backtrace_footer(int output_fd) {
+ log_t log;
+ log.tfd = output_fd;
+ log.amfd_data = nullptr;
+
+ dump_process_footer(&log, getpid());
+}
+
void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix) {
for (size_t i = 0; i < backtrace->NumFrames(); i++) {
_LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str());