Loading debuggerd/crash_dump.cpp +28 −27 Original line number Diff line number Diff line Loading @@ -257,6 +257,9 @@ int main(int argc, char** argv) { exit(0); } // Die if we take too long. alarm(20); check_process(target_proc_fd, target); std::string attach_error; Loading Loading @@ -316,10 +319,9 @@ int main(int argc, char** argv) { // Now that we have the signal that kicked things off, attach all of the // sibling threads, and then proceed. bool fatal_signal = signo != DEBUGGER_SIGNAL; int resume_signal = fatal_signal ? signo : 0; std::set<pid_t> siblings; std::set<pid_t> attached_siblings; if (resume_signal == 0) { if (fatal_signal) { if (!android::procinfo::GetProcessTids(target, &siblings)) { PLOG(FATAL) << "failed to get process siblings"; } Loading Loading @@ -352,12 +354,29 @@ int main(int argc, char** argv) { attached_siblings, abort_address, fatal_signal ? &amfd_data : nullptr); } // We don't actually need to PTRACE_DETACH, as long as our tracees aren't in // group-stop state, which is true as long as no stopping signals are sent. bool wait_for_gdb = android::base::GetBoolProperty("debug.debuggerd.wait_for_gdb", false); if (wait_for_gdb) { if (!fatal_signal || siginfo.si_code == SI_USER) { // Don't wait_for_gdb when the process didn't actually crash. if (!fatal_signal) { wait_for_gdb = false; } else { } // If the process crashed or we need to send it SIGSTOP for wait_for_gdb, // get it in a state where it can receive signals, and then send the relevant // signal. if (wait_for_gdb || fatal_signal) { if (ptrace(PTRACE_INTERRUPT, main_tid, 0, 0) != 0) { PLOG(ERROR) << "failed to use PTRACE_INTERRUPT on " << main_tid; } if (tgkill(target, main_tid, wait_for_gdb ? SIGSTOP : signo) != 0) { PLOG(ERROR) << "failed to resend signal " << signo << " to " << main_tid; } } if (wait_for_gdb) { // Use ALOGI to line up with output from engrave_tombstone. ALOGI( "***********************************************************\n" Loading @@ -369,24 +388,6 @@ int main(int argc, char** argv) { "***********************************************************", target, main_tid); } } for (pid_t tid : attached_siblings) { // Don't send the signal to sibling threads. if (ptrace(PTRACE_DETACH, tid, 0, wait_for_gdb ? SIGSTOP : 0) != 0) { PLOG(ERROR) << "ptrace detach from " << tid << " failed"; } } if (ptrace(PTRACE_DETACH, main_tid, 0, wait_for_gdb ? SIGSTOP : resume_signal)) { PLOG(ERROR) << "ptrace detach from main thread " << main_tid << " failed"; } if (wait_for_gdb) { if (tgkill(target, main_tid, resume_signal) != 0) { PLOG(ERROR) << "failed to resend signal to process " << target; } } if (fatal_signal) { activity_manager_notify(target, signo, amfd_data); Loading debuggerd/debuggerd_test.cpp +3 −12 Original line number Diff line number Diff line Loading @@ -340,24 +340,15 @@ TEST_F(CrasherTest, wait_for_gdb) { AssertDeath(SIGABRT); } // wait_for_gdb shouldn't trigger on manually sent signals. TEST_F(CrasherTest, wait_for_gdb_signal) { if (!android::base::SetProperty(kWaitForGdbKey, "1")) { FAIL() << "failed to enable wait_for_gdb"; } StartCrasher("abort"); ASSERT_EQ(0, kill(crasher_pid, SIGABRT)) << strerror(errno); std::this_thread::sleep_for(500ms); int status; ASSERT_EQ(crasher_pid, (TIMEOUT(1, waitpid(crasher_pid, &status, WUNTRACED)))); ASSERT_TRUE(WIFSTOPPED(status)); ASSERT_EQ(SIGSTOP, WSTOPSIG(status)); ASSERT_EQ(0, kill(crasher_pid, SIGCONT)) << strerror(errno); AssertDeath(SIGABRT); ASSERT_EQ(0, kill(crasher_pid, SIGSEGV)) << strerror(errno); AssertDeath(SIGSEGV); } TEST_F(CrasherTest, backtrace) { Loading Loading
debuggerd/crash_dump.cpp +28 −27 Original line number Diff line number Diff line Loading @@ -257,6 +257,9 @@ int main(int argc, char** argv) { exit(0); } // Die if we take too long. alarm(20); check_process(target_proc_fd, target); std::string attach_error; Loading Loading @@ -316,10 +319,9 @@ int main(int argc, char** argv) { // Now that we have the signal that kicked things off, attach all of the // sibling threads, and then proceed. bool fatal_signal = signo != DEBUGGER_SIGNAL; int resume_signal = fatal_signal ? signo : 0; std::set<pid_t> siblings; std::set<pid_t> attached_siblings; if (resume_signal == 0) { if (fatal_signal) { if (!android::procinfo::GetProcessTids(target, &siblings)) { PLOG(FATAL) << "failed to get process siblings"; } Loading Loading @@ -352,12 +354,29 @@ int main(int argc, char** argv) { attached_siblings, abort_address, fatal_signal ? &amfd_data : nullptr); } // We don't actually need to PTRACE_DETACH, as long as our tracees aren't in // group-stop state, which is true as long as no stopping signals are sent. bool wait_for_gdb = android::base::GetBoolProperty("debug.debuggerd.wait_for_gdb", false); if (wait_for_gdb) { if (!fatal_signal || siginfo.si_code == SI_USER) { // Don't wait_for_gdb when the process didn't actually crash. if (!fatal_signal) { wait_for_gdb = false; } else { } // If the process crashed or we need to send it SIGSTOP for wait_for_gdb, // get it in a state where it can receive signals, and then send the relevant // signal. if (wait_for_gdb || fatal_signal) { if (ptrace(PTRACE_INTERRUPT, main_tid, 0, 0) != 0) { PLOG(ERROR) << "failed to use PTRACE_INTERRUPT on " << main_tid; } if (tgkill(target, main_tid, wait_for_gdb ? SIGSTOP : signo) != 0) { PLOG(ERROR) << "failed to resend signal " << signo << " to " << main_tid; } } if (wait_for_gdb) { // Use ALOGI to line up with output from engrave_tombstone. ALOGI( "***********************************************************\n" Loading @@ -369,24 +388,6 @@ int main(int argc, char** argv) { "***********************************************************", target, main_tid); } } for (pid_t tid : attached_siblings) { // Don't send the signal to sibling threads. if (ptrace(PTRACE_DETACH, tid, 0, wait_for_gdb ? SIGSTOP : 0) != 0) { PLOG(ERROR) << "ptrace detach from " << tid << " failed"; } } if (ptrace(PTRACE_DETACH, main_tid, 0, wait_for_gdb ? SIGSTOP : resume_signal)) { PLOG(ERROR) << "ptrace detach from main thread " << main_tid << " failed"; } if (wait_for_gdb) { if (tgkill(target, main_tid, resume_signal) != 0) { PLOG(ERROR) << "failed to resend signal to process " << target; } } if (fatal_signal) { activity_manager_notify(target, signo, amfd_data); Loading
debuggerd/debuggerd_test.cpp +3 −12 Original line number Diff line number Diff line Loading @@ -340,24 +340,15 @@ TEST_F(CrasherTest, wait_for_gdb) { AssertDeath(SIGABRT); } // wait_for_gdb shouldn't trigger on manually sent signals. TEST_F(CrasherTest, wait_for_gdb_signal) { if (!android::base::SetProperty(kWaitForGdbKey, "1")) { FAIL() << "failed to enable wait_for_gdb"; } StartCrasher("abort"); ASSERT_EQ(0, kill(crasher_pid, SIGABRT)) << strerror(errno); std::this_thread::sleep_for(500ms); int status; ASSERT_EQ(crasher_pid, (TIMEOUT(1, waitpid(crasher_pid, &status, WUNTRACED)))); ASSERT_TRUE(WIFSTOPPED(status)); ASSERT_EQ(SIGSTOP, WSTOPSIG(status)); ASSERT_EQ(0, kill(crasher_pid, SIGCONT)) << strerror(errno); AssertDeath(SIGABRT); ASSERT_EQ(0, kill(crasher_pid, SIGSEGV)) << strerror(errno); AssertDeath(SIGSEGV); } TEST_F(CrasherTest, backtrace) { Loading