diff options
author | Christopher Ferris <cferris@google.com> | 2016-02-02 20:40:36 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2016-02-02 20:40:36 +0000 |
commit | 4821db1b3ecc14828d4acf4abed26bb7d8b8cf6a (patch) | |
tree | f2a8c2bb80073a9d660599b4ad1ee53cc0c696d4 /libc/malloc_debug/tests/malloc_debug_unit_tests.cpp | |
parent | 5992e5fb6da2722fb4c3850048f71ef077735381 (diff) | |
parent | 7993b80f894db20af4d1d154221c42fea6171a3d (diff) |
Merge "Add better free tracking."
Diffstat (limited to 'libc/malloc_debug/tests/malloc_debug_unit_tests.cpp')
-rw-r--r-- | libc/malloc_debug/tests/malloc_debug_unit_tests.cpp | 85 |
1 files changed, 74 insertions, 11 deletions
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp index 08731c236..4b8aaeba1 100644 --- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp +++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp @@ -76,8 +76,7 @@ static size_t get_tag_offset(uint32_t flags = 0, size_t backtrace_frames = 0) { offset += BIONIC_ALIGN(sizeof(TrackHeader), sizeof(uintptr_t)); } if (flags & BACKTRACE_HEADER) { - offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames - 1, sizeof(uintptr_t)); - offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames - 1, sizeof(uintptr_t)); + offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames, sizeof(uintptr_t)); } return offset; } @@ -209,7 +208,7 @@ TEST_F(MallocDebugTest, fill_on_alloc_partial) { } TEST_F(MallocDebugTest, fill_on_free) { - Init("fill_on_free free_track"); + Init("fill_on_free free_track free_track_backtrace_num_frames=0"); uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100)); ASSERT_TRUE(pointer != nullptr); @@ -226,7 +225,7 @@ TEST_F(MallocDebugTest, fill_on_free) { } TEST_F(MallocDebugTest, fill_on_free_partial) { - Init("fill_on_free=30 free_track"); + Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0"); uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100)); ASSERT_TRUE(pointer != nullptr); @@ -246,7 +245,7 @@ TEST_F(MallocDebugTest, fill_on_free_partial) { } TEST_F(MallocDebugTest, free_track_partial) { - Init("fill_on_free=30 free_track"); + Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0"); uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100)); ASSERT_TRUE(pointer != nullptr); @@ -688,7 +687,7 @@ TEST_F(MallocDebugTest, leak_track_frees) { } TEST_F(MallocDebugTest, free_track) { - Init("free_track=5"); + Init("free_track=5 free_track_backtrace_num_frames=0"); void* pointers[10]; for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) { @@ -714,7 +713,7 @@ TEST_F(MallocDebugTest, free_track) { } TEST_F(MallocDebugTest, free_track_use_after_free) { - Init("free_track=5"); + Init("free_track=5 free_track_backtrace_num_frames=0"); uint8_t* pointers[5]; for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) { @@ -779,7 +778,7 @@ TEST_F(MallocDebugTest, free_track_use_after_free) { } TEST_F(MallocDebugTest, free_track_use_after_free_finalize) { - Init("free_track=100"); + Init("free_track=100 free_track_backtrace_num_frames=0"); uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100)); ASSERT_TRUE(pointer != nullptr); @@ -803,10 +802,8 @@ TEST_F(MallocDebugTest, free_track_use_after_free_finalize) { } TEST_F(MallocDebugTest, free_track_use_after_free_with_backtrace) { - Init("free_track=100 backtrace"); + Init("free_track=100"); - // Alloc backtrace. - backtrace_fake_add(std::vector<uintptr_t> {0xf0, 0xe, 0xd}); // Free backtrace. backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc}); @@ -835,6 +832,72 @@ TEST_F(MallocDebugTest, free_track_use_after_free_with_backtrace) { ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str()); } +TEST_F(MallocDebugTest, free_track_use_after_free_call_realloc) { + Init("free_track=100"); + + // Free backtrace. + backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc}); + // Backtrace at realloc. + backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42}); + + void* pointer = debug_malloc(200); + ASSERT_TRUE(pointer != nullptr); + memset(pointer, 0, 200); + debug_free(pointer); + + // Choose a size that should not trigger a realloc to verify tag is + // verified early. + ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr); + + ASSERT_STREQ("", getFakeLogBuf().c_str()); + std::string expected_log(DIVIDER); + expected_log += android::base::StringPrintf( + "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (realloc)\n", pointer); + expected_log += "6 malloc_debug Backtrace of original free:\n"; + expected_log += "6 malloc_debug #00 pc 0xfa\n"; + expected_log += "6 malloc_debug #01 pc 0xeb\n"; + expected_log += "6 malloc_debug #02 pc 0xdc\n"; + expected_log += "6 malloc_debug Backtrace at time of failure:\n"; + expected_log += "6 malloc_debug #00 pc 0x12\n"; + expected_log += "6 malloc_debug #01 pc 0x22\n"; + expected_log += "6 malloc_debug #02 pc 0x32\n"; + expected_log += "6 malloc_debug #03 pc 0x42\n"; + expected_log += DIVIDER; + ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str()); +} + +TEST_F(MallocDebugTest, free_track_use_after_free_call_free) { + Init("free_track=100"); + + // Free backtrace. + backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc}); + // Backtrace at second free. + backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42}); + + void* pointer = debug_malloc(200); + ASSERT_TRUE(pointer != nullptr); + memset(pointer, 0, 200); + debug_free(pointer); + + debug_free(pointer); + + ASSERT_STREQ("", getFakeLogBuf().c_str()); + std::string expected_log(DIVIDER); + expected_log += android::base::StringPrintf( + "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (free)\n", pointer); + expected_log += "6 malloc_debug Backtrace of original free:\n"; + expected_log += "6 malloc_debug #00 pc 0xfa\n"; + expected_log += "6 malloc_debug #01 pc 0xeb\n"; + expected_log += "6 malloc_debug #02 pc 0xdc\n"; + expected_log += "6 malloc_debug Backtrace at time of failure:\n"; + expected_log += "6 malloc_debug #00 pc 0x12\n"; + expected_log += "6 malloc_debug #01 pc 0x22\n"; + expected_log += "6 malloc_debug #02 pc 0x32\n"; + expected_log += "6 malloc_debug #03 pc 0x42\n"; + expected_log += DIVIDER; + ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str()); +} + TEST_F(MallocDebugTest, get_malloc_leak_info_invalid) { Init("fill"); |