Always use main thread pid for manual dumping.
When running debuggerd from the command line, it's possible that
the signal will happen on a side thread. The original intercept
in tombstoned is set to only handle crashes from the main thread
pid, so in this case, the intercept doesn't occur. To fix this,
modify the code so that running debuggerd always sends the signal
to the main pid. In addition, modify the signal handler is entered
due to the BIONIC_SIGNAL_DEBUGGER signal, then the crashing tid is
set to the main thread pid instead of the current thread.
Add unit test to cover this case.
Bug: 194346289
Test: All unit tests pass.
Test: Verify the new unit test is getting the signal on the non-main
Test: thread and still properly handling the intercept.
Test: Modify the debuggerd code to send the signal to the non main pid
Test: and verify the dump still occurs correctly.
Change-Id: I2dd1bd11fc8ef4a6fe87f05ecc67ae349a101c82
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 360ea95..e20e8d9 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -93,8 +93,18 @@
errx(1, "process %d is a zombie", pid);
}
- if (kill(pid, 0) != 0) {
- err(1, "cannot send signal to process %d", pid);
+ // Send a signal to the main thread pid, not a side thread. The signal
+ // handler always sets the crashing tid to the main thread pid when sent this
+ // signal. This is to avoid a problem where the signal is sent to a process,
+ // but happens on a side thread and the intercept mismatches since it
+ // is looking for the main thread pid, not the tid of this random thread.
+ // See b/194346289 for extra details.
+ if (kill(proc_info.pid, 0) != 0) {
+ if (pid == proc_info.pid) {
+ err(1, "cannot send signal to process %d", pid);
+ } else {
+ err(1, "cannot send signal to main thread %d (requested thread %d)", proc_info.pid, pid);
+ }
}
unique_fd piperead, pipewrite;
@@ -103,9 +113,13 @@
}
std::thread redirect_thread = spawn_redirect_thread(std::move(piperead));
- if (!debuggerd_trigger_dump(pid, dump_type, 0, std::move(pipewrite))) {
+ if (!debuggerd_trigger_dump(proc_info.pid, dump_type, 0, std::move(pipewrite))) {
redirect_thread.join();
- errx(1, "failed to dump process %d", pid);
+ if (pid == proc_info.pid) {
+ errx(1, "failed to dump process %d", pid);
+ } else {
+ errx(1, "failed to dump main thread %d (requested thread %d)", proc_info.pid, pid);
+ }
}
redirect_thread.join();