Loading debuggerd/debuggerd_test.cpp +76 −6 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ constexpr char kWaitForGdbKey[] = "debug.debuggerd.wait_for_gdb"; } while (0) static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd, DebuggerdDumpType intercept_type) { InterceptStatus* status, DebuggerdDumpType intercept_type) { intercept_fd->reset(socket_local_client(kTombstonedInterceptSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET)); if (intercept_fd->get() == -1) { Loading Loading @@ -136,7 +136,7 @@ static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, uniq << ", received " << rc; } ASSERT_EQ(InterceptStatus::kRegistered, response.status); *status = response.status; } class CrasherTest : public ::testing::Test { Loading Loading @@ -180,7 +180,9 @@ void CrasherTest::StartIntercept(unique_fd* output_fd, DebuggerdDumpType interce FAIL() << "crasher hasn't been started"; } tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, intercept_type); InterceptStatus status; tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, &status, intercept_type); ASSERT_EQ(InterceptStatus::kRegistered, status); } void CrasherTest::FinishIntercept(int* result) { Loading Loading @@ -598,7 +600,9 @@ TEST(tombstoned, no_notify) { pid_t pid = 123'456'789 + i; unique_fd intercept_fd, output_fd; tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone); InterceptStatus status; tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone); ASSERT_EQ(InterceptStatus::kRegistered, status); { unique_fd tombstoned_socket, input_fd; Loading Loading @@ -630,7 +634,9 @@ TEST(tombstoned, stress) { pid_t pid = pid_base + dump; unique_fd intercept_fd, output_fd; tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone); InterceptStatus status; tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone); ASSERT_EQ(InterceptStatus::kRegistered, status); // Pretend to crash, and then immediately close the socket. unique_fd sockfd(socket_local_client(kTombstonedCrashSocketName, Loading Loading @@ -661,7 +667,9 @@ TEST(tombstoned, stress) { pid_t pid = pid_base + dump; unique_fd intercept_fd, output_fd; tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone); InterceptStatus status; tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone); ASSERT_EQ(InterceptStatus::kRegistered, status); { unique_fd tombstoned_socket, input_fd; Loading @@ -685,3 +693,65 @@ TEST(tombstoned, stress) { thread.join(); } } TEST(tombstoned, java_trace_intercept_smoke) { // Using a "real" PID is a little dangerous here - if the test fails // or crashes, we might end up getting a bogus / unreliable stack // trace. const pid_t self = getpid(); unique_fd intercept_fd, output_fd; InterceptStatus status; tombstoned_intercept(self, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace); ASSERT_EQ(InterceptStatus::kRegistered, status); // First connect to tombstoned requesting a native backtrace. This // should result in a "regular" FD and not the installed intercept. const char native[] = "native"; unique_fd tombstoned_socket, input_fd; ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdNativeBacktrace)); ASSERT_TRUE(android::base::WriteFully(input_fd.get(), native, sizeof(native))); tombstoned_notify_completion(tombstoned_socket.get()); // Then, connect to tombstoned asking for a java backtrace. This *should* // trigger the intercept. const char java[] = "java"; ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdJavaBacktrace)); ASSERT_TRUE(android::base::WriteFully(input_fd.get(), java, sizeof(java))); tombstoned_notify_completion(tombstoned_socket.get()); char outbuf[sizeof(java)]; ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf))); ASSERT_STREQ("java", outbuf); } TEST(tombstoned, multiple_intercepts) { const pid_t fake_pid = 1'234'567; unique_fd intercept_fd, output_fd; InterceptStatus status; tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace); ASSERT_EQ(InterceptStatus::kRegistered, status); unique_fd intercept_fd_2, output_fd_2; tombstoned_intercept(fake_pid, &intercept_fd_2, &output_fd_2, &status, kDebuggerdNativeBacktrace); ASSERT_EQ(InterceptStatus::kFailedAlreadyRegistered, status); } TEST(tombstoned, intercept_any) { const pid_t fake_pid = 1'234'567; unique_fd intercept_fd, output_fd; InterceptStatus status; tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdNativeBacktrace); ASSERT_EQ(InterceptStatus::kRegistered, status); const char any[] = "any"; unique_fd tombstoned_socket, input_fd; ASSERT_TRUE(tombstoned_connect(fake_pid, &tombstoned_socket, &input_fd, kDebuggerdAnyIntercept)); ASSERT_TRUE(android::base::WriteFully(input_fd.get(), any, sizeof(any))); tombstoned_notify_completion(tombstoned_socket.get()); char outbuf[sizeof(any)]; ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf))); ASSERT_STREQ("any", outbuf); } debuggerd/tombstoned/tombstoned.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ class CrashQueue { }; // Whether java trace dumps are produced via tombstoned. static constexpr bool kJavaTraceDumpsEnabled = false; static constexpr bool kJavaTraceDumpsEnabled = true; /* static */ CrashQueue* const CrashQueue::tombstone = new CrashQueue("/data/tombstones", "tombstone_" /* file_name_prefix */, 10 /* max_artifacts */, Loading Loading
debuggerd/debuggerd_test.cpp +76 −6 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ constexpr char kWaitForGdbKey[] = "debug.debuggerd.wait_for_gdb"; } while (0) static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd, DebuggerdDumpType intercept_type) { InterceptStatus* status, DebuggerdDumpType intercept_type) { intercept_fd->reset(socket_local_client(kTombstonedInterceptSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET)); if (intercept_fd->get() == -1) { Loading Loading @@ -136,7 +136,7 @@ static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, uniq << ", received " << rc; } ASSERT_EQ(InterceptStatus::kRegistered, response.status); *status = response.status; } class CrasherTest : public ::testing::Test { Loading Loading @@ -180,7 +180,9 @@ void CrasherTest::StartIntercept(unique_fd* output_fd, DebuggerdDumpType interce FAIL() << "crasher hasn't been started"; } tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, intercept_type); InterceptStatus status; tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, &status, intercept_type); ASSERT_EQ(InterceptStatus::kRegistered, status); } void CrasherTest::FinishIntercept(int* result) { Loading Loading @@ -598,7 +600,9 @@ TEST(tombstoned, no_notify) { pid_t pid = 123'456'789 + i; unique_fd intercept_fd, output_fd; tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone); InterceptStatus status; tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone); ASSERT_EQ(InterceptStatus::kRegistered, status); { unique_fd tombstoned_socket, input_fd; Loading Loading @@ -630,7 +634,9 @@ TEST(tombstoned, stress) { pid_t pid = pid_base + dump; unique_fd intercept_fd, output_fd; tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone); InterceptStatus status; tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone); ASSERT_EQ(InterceptStatus::kRegistered, status); // Pretend to crash, and then immediately close the socket. unique_fd sockfd(socket_local_client(kTombstonedCrashSocketName, Loading Loading @@ -661,7 +667,9 @@ TEST(tombstoned, stress) { pid_t pid = pid_base + dump; unique_fd intercept_fd, output_fd; tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone); InterceptStatus status; tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone); ASSERT_EQ(InterceptStatus::kRegistered, status); { unique_fd tombstoned_socket, input_fd; Loading @@ -685,3 +693,65 @@ TEST(tombstoned, stress) { thread.join(); } } TEST(tombstoned, java_trace_intercept_smoke) { // Using a "real" PID is a little dangerous here - if the test fails // or crashes, we might end up getting a bogus / unreliable stack // trace. const pid_t self = getpid(); unique_fd intercept_fd, output_fd; InterceptStatus status; tombstoned_intercept(self, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace); ASSERT_EQ(InterceptStatus::kRegistered, status); // First connect to tombstoned requesting a native backtrace. This // should result in a "regular" FD and not the installed intercept. const char native[] = "native"; unique_fd tombstoned_socket, input_fd; ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdNativeBacktrace)); ASSERT_TRUE(android::base::WriteFully(input_fd.get(), native, sizeof(native))); tombstoned_notify_completion(tombstoned_socket.get()); // Then, connect to tombstoned asking for a java backtrace. This *should* // trigger the intercept. const char java[] = "java"; ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdJavaBacktrace)); ASSERT_TRUE(android::base::WriteFully(input_fd.get(), java, sizeof(java))); tombstoned_notify_completion(tombstoned_socket.get()); char outbuf[sizeof(java)]; ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf))); ASSERT_STREQ("java", outbuf); } TEST(tombstoned, multiple_intercepts) { const pid_t fake_pid = 1'234'567; unique_fd intercept_fd, output_fd; InterceptStatus status; tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace); ASSERT_EQ(InterceptStatus::kRegistered, status); unique_fd intercept_fd_2, output_fd_2; tombstoned_intercept(fake_pid, &intercept_fd_2, &output_fd_2, &status, kDebuggerdNativeBacktrace); ASSERT_EQ(InterceptStatus::kFailedAlreadyRegistered, status); } TEST(tombstoned, intercept_any) { const pid_t fake_pid = 1'234'567; unique_fd intercept_fd, output_fd; InterceptStatus status; tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdNativeBacktrace); ASSERT_EQ(InterceptStatus::kRegistered, status); const char any[] = "any"; unique_fd tombstoned_socket, input_fd; ASSERT_TRUE(tombstoned_connect(fake_pid, &tombstoned_socket, &input_fd, kDebuggerdAnyIntercept)); ASSERT_TRUE(android::base::WriteFully(input_fd.get(), any, sizeof(any))); tombstoned_notify_completion(tombstoned_socket.get()); char outbuf[sizeof(any)]; ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf))); ASSERT_STREQ("any", outbuf); }
debuggerd/tombstoned/tombstoned.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ class CrashQueue { }; // Whether java trace dumps are produced via tombstoned. static constexpr bool kJavaTraceDumpsEnabled = false; static constexpr bool kJavaTraceDumpsEnabled = true; /* static */ CrashQueue* const CrashQueue::tombstone = new CrashQueue("/data/tombstones", "tombstone_" /* file_name_prefix */, 10 /* max_artifacts */, Loading