summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Gao2017-08-21 16:31:17 -0500
committerJosh Gao2017-12-15 16:11:12 -0600
commit2b2ae0c88ef83c4c53297ff54fa601b18c014fa4 (patch)
tree832d3ab764da9a63d4e22001f18045fa13078dd5 /debuggerd/libdebuggerd/test/tombstone_test.cpp
parent385ea22741ed5bad794fb6b1dff2b46481f241c4 (diff)
downloadplatform-system-core-2b2ae0c88ef83c4c53297ff54fa601b18c014fa4.tar.gz
platform-system-core-2b2ae0c88ef83c4c53297ff54fa601b18c014fa4.tar.xz
platform-system-core-2b2ae0c88ef83c4c53297ff54fa601b18c014fa4.zip
crash_dump: fork a copy of the target's address space.
Reduce the amount of time that a process remains paused by pausing its threads, fetching their registers, and then performing unwinding on a copy of its address space. This also works around a kernel change that's in 4.9 that prevents ptrace from reading memory of processes that we don't have immediate permissions to ptrace (even if we previously ptraced them). Bug: http://b/62112103 Bug: http://b/63989615 Test: treehugger Change-Id: I7b9cc5dd8f54a354bc61f1bda0d2b7a8a55733c4
Diffstat (limited to 'debuggerd/libdebuggerd/test/tombstone_test.cpp')
-rw-r--r--debuggerd/libdebuggerd/test/tombstone_test.cpp173
1 files changed, 10 insertions, 163 deletions
diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp
index 59a43b73b..1e3a10f08 100644
--- a/debuggerd/libdebuggerd/test/tombstone_test.cpp
+++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp
@@ -29,11 +29,6 @@
29#include "elf_fake.h" 29#include "elf_fake.h"
30#include "host_signal_fixup.h" 30#include "host_signal_fixup.h"
31#include "log_fake.h" 31#include "log_fake.h"
32#include "ptrace_fake.h"
33
34// In order to test this code, we need to include the tombstone.cpp code.
35// Including it, also allows us to override the ptrace function.
36#define ptrace ptrace_fake
37 32
38#include "tombstone.cpp" 33#include "tombstone.cpp"
39 34
@@ -50,7 +45,6 @@ class TombstoneTest : public ::testing::Test {
50 protected: 45 protected:
51 virtual void SetUp() { 46 virtual void SetUp() {
52 map_mock_.reset(new BacktraceMapMock()); 47 map_mock_.reset(new BacktraceMapMock());
53 backtrace_mock_.reset(new BacktraceMock(map_mock_.get()));
54 48
55 char tmp_file[256]; 49 char tmp_file[256];
56 const char data_template[] = "/data/local/tmp/debuggerd_memory_testXXXXXX"; 50 const char data_template[] = "/data/local/tmp/debuggerd_memory_testXXXXXX";
@@ -77,11 +71,6 @@ class TombstoneTest : public ::testing::Test {
77 71
78 resetLogs(); 72 resetLogs();
79 elf_set_fake_build_id(""); 73 elf_set_fake_build_id("");
80 siginfo_t si;
81 memset(&si, 0, sizeof(si));
82 si.si_signo = SIGABRT;
83 si.si_code = SI_KERNEL;
84 ptrace_set_fake_getsiginfo(si);
85 } 74 }
86 75
87 virtual void TearDown() { 76 virtual void TearDown() {
@@ -91,7 +80,6 @@ class TombstoneTest : public ::testing::Test {
91 } 80 }
92 81
93 std::unique_ptr<BacktraceMapMock> map_mock_; 82 std::unique_ptr<BacktraceMapMock> map_mock_;
94 std::unique_ptr<BacktraceMock> backtrace_mock_;
95 83
96 log_t log_; 84 log_t log_;
97 std::string amfd_data_; 85 std::string amfd_data_;
@@ -108,7 +96,7 @@ TEST_F(TombstoneTest, single_map) {
108#endif 96#endif
109 map_mock_->AddMap(map); 97 map_mock_->AddMap(map);
110 98
111 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100); 99 dump_all_maps(&log_, map_mock_.get(), nullptr, 0);
112 100
113 std::string tombstone_contents; 101 std::string tombstone_contents;
114 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 102 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -143,7 +131,7 @@ TEST_F(TombstoneTest, single_map_elf_build_id) {
143 map_mock_->AddMap(map); 131 map_mock_->AddMap(map);
144 132
145 elf_set_fake_build_id("abcdef1234567890abcdef1234567890"); 133 elf_set_fake_build_id("abcdef1234567890abcdef1234567890");
146 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100); 134 dump_all_maps(&log_, map_mock_.get(), nullptr, 0);
147 135
148 std::string tombstone_contents; 136 std::string tombstone_contents;
149 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 137 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -182,7 +170,7 @@ TEST_F(TombstoneTest, single_map_no_build_id) {
182 map_mock_->AddMap(map); 170 map_mock_->AddMap(map);
183 171
184 elf_set_fake_build_id("abcdef1234567890abcdef1234567890"); 172 elf_set_fake_build_id("abcdef1234567890abcdef1234567890");
185 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100); 173 dump_all_maps(&log_, map_mock_.get(), nullptr, 0);
186 174
187 std::string tombstone_contents; 175 std::string tombstone_contents;
188 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 176 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -240,7 +228,7 @@ TEST_F(TombstoneTest, multiple_maps) {
240 map.name = "/system/lib/fake.so"; 228 map.name = "/system/lib/fake.so";
241 map_mock_->AddMap(map); 229 map_mock_->AddMap(map);
242 230
243 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100); 231 dump_all_maps(&log_, map_mock_.get(), nullptr, 0);
244 232
245 std::string tombstone_contents; 233 std::string tombstone_contents;
246 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 234 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -294,13 +282,7 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_before) {
294 map.name = "/system/lib/fake.so"; 282 map.name = "/system/lib/fake.so";
295 map_mock_->AddMap(map); 283 map_mock_->AddMap(map);
296 284
297 siginfo_t si; 285 dump_all_maps(&log_, map_mock_.get(), nullptr, 0x1000);
298 memset(&si, 0, sizeof(si));
299 si.si_signo = SIGBUS;
300 si.si_code = SI_KERNEL;
301 si.si_addr = reinterpret_cast<void*>(0x1000);
302 ptrace_set_fake_getsiginfo(si);
303 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
304 286
305 std::string tombstone_contents; 287 std::string tombstone_contents;
306 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 288 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -352,13 +334,7 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_between) {
352 map.name = "/system/lib/fake.so"; 334 map.name = "/system/lib/fake.so";
353 map_mock_->AddMap(map); 335 map_mock_->AddMap(map);
354 336
355 siginfo_t si; 337 dump_all_maps(&log_, map_mock_.get(), nullptr, 0xa533000);
356 memset(&si, 0, sizeof(si));
357 si.si_signo = SIGBUS;
358 si.si_code = SI_KERNEL;
359 si.si_addr = reinterpret_cast<void*>(0xa533000);
360 ptrace_set_fake_getsiginfo(si);
361 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
362 338
363 std::string tombstone_contents; 339 std::string tombstone_contents;
364 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 340 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -410,13 +386,7 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) {
410 map.name = "/system/lib/fake.so"; 386 map.name = "/system/lib/fake.so";
411 map_mock_->AddMap(map); 387 map_mock_->AddMap(map);
412 388
413 siginfo_t si; 389 dump_all_maps(&log_, map_mock_.get(), nullptr, 0xa534040);
414 memset(&si, 0, sizeof(si));
415 si.si_signo = SIGBUS;
416 si.si_code = SI_KERNEL;
417 si.si_addr = reinterpret_cast<void*>(0xa534040);
418 ptrace_set_fake_getsiginfo(si);
419 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
420 390
421 std::string tombstone_contents; 391 std::string tombstone_contents;
422 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 392 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -466,17 +436,12 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_after) {
466 map.name = "/system/lib/fake.so"; 436 map.name = "/system/lib/fake.so";
467 map_mock_->AddMap(map); 437 map_mock_->AddMap(map);
468 438
469 siginfo_t si;
470 memset(&si, 0, sizeof(si));
471 si.si_signo = SIGBUS;
472 si.si_code = SI_KERNEL;
473#if defined(__LP64__) 439#if defined(__LP64__)
474 si.si_addr = reinterpret_cast<void*>(0x12345a534040UL); 440 uintptr_t addr = 0x12345a534040UL;
475#else 441#else
476 si.si_addr = reinterpret_cast<void*>(0xf534040UL); 442 uintptr_t addr = 0xf534040UL;
477#endif 443#endif
478 ptrace_set_fake_getsiginfo(si); 444 dump_all_maps(&log_, map_mock_.get(), nullptr, addr);
479 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
480 445
481 std::string tombstone_contents; 446 std::string tombstone_contents;
482 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 447 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -503,124 +468,6 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_after) {
503 ASSERT_STREQ("", getFakeLogPrint().c_str()); 468 ASSERT_STREQ("", getFakeLogPrint().c_str());
504} 469}
505 470
506TEST_F(TombstoneTest, multiple_maps_getsiginfo_fail) {
507 backtrace_map_t map;
508
509 map.start = 0xa434000;
510 map.end = 0xa435000;
511 map.offset = 0x1000;
512 map.load_bias = 0xd000;
513 map.flags = PROT_WRITE;
514 map_mock_->AddMap(map);
515
516 siginfo_t si;
517 memset(&si, 0, sizeof(si));
518 ptrace_set_fake_getsiginfo(si);
519 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
520
521 std::string tombstone_contents;
522 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
523 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
524 const char* expected_dump =
525 "\nmemory map (1 entry):\n"
526#if defined(__LP64__)
527 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n";
528#else
529 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n";
530#endif
531 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
532
533 ASSERT_STREQ("", amfd_data_.c_str());
534
535 // Verify that the log buf is empty, and no error messages.
536 ASSERT_STREQ("", getFakeLogBuf().c_str());
537 ASSERT_STREQ("6 DEBUG Cannot get siginfo for 100: Bad address\n\n", getFakeLogPrint().c_str());
538}
539
540TEST_F(TombstoneTest, multiple_maps_check_signal_has_si_addr) {
541 backtrace_map_t map;
542
543 map.start = 0xa434000;
544 map.end = 0xa435000;
545 map.flags = PROT_WRITE;
546 map_mock_->AddMap(map);
547
548 for (int i = 1; i < 255; i++) {
549 ASSERT_TRUE(ftruncate(log_.tfd, 0) == 0);
550 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
551
552 siginfo_t si;
553 memset(&si, 0, sizeof(si));
554 si.si_signo = i;
555 si.si_code = SI_KERNEL;
556 si.si_addr = reinterpret_cast<void*>(0x1000);
557 ptrace_set_fake_getsiginfo(si);
558 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
559
560 std::string tombstone_contents;
561 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
562 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
563 bool has_addr = false;
564 switch (si.si_signo) {
565 case SIGBUS:
566 case SIGFPE:
567 case SIGILL:
568 case SIGSEGV:
569 case SIGTRAP:
570 has_addr = true;
571 break;
572 }
573
574 const char* expected_addr_dump = \
575"\nmemory map (1 entry):\n"
576#if defined(__LP64__)
577"--->Fault address falls at 00000000'00001000 before any mapped regions\n"
578" 00000000'0a434000-00000000'0a434fff -w- 0 1000\n";
579#else
580"--->Fault address falls at 00001000 before any mapped regions\n"
581" 0a434000-0a434fff -w- 0 1000\n";
582#endif
583 const char* expected_dump = \
584"\nmemory map (1 entry):\n"
585#if defined(__LP64__)
586" 00000000'0a434000-00000000'0a434fff -w- 0 1000\n";
587#else
588" 0a434000-0a434fff -w- 0 1000\n";
589#endif
590 if (has_addr) {
591 ASSERT_STREQ(expected_addr_dump, tombstone_contents.c_str())
592 << "Signal " << si.si_signo << " expected to include an address.";
593 } else {
594 ASSERT_STREQ(expected_dump, tombstone_contents.c_str())
595 << "Signal " << si.si_signo << " is not expected to include an address.";
596 }
597
598 ASSERT_STREQ("", amfd_data_.c_str());
599
600 // Verify that the log buf is empty, and no error messages.
601 ASSERT_STREQ("", getFakeLogBuf().c_str());
602 ASSERT_STREQ("", getFakeLogPrint().c_str());
603 }
604}
605
606TEST_F(TombstoneTest, dump_signal_info_error) {
607 siginfo_t si;
608 memset(&si, 0, sizeof(si));
609 ptrace_set_fake_getsiginfo(si);
610
611 dump_signal_info(&log_, 123);
612
613 std::string tombstone_contents;
614 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
615 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
616 ASSERT_STREQ("", tombstone_contents.c_str());
617
618 ASSERT_STREQ("", getFakeLogBuf().c_str());
619 ASSERT_STREQ("6 DEBUG cannot get siginfo: Bad address\n\n", getFakeLogPrint().c_str());
620
621 ASSERT_STREQ("", amfd_data_.c_str());
622}
623
624TEST_F(TombstoneTest, dump_log_file_error) { 471TEST_F(TombstoneTest, dump_log_file_error) {
625 log_.should_retrieve_logcat = true; 472 log_.should_retrieve_logcat = true;
626 dump_log_file(&log_, 123, "/fake/filename", 10); 473 dump_log_file(&log_, 123, "/fake/filename", 10);