TEST_F(MallocDebugConfigTest, overflow) { ASSERT_FALSE(InitConfig("backtrace=99999999999999999999")); ASSERT_STREQ("", getFakeLogBuf().c_str()); std::string log_msg( "6 malloc_debug malloc_testing: bad value for option 'backtrace': " "Math result not representable\n"); ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, rear_guard_max_error) { ASSERT_FALSE(InitConfig("rear_guard=20000")); ASSERT_STREQ("", getFakeLogBuf().c_str()); std::string log_msg( "6 malloc_debug malloc_testing: bad value for option 'rear_guard', " "value must be <= 16384: 20000\n"); ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, no_space) { ASSERT_FALSE(InitConfig("backtrace=10front_guard")); ASSERT_STREQ("", getFakeLogBuf().c_str()); std::string log_msg( "6 malloc_debug malloc_testing: bad value for option 'backtrace', " "non space found after option: front_guard\n"); ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, illegal_value_negative) { ASSERT_FALSE(InitConfig("backtrace=-1")); ASSERT_STREQ("", getFakeLogBuf().c_str()); std::string log_msg( "6 malloc_debug malloc_testing: bad value for option 'backtrace', " "value cannot be negative: -1\n"); ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, free_track_backtrace_num_frames_zero) { ASSERT_TRUE(InitConfig("free_track_backtrace_num_frames=0")); ASSERT_EQ(0U, config->options); ASSERT_EQ(0U, config->free_track_backtrace_num_frames); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, free_track_backtrace_num_frames_max_error) { ASSERT_FALSE(InitConfig("free_track_backtrace_num_frames=400")); ASSERT_STREQ("", getFakeLogBuf().c_str()); std::string log_msg( "6 malloc_debug malloc_testing: bad value for option 'free_track_backtrace_num_frames', " "value must be <= 256: 400\n"); ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, backtrace_enable_on_signal_max_error) { ASSERT_FALSE(InitConfig("backtrace_enable_on_signal=300")); ASSERT_STREQ("", getFakeLogBuf().c_str()); std::string log_msg( "6 malloc_debug malloc_testing: bad value for option 'backtrace_enable_on_signal', " "value must be <= 256: 300\n"); ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, leak_track_fail) { ASSERT_FALSE(InitConfig("leak_track=100")); ASSERT_STREQ("", getFakeLogBuf().c_str()); std::string log_msg( "6 malloc_debug malloc_testing: value set for option 'leak_track' " "which does not take a value\n"); ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, fill_min_error) { ASSERT_FALSE(InitConfig("fill=0")); ASSERT_STREQ("", getFakeLogBuf().c_str()); std::string log_msg( "6 malloc_debug malloc_testing: bad value for option 'fill', " "value must be >= 1: 0\n"); ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, multiple_options) { ASSERT_TRUE(InitConfig(" backtrace=64 front_guard=48")); ASSERT_EQ(BACKTRACE | TRACK_ALLOCS | FRONT_GUARD, config->options); ASSERT_EQ(64U, config->backtrace_frames); ASSERT_EQ(48U, config->front_guard_bytes); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(TombstoneTest, multiple_maps_fault_address_between) { backtrace_map_t map; map.start = 0xa434000; map.end = 0xa435000; map.offset = 0x1000; map.load_base = 0xd000; map.flags = PROT_WRITE; map_mock_->AddMap(map); map.start = 0xa534000; map.end = 0xa535000; map.offset = 0x3000; map.load_base = 0x2000; map.flags = PROT_EXEC; map_mock_->AddMap(map); map.start = 0xa634000; map.end = 0xa635000; map.offset = 0; map.load_base = 0; map.flags = PROT_READ | PROT_WRITE | PROT_EXEC; map.name = "/system/lib/fake.so"; map_mock_->AddMap(map); siginfo_t si; si.si_signo = SIGBUS; si.si_addr = reinterpret_cast<void*>(0xa533000); ptrace_set_fake_getsiginfo(si); dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100); std::string tombstone_contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); const char* expected_dump = \ "\nmemory map: (fault address prefixed with --->)\n" #if defined(__LP64__) " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n" "--->Fault address falls at 00000000'0a533000 between mapped regions\n" " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n" " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"; #else " 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n" "--->Fault address falls at 0a533000 between mapped regions\n" " 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n" " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"; #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, rear_guard) { ASSERT_TRUE(InitConfig("rear_guard=50")); ASSERT_EQ(REAR_GUARD, config->options); ASSERT_EQ(50U, config->rear_guard_bytes); ASSERT_TRUE(InitConfig("rear_guard")); ASSERT_EQ(REAR_GUARD, config->options); ASSERT_EQ(32U, config->rear_guard_bytes); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, expand_alloc) { ASSERT_TRUE(InitConfig("expand_alloc=1234")); ASSERT_EQ(EXPAND_ALLOC, config->options); ASSERT_EQ(1234U, config->expand_alloc_bytes); ASSERT_TRUE(InitConfig("expand_alloc")); ASSERT_EQ(EXPAND_ALLOC, config->options); ASSERT_EQ(16U, config->expand_alloc_bytes); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, free_track_backtrace_num_frames_and_free_track) { ASSERT_TRUE(InitConfig("free_track free_track_backtrace_num_frames=123")); ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options); ASSERT_EQ(123U, config->free_track_backtrace_num_frames); ASSERT_TRUE(InitConfig("free_track free_track_backtrace_num_frames")); ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options); ASSERT_EQ(16U, config->free_track_backtrace_num_frames); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, fill_on_free) { ASSERT_TRUE(InitConfig("fill_on_free=64")); ASSERT_EQ(FILL_ON_FREE, config->options); ASSERT_EQ(64U, config->fill_on_free_bytes); ASSERT_TRUE(InitConfig("fill_on_free")); ASSERT_EQ(FILL_ON_FREE, config->options); ASSERT_EQ(SIZE_MAX, config->fill_on_free_bytes); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, backtrace_enable_on_signal) { ASSERT_TRUE(InitConfig("backtrace_enable_on_signal=64")); ASSERT_EQ(BACKTRACE | TRACK_ALLOCS, config->options); ASSERT_EQ(64U, config->backtrace_frames); ASSERT_TRUE(InitConfig("backtrace_enable_on_signal")); ASSERT_EQ(BACKTRACE | TRACK_ALLOCS, config->options); ASSERT_EQ(16U, config->backtrace_frames); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, guard) { ASSERT_TRUE(InitConfig("guard=32")); ASSERT_EQ(FRONT_GUARD | REAR_GUARD, config->options); ASSERT_EQ(32U, config->front_guard_bytes); ASSERT_EQ(32U, config->rear_guard_bytes); ASSERT_TRUE(InitConfig("guard")); ASSERT_EQ(FRONT_GUARD | REAR_GUARD, config->options); ASSERT_EQ(32U, config->front_guard_bytes); ASSERT_EQ(32U, config->rear_guard_bytes); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, free_track_and_fill_on_free) { ASSERT_TRUE(InitConfig("free_track=1234 fill_on_free=32")); ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options); ASSERT_EQ(1234U, config->free_track_allocations); ASSERT_EQ(32U, config->fill_on_free_bytes); ASSERT_TRUE(InitConfig("free_track fill_on_free=60")); ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options); ASSERT_EQ(100U, config->free_track_allocations); ASSERT_EQ(60U, config->fill_on_free_bytes); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, front_guard) { ASSERT_TRUE(InitConfig("front_guard=48")) << getFakeLogPrint(); ASSERT_EQ(FRONT_GUARD, config->options); ASSERT_EQ(48U, config->front_guard_bytes); ASSERT_TRUE(InitConfig("front_guard")) << getFakeLogPrint(); ASSERT_EQ(FRONT_GUARD, config->options); ASSERT_EQ(32U, config->front_guard_bytes); ASSERT_TRUE(InitConfig("front_guard=39")) << getFakeLogPrint(); ASSERT_EQ(FRONT_GUARD, config->options); #if defined(__LP64__) ASSERT_EQ(48U, config->front_guard_bytes); #else ASSERT_EQ(40U, config->front_guard_bytes); #endif ASSERT_TRUE(InitConfig("front_guard=41")) << getFakeLogPrint(); ASSERT_EQ(FRONT_GUARD, config->options); ASSERT_EQ(48U, config->front_guard_bytes); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(TombstoneTest, dump_log_file_error) { log_.should_retrieve_logcat = true; dump_log_file(&log_, 123, "/fake/filename", 10); std::string tombstone_contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); ASSERT_STREQ("", tombstone_contents.c_str()); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("6 DEBUG Unable to open /fake/filename: Permission denied\n\n", getFakeLogPrint().c_str()); ASSERT_STREQ("", amfd_data_.c_str()); }
TEST_F(MallocDebugConfigTest, front_guard) { ASSERT_TRUE(InitConfig("front_guard=24")); ASSERT_EQ(FRONT_GUARD, config->options); ASSERT_EQ(24U, config->front_guard_bytes); ASSERT_TRUE(InitConfig("front_guard")); ASSERT_EQ(FRONT_GUARD, config->options); ASSERT_EQ(32U, config->front_guard_bytes); ASSERT_TRUE(InitConfig("front_guard=39")); ASSERT_EQ(FRONT_GUARD, config->options); ASSERT_EQ(40U, config->front_guard_bytes); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(MallocDebugConfigTest, free_track) { ASSERT_TRUE(InitConfig("free_track=1234")); ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options); ASSERT_EQ(1234U, config->free_track_allocations); ASSERT_EQ(SIZE_MAX, config->fill_on_free_bytes); ASSERT_EQ(16U, config->free_track_backtrace_num_frames); ASSERT_TRUE(InitConfig("free_track")); ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options); ASSERT_EQ(100U, config->free_track_allocations); ASSERT_EQ(SIZE_MAX, config->fill_on_free_bytes); ASSERT_EQ(16U, config->free_track_backtrace_num_frames); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(TombstoneTest, dump_signal_info_error) { siginfo_t si; si.si_signo = 0; ptrace_set_fake_getsiginfo(si); dump_signal_info(&log_, 123, SIGSEGV, 10); std::string tombstone_contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); ASSERT_STREQ("", tombstone_contents.c_str()); ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("6 DEBUG cannot get siginfo: Bad address\n\n", getFakeLogPrint().c_str()); ASSERT_STREQ("", amfd_data_.c_str()); }
// Even though build id is present, it should not be printed in either of // these cases. TEST_F(TombstoneTest, single_map_no_build_id) { backtrace_map_t map; #if defined(__LP64__) map.start = 0x123456789abcd000UL; map.end = 0x123456789abdf000UL; #else map.start = 0x1234000; map.end = 0x1235000; #endif map.flags = PROT_WRITE; map_mock_->AddMap(map); map.name = "/system/lib/libfake.so"; map_mock_->AddMap(map); elf_set_fake_build_id("abcdef1234567890abcdef1234567890"); dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100); std::string tombstone_contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); const char* expected_dump = \ "\nmemory map:\n" #if defined(__LP64__) " 12345678'9abcd000-12345678'9abdefff -w- 0 12000\n" " 12345678'9abcd000-12345678'9abdefff -w- 0 12000 /system/lib/libfake.so\n"; #else " 01234000-01234fff -w- 0 1000\n" " 01234000-01234fff -w- 0 1000 /system/lib/libfake.so\n"; #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }
TEST_F(DumpMapsTest, multiple_maps_check_signal_has_si_addr) { backtrace_map_t map; map.start = 0xa434000; map.end = 0xa435000; map.flags = PROT_WRITE; map_mock_->AddMap(map); for (int i = 1; i < 255; i++) { ASSERT_TRUE(ftruncate(log_.tfd, 0) == 0); ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); siginfo_t si; si.si_signo = i; si.si_addr = reinterpret_cast<void*>(0x1000); ptrace_set_fake_getsiginfo(si); dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100); std::string tombstone_contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); bool has_addr = false; switch (si.si_signo) { case SIGBUS: case SIGFPE: case SIGILL: case SIGSEGV: case SIGTRAP: has_addr = true; break; } const char* expected_addr_dump = \ "\nmemory map: (fault address prefixed with --->)\n" #if defined(__LP64__) "--->Fault address falls at 00000000'00001000 before any mapped regions\n" " 00000000'0a434000-00000000'0a434fff -w- 0 1000\n"; #else "--->Fault address falls at 00001000 before any mapped regions\n" " 0a434000-0a434fff -w- 0 1000\n"; #endif const char* expected_dump = \ "\nmemory map:\n" #if defined(__LP64__) " 00000000'0a434000-00000000'0a434fff -w- 0 1000\n"; #else " 0a434000-0a434fff -w- 0 1000\n"; #endif if (has_addr) { ASSERT_STREQ(expected_addr_dump, tombstone_contents.c_str()) << "Signal " << si.si_signo << " expected to include an address."; } else { ASSERT_STREQ(expected_dump, tombstone_contents.c_str()) << "Signal " << si.si_signo << " is not expected to include an address."; } // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); } }
TEST_F(DumpMapsTest, multiple_maps) { backtrace_map_t map; map.start = 0xa234000; map.end = 0xa235000; map_mock_->AddMap(map); map.start = 0xa334000; map.end = 0xa335000; map.offset = 0xf000; map.flags = PROT_READ; map_mock_->AddMap(map); map.start = 0xa434000; map.end = 0xa435000; map.offset = 0x1000; map.load_base = 0xd000; map.flags = PROT_WRITE; map_mock_->AddMap(map); map.start = 0xa534000; map.end = 0xa535000; map.offset = 0x3000; map.load_base = 0x2000; map.flags = PROT_EXEC; map_mock_->AddMap(map); map.start = 0xa634000; map.end = 0xa635000; map.offset = 0; map.load_base = 0; map.flags = PROT_READ | PROT_WRITE | PROT_EXEC; map.name = "/system/lib/fake.so"; map_mock_->AddMap(map); dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100); std::string tombstone_contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); const char* expected_dump = \ "\nmemory map:\n" #if defined(__LP64__) " 00000000'0a234000-00000000'0a234fff --- 0 1000\n" " 00000000'0a334000-00000000'0a334fff r-- f000 1000\n" " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n" " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n" " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"; #else " 0a234000-0a234fff --- 0 1000\n" " 0a334000-0a334fff r-- f000 1000\n" " 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n" " 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n" " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"; #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); }