1 /*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <malloc.h>
18 #include <signal.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/cdefs.h>
23 #include <sys/mman.h>
24 #include <sys/param.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27
28 #include <algorithm>
29 #include <memory>
30 #include <string>
31 #include <string_view>
32 #include <thread>
33 #include <vector>
34 #include <utility>
35
36 #include <tinyxml2.h>
37
38 #include <gtest/gtest.h>
39
40 #include <android-base/file.h>
41 #include <android-base/stringprintf.h>
42 #include <android-base/strings.h>
43 #include <android-base/test_utils.h>
44
45 #include <platform/bionic/macros.h>
46 #include <private/bionic_malloc_dispatch.h>
47
48 #include <memory_trace/MemoryTrace.h>
49 #include <unwindstack/Unwinder.h>
50
51 #include "Config.h"
52 #include "malloc_debug.h"
53
54 #include "log_fake.h"
55 #include "backtrace_fake.h"
56
57 __BEGIN_DECLS
58
59 bool debug_initialize(const MallocDispatch*, bool*, const char*);
60 void debug_finalize();
61
62 void* debug_malloc(size_t);
63 void debug_free(void*);
64 void* debug_calloc(size_t, size_t);
65 void* debug_realloc(void*, size_t);
66 int debug_posix_memalign(void**, size_t, size_t);
67 void* debug_memalign(size_t, size_t);
68 void* debug_aligned_alloc(size_t, size_t);
69 size_t debug_malloc_usable_size(void*);
70 void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
71 void debug_free_malloc_leak_info(uint8_t*);
72
73 struct mallinfo debug_mallinfo();
74 int debug_mallopt(int, int);
75 int debug_malloc_info(int, FILE*);
76
77 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
78 void* debug_pvalloc(size_t);
79 void* debug_valloc(size_t);
80 #endif
81
82 bool debug_write_malloc_leak_info(FILE*);
83 void debug_dump_heap(const char*);
84
85 void malloc_enable();
86 void malloc_disable();
87
88 __END_DECLS
89
90 // Change the slow threshold since some tests take more than 2 seconds.
GetInitialArgs(const char *** args,size_t * num_args)91 extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) {
92 static const char* initial_args[] = {"--slow_threshold_ms=5000"};
93 *args = initial_args;
94 *num_args = 1;
95 return true;
96 }
97
98 constexpr char DIVIDER[] =
99 "6 malloc_debug *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n";
100
get_tag_offset()101 static size_t get_tag_offset() {
102 return __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
103 }
104
105 static constexpr const char RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs";
106
107 static constexpr const char BACKTRACE_DUMP_PREFIX[] = "/data/local/tmp/backtrace_heap";
108
109 class MallocDebugTest : public ::testing::Test {
110 protected:
SetUp()111 void SetUp() override {
112 initialized = false;
113 resetLogs();
114 backtrace_fake_clear_all();
115 }
116
TearDown()117 void TearDown() override {
118 if (initialized) {
119 debug_finalize();
120 }
121 if (!record_filename.empty()) {
122 // Try to delete the record data file even it doesn't exist.
123 unlink(record_filename.c_str());
124 }
125 }
126
Init(const char * options)127 void Init(const char* options) {
128 zygote_child = false;
129 ASSERT_TRUE(debug_initialize(&dispatch, &zygote_child, options));
130 initialized = true;
131 }
132
InitRecordAllocs(const char * options)133 void InitRecordAllocs(const char* options) {
134 record_filename = android::base::StringPrintf("%s.%d.txt", RECORD_ALLOCS_FILE, getpid());
135 std::string init(options);
136 init += android::base::StringPrintf(" record_allocs_file=%s", record_filename.c_str());
137 Init(init.c_str());
138 }
139
140 void BacktraceDumpOnSignal(bool trigger_with_alloc);
141
GetInfoEntrySize(size_t max_frames)142 static size_t GetInfoEntrySize(size_t max_frames) {
143 return 2 * sizeof(size_t) + max_frames * sizeof(uintptr_t);
144 }
145
146 bool initialized;
147
148 bool zygote_child;
149
150 std::string record_filename;
151
152 static MallocDispatch dispatch;
153 };
154
155 MallocDispatch MallocDebugTest::dispatch = {
156 calloc,
157 free,
158 mallinfo,
159 malloc,
160 malloc_usable_size,
161 memalign,
162 posix_memalign,
163 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
164 nullptr,
165 #endif
166 realloc,
167 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
168 nullptr,
169 #endif
170 nullptr,
171 nullptr,
172 nullptr,
173 mallopt,
174 aligned_alloc,
175 malloc_info,
176 };
177
ShowDiffs(uint8_t * a,uint8_t * b,size_t size)178 std::string ShowDiffs(uint8_t* a, uint8_t* b, size_t size) {
179 std::string diff;
180 for (size_t i = 0; i < size; i++) {
181 if (a[i] != b[i]) {
182 diff += android::base::StringPrintf("Byte %zu: 0x%x 0x%x\n", i, a[i], b[i]);
183 }
184 }
185 return diff;
186 }
187
VerifyRecords(std::vector<std::string> & expected,std::string & actual)188 static void VerifyRecords(std::vector<std::string>& expected, std::string& actual) {
189 ASSERT_TRUE(expected.size() != 0);
190 size_t offset = 0;
191 for (std::string& str : expected) {
192 ASSERT_STREQ(str.c_str(), actual.substr(offset, str.size()).c_str());
193 if (str.find("thread_done") != std::string::npos) {
194 offset = actual.find_first_of("\n", offset) + 1;
195 continue;
196 }
197 offset += str.size() + 1;
198 uint64_t st = strtoull(&actual[offset], nullptr, 10);
199 offset = actual.find_first_of(" ", offset) + 1;
200 uint64_t et = strtoull(&actual[offset], nullptr, 10);
201 ASSERT_GT(et, st);
202 offset = actual.find_first_of("\n", offset) + 1;
203 }
204 }
205
VerifyRecordEntries(const std::vector<memory_trace::Entry> & expected,std::string & actual)206 static void VerifyRecordEntries(const std::vector<memory_trace::Entry>& expected,
207 std::string& actual) {
208 ASSERT_TRUE(expected.size() != 0);
209 // Convert the text to entries.
210 std::vector<memory_trace::Entry> actual_entries;
211 for (const auto& line : android::base::Split(actual, "\n")) {
212 if (line.empty()) {
213 continue;
214 }
215 memory_trace::Entry entry;
216 std::string error;
217 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
218 actual_entries.emplace_back(entry);
219 }
220 auto expected_iter = expected.begin();
221 for (const auto& actual_entry : actual_entries) {
222 if (actual_entry.type == memory_trace::THREAD_DONE) {
223 // Skip thread done entries.
224 continue;
225 }
226 ASSERT_NE(expected_iter, expected.end())
227 << "Found extra entry " << memory_trace::CreateStringFromEntry(*expected_iter);
228 SCOPED_TRACE(testing::Message()
229 << "\nExpected entry:\n " << memory_trace::CreateStringFromEntry(*expected_iter)
230 << "\nActual entry:\n " << memory_trace::CreateStringFromEntry(actual_entry));
231 EXPECT_EQ(actual_entry.type, expected_iter->type);
232 EXPECT_EQ(actual_entry.ptr, expected_iter->ptr);
233 EXPECT_EQ(actual_entry.size, expected_iter->size);
234 EXPECT_EQ(actual_entry.u.old_ptr, expected_iter->u.old_ptr);
235 EXPECT_EQ(actual_entry.present_bytes, expected_iter->present_bytes);
236 // Verify the timestamps are non-zero.
237 EXPECT_NE(actual_entry.start_ns, 0U);
238 EXPECT_NE(actual_entry.end_ns, 0U);
239 ++expected_iter;
240 }
241 EXPECT_TRUE(expected_iter == expected.end()) << "Not all expected entries found.";
242 }
243
VerifyAllocCalls(bool all_options)244 void VerifyAllocCalls(bool all_options) {
245 size_t alloc_size = 1024;
246
247 // Verify debug_malloc.
248 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(alloc_size));
249 ASSERT_TRUE(pointer != nullptr);
250 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
251 ASSERT_EQ(0xeb, pointer[i]);
252 }
253 debug_free(pointer);
254
255 // Verify debug_calloc.
256 pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, alloc_size));
257 ASSERT_TRUE(pointer != nullptr);
258 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
259 ASSERT_EQ(0, pointer[i]) << "Failed at byte " << i;
260 }
261 debug_free(pointer);
262
263 pointer = reinterpret_cast<uint8_t*>(debug_memalign(128, alloc_size));
264 ASSERT_TRUE(pointer != nullptr);
265 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
266 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
267 }
268 debug_free(pointer);
269
270 pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, alloc_size));
271 ASSERT_TRUE(pointer != nullptr);
272 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
273 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
274 }
275 memset(pointer, 0xff, alloc_size);
276 // Increase the size, verify the extra length is initialized to 0xeb,
277 // but the rest is 0xff.
278 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size * 2));
279 ASSERT_TRUE(pointer != nullptr);
280 for (size_t i = 0; i < alloc_size; i++) {
281 ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
282 }
283 for (size_t i = alloc_size; i < debug_malloc_usable_size(pointer); i++) {
284 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
285 }
286 memset(pointer, 0xff, debug_malloc_usable_size(pointer));
287 // Shrink the size and verify nothing changes.
288 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size));
289 ASSERT_TRUE(pointer != nullptr);
290 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
291 ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
292 }
293 // This should free the pointer.
294 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
295 ASSERT_TRUE(pointer == nullptr);
296
297 ASSERT_STREQ("", getFakeLogBuf().c_str());
298 std::string expected_log;
299 if (all_options) {
300 expected_log += android::base::StringPrintf(
301 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
302 SIGRTMAX - 19, getpid());
303 expected_log += android::base::StringPrintf(
304 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
305 SIGRTMAX - 17, getpid());
306 expected_log += android::base::StringPrintf(
307 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
308 SIGRTMAX - 18, getpid());
309 expected_log += android::base::StringPrintf(
310 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to log allocator stats.\n",
311 SIGRTMAX - 15, getpid());
312 expected_log += android::base::StringPrintf(
313 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to check for unreachable memory.\n",
314 SIGRTMAX - 16, getpid());
315 }
316 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
317 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
318 }
319
TEST_F(MallocDebugTest,fill_generic)320 TEST_F(MallocDebugTest, fill_generic) {
321 Init("verbose fill");
322 VerifyAllocCalls(false);
323 }
324
TEST_F(MallocDebugTest,fill_on_alloc_generic)325 TEST_F(MallocDebugTest, fill_on_alloc_generic) {
326 Init("verbose fill_on_alloc");
327 VerifyAllocCalls(false);
328 }
329
TEST_F(MallocDebugTest,fill_on_alloc_partial)330 TEST_F(MallocDebugTest, fill_on_alloc_partial) {
331 Init("fill_on_alloc=25");
332
333 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
334 ASSERT_TRUE(pointer != nullptr);
335 for (size_t i = 0; i < 25; i++) {
336 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
337 }
338 debug_free(pointer);
339
340 ASSERT_STREQ("", getFakeLogBuf().c_str());
341 ASSERT_STREQ("", getFakeLogPrint().c_str());
342 }
343
TEST_F(MallocDebugTest,verbose_only)344 TEST_F(MallocDebugTest, verbose_only) {
345 Init("verbose");
346
347 ASSERT_STREQ("", getFakeLogBuf().c_str());
348 ASSERT_STREQ("4 malloc_debug malloc_testing: malloc debug enabled\n", getFakeLogPrint().c_str());
349 }
350
TEST_F(MallocDebugTest,verbose_backtrace_enable_on_signal)351 TEST_F(MallocDebugTest, verbose_backtrace_enable_on_signal) {
352 Init("verbose backtrace_enable_on_signal");
353
354 std::string expected_log = android::base::StringPrintf(
355 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
356 SIGRTMAX - 19, getpid());
357 expected_log += android::base::StringPrintf(
358 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
359 SIGRTMAX - 17, getpid());
360 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
361 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
362 }
363
TEST_F(MallocDebugTest,verbose_backtrace)364 TEST_F(MallocDebugTest, verbose_backtrace) {
365 Init("verbose backtrace");
366
367 std::string expected_log = android::base::StringPrintf(
368 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
369 SIGRTMAX - 17, getpid());
370 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
371 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
372 }
373
TEST_F(MallocDebugTest,verbose_record_allocs)374 TEST_F(MallocDebugTest, verbose_record_allocs) {
375 Init("verbose record_allocs");
376
377 std::string expected_log = android::base::StringPrintf(
378 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
379 SIGRTMAX - 18, getpid());
380 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
381 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
382 }
383
TEST_F(MallocDebugTest,verbose_check_unreachable_on_signal)384 TEST_F(MallocDebugTest, verbose_check_unreachable_on_signal) {
385 Init("verbose check_unreachable_on_signal");
386
387 std::string expected_log = android::base::StringPrintf(
388 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to check for unreachable memory.\n",
389 SIGRTMAX - 16, getpid());
390 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
391 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
392 }
393
TEST_F(MallocDebugTest,verbose_log_allocator_stats_on_signal)394 TEST_F(MallocDebugTest, verbose_log_allocator_stats_on_signal) {
395 Init("verbose log_allocator_stats_on_signal");
396
397 std::string expected_log = android::base::StringPrintf(
398 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to log allocator stats.\n", SIGRTMAX - 15,
399 getpid());
400 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
401 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
402 }
403
TEST_F(MallocDebugTest,fill_on_free)404 TEST_F(MallocDebugTest, fill_on_free) {
405 Init("fill_on_free free_track free_track_backtrace_num_frames=0");
406
407 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
408 ASSERT_TRUE(pointer != nullptr);
409 size_t usable_size = debug_malloc_usable_size(pointer);
410 memset(pointer, 0, usable_size);
411 debug_free(pointer);
412
413 for (size_t i = 0; i < usable_size; i++) {
414 ASSERT_EQ(0xef, pointer[i]) << "Failed at byte " << i;
415 }
416
417 ASSERT_STREQ("", getFakeLogBuf().c_str());
418 ASSERT_STREQ("", getFakeLogPrint().c_str());
419 }
420
TEST_F(MallocDebugTest,fill_on_free_partial)421 TEST_F(MallocDebugTest, fill_on_free_partial) {
422 Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
423
424 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
425 ASSERT_TRUE(pointer != nullptr);
426 size_t usable_size = debug_malloc_usable_size(pointer);
427 memset(pointer, 0, usable_size);
428 debug_free(pointer);
429
430 for (size_t i = 0; i < 30; i++) {
431 ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
432 }
433 for (size_t i = 30; i < usable_size; i++) {
434 ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
435 }
436
437 ASSERT_STREQ("", getFakeLogBuf().c_str());
438 ASSERT_STREQ("", getFakeLogPrint().c_str());
439 }
440
TEST_F(MallocDebugTest,free_track_partial)441 TEST_F(MallocDebugTest, free_track_partial) {
442 Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
443
444 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
445 ASSERT_TRUE(pointer != nullptr);
446 size_t usable_size = debug_malloc_usable_size(pointer);
447 memset(pointer, 0, usable_size);
448 debug_free(pointer);
449
450 for (size_t i = 0; i < 30; i++) {
451 ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
452 }
453 for (size_t i = 30; i < usable_size; i++) {
454 ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
455 }
456
457 debug_finalize();
458 initialized = false;
459
460 ASSERT_STREQ("", getFakeLogBuf().c_str());
461 ASSERT_STREQ("", getFakeLogPrint().c_str());
462 }
463
TEST_F(MallocDebugTest,all_options)464 TEST_F(MallocDebugTest, all_options) {
465 Init(
466 "guard backtrace backtrace_enable_on_signal fill expand_alloc free_track leak_track "
467 "record_allocs verify_pointers abort_on_error verbose check_unreachable_on_signal "
468 "log_allocator_stats_on_signal log_allocator_stats_on_exit");
469 VerifyAllocCalls(true);
470 }
471
TEST_F(MallocDebugTest,expand_alloc)472 TEST_F(MallocDebugTest, expand_alloc) {
473 Init("expand_alloc=1024");
474
475 void* pointer = debug_malloc(10);
476 ASSERT_TRUE(pointer != nullptr);
477 ASSERT_LE(1034U, debug_malloc_usable_size(pointer));
478 debug_free(pointer);
479
480 pointer = debug_calloc(1, 20);
481 ASSERT_TRUE(pointer != nullptr);
482 ASSERT_LE(1044U, debug_malloc_usable_size(pointer));
483 debug_free(pointer);
484
485 pointer = debug_memalign(128, 15);
486 ASSERT_TRUE(pointer != nullptr);
487 ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
488 debug_free(pointer);
489
490 pointer = debug_aligned_alloc(16, 16);
491 ASSERT_TRUE(pointer != nullptr);
492 ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
493 debug_free(pointer);
494
495 pointer = debug_realloc(nullptr, 30);
496 ASSERT_TRUE(pointer != nullptr);
497 ASSERT_LE(1054U, debug_malloc_usable_size(pointer));
498 pointer = debug_realloc(pointer, 100);
499 ASSERT_LE(1124U, debug_malloc_usable_size(pointer));
500 debug_free(pointer);
501
502 ASSERT_STREQ("", getFakeLogBuf().c_str());
503 ASSERT_STREQ("", getFakeLogPrint().c_str());
504 }
505
TEST_F(MallocDebugTest,front_guard)506 TEST_F(MallocDebugTest, front_guard) {
507 Init("front_guard=32");
508
509 // Create a buffer for doing comparisons.
510 std::vector<uint8_t> buffer(32);
511 memset(buffer.data(), 0xaa, buffer.size());
512
513 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
514 ASSERT_TRUE(pointer != nullptr);
515 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
516 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
517 memset(pointer, 0xff, 100);
518 debug_free(pointer);
519
520 // Loop through a bunch alignments.
521 for (size_t alignment = 1; alignment <= 256; alignment++) {
522 pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
523 ASSERT_TRUE(pointer != nullptr);
524 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
525 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
526 size_t alignment_mask = alignment - 1;
527 if (!powerof2(alignment)) {
528 alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
529 }
530 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask);
531 memset(pointer, 0xff, 100);
532 debug_free(pointer);
533 }
534
535 pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
536 ASSERT_TRUE(pointer != nullptr);
537 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
538 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
539 for (size_t i = 0; i < 100; i++) {
540 ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
541 }
542 debug_free(pointer);
543
544 pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
545 ASSERT_TRUE(pointer != nullptr);
546 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
547 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
548 memset(pointer, 0xff, 100);
549 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
550 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
551 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
552 memset(pointer, 0xff, 200);
553 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
554 ASSERT_TRUE(pointer == nullptr);
555
556 ASSERT_STREQ("", getFakeLogBuf().c_str());
557 ASSERT_STREQ("", getFakeLogPrint().c_str());
558 }
559
TEST_F(MallocDebugTest,realloc_memalign_memory)560 TEST_F(MallocDebugTest, realloc_memalign_memory) {
561 Init("rear_guard");
562
563 void* pointer = debug_memalign(1024, 100);
564 ASSERT_TRUE(pointer != nullptr);
565 memset(pointer, 0, 100);
566
567 pointer = debug_realloc(pointer, 1024);
568 ASSERT_TRUE(pointer != nullptr);
569 ASSERT_EQ(1024U, debug_malloc_usable_size(pointer));
570 memset(pointer, 0, 1024);
571 debug_free(pointer);
572
573 ASSERT_STREQ("", getFakeLogBuf().c_str());
574 ASSERT_STREQ("", getFakeLogPrint().c_str());
575 }
576
TEST_F(MallocDebugTest,front_guard_corrupted)577 TEST_F(MallocDebugTest, front_guard_corrupted) {
578 Init("front_guard=32");
579
580 backtrace_fake_add(std::vector<uintptr_t> {0x1, 0x2, 0x3});
581
582 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
583 ASSERT_TRUE(pointer != nullptr);
584 pointer[-32] = 0x00;
585 pointer[-15] = 0x02;
586 debug_free(pointer);
587
588 std::string expected_log(DIVIDER);
589 expected_log += android::base::StringPrintf(
590 "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED FRONT GUARD\n", pointer);
591 expected_log += "6 malloc_debug allocation[-32] = 0x00 (expected 0xaa)\n";
592 expected_log += "6 malloc_debug allocation[-15] = 0x02 (expected 0xaa)\n";
593 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
594 expected_log += "6 malloc_debug #00 pc 0x1\n";
595 expected_log += "6 malloc_debug #01 pc 0x2\n";
596 expected_log += "6 malloc_debug #02 pc 0x3\n";
597 expected_log += DIVIDER;
598 ASSERT_STREQ("", getFakeLogBuf().c_str());
599 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
600 }
601
TEST_F(MallocDebugTest,rear_guard)602 TEST_F(MallocDebugTest, rear_guard) {
603 Init("rear_guard=32");
604
605 // Create a buffer for doing comparisons.
606 std::vector<uint8_t> buffer(32);
607 memset(buffer.data(), 0xbb, buffer.size());
608
609 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
610 ASSERT_TRUE(pointer != nullptr);
611 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
612 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0)
613 << ShowDiffs(buffer.data(), &pointer[100], buffer.size());
614 memset(pointer, 0xff, 100);
615 debug_free(pointer);
616
617 // Loop through a bunch alignments.
618 for (size_t alignment = 1; alignment <= 256; alignment++) {
619 pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
620 ASSERT_TRUE(pointer != nullptr);
621 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
622 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0)
623 << ShowDiffs(buffer.data(), &pointer[100], buffer.size());
624 size_t alignment_mask = alignment - 1;
625 if (!powerof2(alignment)) {
626 alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
627 }
628 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask)
629 << "Failed at alignment " << alignment << " mask " << alignment_mask;
630 memset(pointer, 0xff, 100);
631 debug_free(pointer);
632 }
633
634 pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
635 ASSERT_TRUE(pointer != nullptr);
636 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
637 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0)
638 << ShowDiffs(buffer.data(), &pointer[100], buffer.size());
639 for (size_t i = 0; i < 100; i++) {
640 ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
641 }
642 debug_free(pointer);
643
644 pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
645 ASSERT_TRUE(pointer != nullptr);
646 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0)
647 << ShowDiffs(buffer.data(), &pointer[100], buffer.size());
648 memset(pointer, 0xff, 100);
649 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
650 ASSERT_TRUE(memcmp(buffer.data(), &pointer[200], buffer.size()) == 0)
651 << ShowDiffs(buffer.data(), &pointer[200], buffer.size());
652 for (size_t i = 0; i < 100; i++) {
653 ASSERT_EQ(0xff, pointer[i]) << "debug_realloc not copied byte at " << i;
654 }
655 memset(pointer, 0xff, 200);
656 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
657 ASSERT_TRUE(pointer == nullptr);
658
659 ASSERT_STREQ("", getFakeLogBuf().c_str());
660 ASSERT_STREQ("", getFakeLogPrint().c_str());
661 }
662
TEST_F(MallocDebugTest,rear_guard_corrupted)663 TEST_F(MallocDebugTest, rear_guard_corrupted) {
664 Init("rear_guard=32");
665
666 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
667
668 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
669 ASSERT_TRUE(pointer != nullptr);
670 pointer[130] = 0xbf;
671 pointer[131] = 0x00;
672 debug_free(pointer);
673
674 std::string expected_log(DIVIDER);
675 expected_log += android::base::StringPrintf(
676 "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
677 expected_log += "6 malloc_debug allocation[130] = 0xbf (expected 0xbb)\n";
678 expected_log += "6 malloc_debug allocation[131] = 0x00 (expected 0xbb)\n";
679 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
680 expected_log += "6 malloc_debug #00 pc 0x100\n";
681 expected_log += "6 malloc_debug #01 pc 0x200\n";
682 expected_log += "6 malloc_debug #02 pc 0x300\n";
683 expected_log += DIVIDER;
684
685 ASSERT_STREQ("", getFakeLogBuf().c_str());
686 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
687 }
688
TEST_F(MallocDebugTest,rear_guard_corrupted_after_realloc_shrink)689 TEST_F(MallocDebugTest, rear_guard_corrupted_after_realloc_shrink) {
690 Init("rear_guard=32");
691
692 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
693
694 void* pointer = debug_malloc(200);
695 ASSERT_TRUE(pointer != nullptr);
696 memset(pointer, 0, 200);
697
698 uint8_t* pointer_shrink = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 100));
699 pointer_shrink[130] = 0xbf;
700 pointer_shrink[131] = 0x00;
701 debug_free(pointer);
702
703 // When shrinking sizes, the same pointer should be returned.
704 ASSERT_EQ(pointer, pointer_shrink);
705
706 std::string expected_log(DIVIDER);
707 expected_log += android::base::StringPrintf(
708 "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
709 expected_log += "6 malloc_debug allocation[130] = 0xbf (expected 0xbb)\n";
710 expected_log += "6 malloc_debug allocation[131] = 0x00 (expected 0xbb)\n";
711 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
712 expected_log += "6 malloc_debug #00 pc 0x100\n";
713 expected_log += "6 malloc_debug #01 pc 0x200\n";
714 expected_log += "6 malloc_debug #02 pc 0x300\n";
715 expected_log += DIVIDER;
716
717 ASSERT_STREQ("", getFakeLogBuf().c_str());
718 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
719 }
720
TEST_F(MallocDebugTest,tag_corrupted)721 TEST_F(MallocDebugTest, tag_corrupted) {
722 Init("rear_guard=32");
723
724 backtrace_fake_add(std::vector<uintptr_t> {0xa, 0xb, 0xc});
725
726 backtrace_fake_add(std::vector<uintptr_t> {0xaa, 0xbb, 0xcc});
727
728 backtrace_fake_add(std::vector<uintptr_t> {0xaaa, 0xbbb, 0xccc});
729
730 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
731 ASSERT_TRUE(pointer != nullptr);
732 uint8_t saved = pointer[-get_tag_offset()];
733 pointer[-get_tag_offset()] = 0x00;
734 ASSERT_EQ(0U, debug_malloc_usable_size(pointer));
735 ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
736 debug_free(pointer);
737
738 // Fix the pointer and really free it.
739 pointer[-get_tag_offset()] = saved;
740 debug_free(pointer);
741
742 std::string expected_log(DIVIDER);
743 expected_log += android::base::StringPrintf(
744 "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (malloc_usable_size)\n",
745 pointer);
746 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
747 expected_log += "6 malloc_debug #00 pc 0xa\n";
748 expected_log += "6 malloc_debug #01 pc 0xb\n";
749 expected_log += "6 malloc_debug #02 pc 0xc\n";
750 expected_log += DIVIDER;
751
752 expected_log += DIVIDER;
753 expected_log += android::base::StringPrintf(
754 "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (realloc)\n",
755 pointer);
756 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
757 expected_log += "6 malloc_debug #00 pc 0xaa\n";
758 expected_log += "6 malloc_debug #01 pc 0xbb\n";
759 expected_log += "6 malloc_debug #02 pc 0xcc\n";
760 expected_log += DIVIDER;
761
762 expected_log += DIVIDER;
763 expected_log += android::base::StringPrintf(
764 "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (free)\n",
765 pointer);
766 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
767 expected_log += "6 malloc_debug #00 pc 0xaaa\n";
768 expected_log += "6 malloc_debug #01 pc 0xbbb\n";
769 expected_log += "6 malloc_debug #02 pc 0xccc\n";
770 expected_log += DIVIDER;
771
772 ASSERT_STREQ("", getFakeLogBuf().c_str());
773 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
774 }
775
TEST_F(MallocDebugTest,leak_track_no_frees)776 TEST_F(MallocDebugTest, leak_track_no_frees) {
777 Init("leak_track");
778
779 void* pointer1 = debug_malloc(200);
780 ASSERT_TRUE(pointer1 != nullptr);
781 memset(pointer1, 0, 200);
782
783 void* pointer2 = debug_malloc(128);
784 ASSERT_TRUE(pointer2 != nullptr);
785 memset(pointer2, 0, 128);
786
787 void* pointer3 = debug_malloc(1024);
788 ASSERT_TRUE(pointer3 != nullptr);
789 memset(pointer3, 0, 1024);
790
791 debug_finalize();
792 initialized = false;
793
794 ASSERT_STREQ("", getFakeLogBuf().c_str());
795 std::string expected_log = android::base::StringPrintf(
796 "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
797 pointer3);
798 expected_log += android::base::StringPrintf(
799 "6 malloc_debug +++ malloc_testing leaked block of size 200 at %p (leak 2 of 3)\n",
800 pointer1);
801 expected_log += android::base::StringPrintf(
802 "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 3 of 3)\n",
803 pointer2);
804 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
805 }
806
TEST_F(MallocDebugTest,leak_track_no_frees_with_backtrace)807 TEST_F(MallocDebugTest, leak_track_no_frees_with_backtrace) {
808 Init("leak_track backtrace");
809
810 backtrace_fake_add(std::vector<uintptr_t> {0x1000, 0x2000, 0x3000});
811
812 void* pointer1 = debug_malloc(100);
813 ASSERT_TRUE(pointer1 != nullptr);
814 memset(pointer1, 0, 100);
815
816 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000, 0xc000, 0xd000});
817
818 void* pointer2 = debug_malloc(128);
819 ASSERT_TRUE(pointer2 != nullptr);
820 memset(pointer2, 0, 128);
821
822 backtrace_fake_add(std::vector<uintptr_t> {0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
823
824 void* pointer3 = debug_malloc(1024);
825 ASSERT_TRUE(pointer3 != nullptr);
826 memset(pointer3, 0, 1024);
827
828 debug_finalize();
829 initialized = false;
830
831 ASSERT_STREQ("", getFakeLogBuf().c_str());
832 std::string expected_log = android::base::StringPrintf(
833 "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
834 pointer3);
835 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
836 expected_log += "6 malloc_debug #00 pc 0xfe000\n";
837 expected_log += "6 malloc_debug #01 pc 0xde000\n";
838 expected_log += "6 malloc_debug #02 pc 0xce000\n";
839 expected_log += "6 malloc_debug #03 pc 0xbe000\n";
840 expected_log += "6 malloc_debug #04 pc 0xae000\n";
841
842 expected_log += android::base::StringPrintf(
843 "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 2 of 3)\n",
844 pointer2);
845 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
846 expected_log += "6 malloc_debug #00 pc 0xa000\n";
847 expected_log += "6 malloc_debug #01 pc 0xb000\n";
848 expected_log += "6 malloc_debug #02 pc 0xc000\n";
849 expected_log += "6 malloc_debug #03 pc 0xd000\n";
850
851 expected_log += android::base::StringPrintf(
852 "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 3 of 3)\n",
853 pointer1);
854 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
855 expected_log += "6 malloc_debug #00 pc 0x1000\n";
856 expected_log += "6 malloc_debug #01 pc 0x2000\n";
857 expected_log += "6 malloc_debug #02 pc 0x3000\n";
858 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
859 }
860
TEST_F(MallocDebugTest,leak_track_frees)861 TEST_F(MallocDebugTest, leak_track_frees) {
862 Init("leak_track");
863
864 void* pointer1 = debug_malloc(390);
865 ASSERT_TRUE(pointer1 != nullptr);
866 memset(pointer1, 0, 390);
867 debug_free(pointer1);
868
869 pointer1 = debug_malloc(100);
870 ASSERT_TRUE(pointer1 != nullptr);
871 memset(pointer1, 0, 100);
872
873 void* pointer2 = debug_malloc(250);
874 ASSERT_TRUE(pointer2 != nullptr);
875 memset(pointer2, 0, 250);
876 debug_free(pointer2);
877
878 pointer2 = debug_malloc(450);
879 ASSERT_TRUE(pointer2 != nullptr);
880 memset(pointer2, 0, 450);
881
882 void* pointer3 = debug_malloc(999);
883 ASSERT_TRUE(pointer3 != nullptr);
884 memset(pointer3, 0, 999);
885 debug_free(pointer2);
886
887 debug_finalize();
888 initialized = false;
889
890 ASSERT_STREQ("", getFakeLogBuf().c_str());
891 std::string expected_log = android::base::StringPrintf(
892 "6 malloc_debug +++ malloc_testing leaked block of size 999 at %p (leak 1 of 2)\n",
893 pointer3);
894 expected_log += android::base::StringPrintf(
895 "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 2 of 2)\n",
896 pointer1);
897 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
898 }
899
TEST_F(MallocDebugTest,free_track)900 TEST_F(MallocDebugTest, free_track) {
901 Init("free_track=5 free_track_backtrace_num_frames=0");
902
903 void* pointers[10];
904 for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
905 pointers[i] = debug_malloc(100 + i);
906 ASSERT_TRUE(pointers[i] != nullptr);
907 memset(pointers[i], 0, 100 + i);
908 debug_free(pointers[i]);
909 }
910
911 // Large allocations (> 4096) to verify large allocation checks.
912 void* pointer = debug_malloc(8192);
913 ASSERT_TRUE(pointer != nullptr);
914 memset(pointer, 0, 8192);
915 debug_free(pointer);
916
917 pointer = debug_malloc(9000);
918 ASSERT_TRUE(pointer != nullptr);
919 memset(pointer, 0, 9000);
920 debug_free(pointer);
921
922 ASSERT_STREQ("", getFakeLogBuf().c_str());
923 ASSERT_STREQ("", getFakeLogPrint().c_str());
924 }
925
TEST_F(MallocDebugTest,free_track_use_after_free)926 TEST_F(MallocDebugTest, free_track_use_after_free) {
927 Init("free_track=5 free_track_backtrace_num_frames=0");
928
929 uint8_t* pointers[5];
930 for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
931 pointers[i] = reinterpret_cast<uint8_t*>(debug_malloc(100 + i));
932 ASSERT_TRUE(pointers[i] != nullptr);
933 memset(pointers[i], 0, 100 + i);
934 debug_free(pointers[i]);
935 }
936
937 // Stomp on the data.
938 pointers[0][20] = 0xaf;
939 pointers[0][99] = 0x12;
940
941 pointers[3][3] = 0x34;
942
943 // Large allocations (> 4096) to verify large allocation checks.
944 uint8_t* pointer1_large = reinterpret_cast<uint8_t*>(debug_malloc(8192));
945 ASSERT_TRUE(pointer1_large != nullptr);
946 memset(pointer1_large, 0, 8192);
947 debug_free(pointer1_large);
948
949 pointer1_large[4095] = 0x90;
950 pointer1_large[4100] = 0x56;
951 pointer1_large[8191] = 0x89;
952
953 uint8_t* pointer2_large = reinterpret_cast<uint8_t*>(debug_malloc(9000));
954 ASSERT_TRUE(pointer2_large != nullptr);
955 memset(pointer2_large, 0, 9000);
956 debug_free(pointer2_large);
957
958 pointer2_large[8200] = 0x78;
959
960 // Do a bunch of alloc and free to verify the above frees are checked.
961 for (size_t i = 0; i < 10; i++) {
962 void* flush_pointer = debug_malloc(100+i);
963 ASSERT_TRUE(flush_pointer != nullptr);
964 memset(flush_pointer, 0, 100 + i);
965 debug_free(flush_pointer);
966 }
967
968 ASSERT_STREQ("", getFakeLogBuf().c_str());
969 std::string expected_log(DIVIDER);
970 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[0]);
971 expected_log += "6 malloc_debug allocation[20] = 0xaf (expected 0xef)\n";
972 expected_log += "6 malloc_debug allocation[99] = 0x12 (expected 0xef)\n";
973 expected_log += DIVIDER;
974 expected_log += DIVIDER;
975 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[3]);
976 expected_log += "6 malloc_debug allocation[3] = 0x34 (expected 0xef)\n";
977 expected_log += DIVIDER;
978 expected_log += DIVIDER;
979 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer1_large);
980 expected_log += "6 malloc_debug allocation[4095] = 0x90 (expected 0xef)\n";
981 expected_log += "6 malloc_debug allocation[4100] = 0x56 (expected 0xef)\n";
982 expected_log += "6 malloc_debug allocation[8191] = 0x89 (expected 0xef)\n";
983 expected_log += DIVIDER;
984 expected_log += DIVIDER;
985 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer2_large);
986 expected_log += "6 malloc_debug allocation[8200] = 0x78 (expected 0xef)\n";
987 expected_log += DIVIDER;
988 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
989 }
990
TEST_F(MallocDebugTest,free_track_use_after_free_finalize)991 TEST_F(MallocDebugTest, free_track_use_after_free_finalize) {
992 Init("free_track=100 free_track_backtrace_num_frames=0");
993
994 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
995 ASSERT_TRUE(pointer != nullptr);
996 memset(pointer, 0, 100);
997 debug_free(pointer);
998
999 pointer[56] = 0x91;
1000
1001 ASSERT_STREQ("", getFakeLogBuf().c_str());
1002 ASSERT_STREQ("", getFakeLogPrint().c_str());
1003
1004 debug_finalize();
1005 initialized = false;
1006
1007 ASSERT_STREQ("", getFakeLogBuf().c_str());
1008 std::string expected_log(DIVIDER);
1009 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
1010 expected_log += "6 malloc_debug allocation[56] = 0x91 (expected 0xef)\n";
1011 expected_log += DIVIDER;
1012 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1013 }
1014
TEST_F(MallocDebugTest,free_track_use_after_free_with_backtrace)1015 TEST_F(MallocDebugTest, free_track_use_after_free_with_backtrace) {
1016 Init("free_track=100 rear_guard");
1017
1018 // Free backtrace.
1019 backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
1020
1021 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(200));
1022 ASSERT_TRUE(pointer != nullptr);
1023 memset(pointer, 0, 200);
1024 debug_free(pointer);
1025
1026 pointer[101] = 0xab;
1027
1028 ASSERT_STREQ("", getFakeLogBuf().c_str());
1029 ASSERT_STREQ("", getFakeLogPrint().c_str());
1030
1031 debug_finalize();
1032 initialized = false;
1033
1034 ASSERT_STREQ("", getFakeLogBuf().c_str());
1035 std::string expected_log(DIVIDER);
1036 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
1037 expected_log += "6 malloc_debug allocation[101] = 0xab (expected 0xef)\n";
1038 expected_log += "6 malloc_debug Backtrace at time of free:\n";
1039 expected_log += "6 malloc_debug #00 pc 0xfa\n";
1040 expected_log += "6 malloc_debug #01 pc 0xeb\n";
1041 expected_log += "6 malloc_debug #02 pc 0xdc\n";
1042 expected_log += DIVIDER;
1043 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1044 }
1045
TEST_F(MallocDebugTest,free_track_use_after_free_call_realloc)1046 TEST_F(MallocDebugTest, free_track_use_after_free_call_realloc) {
1047 Init("free_track=100 rear_guard");
1048
1049 // Free backtrace.
1050 backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
1051 // Backtrace at realloc.
1052 backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
1053
1054 void* pointer = debug_malloc(200);
1055 ASSERT_TRUE(pointer != nullptr);
1056 memset(pointer, 0, 200);
1057 debug_free(pointer);
1058
1059 // Choose a size that should not trigger a realloc to verify tag is
1060 // verified early.
1061 ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
1062
1063 ASSERT_STREQ("", getFakeLogBuf().c_str());
1064 std::string expected_log(DIVIDER);
1065 expected_log += android::base::StringPrintf(
1066 "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (realloc)\n", pointer);
1067 expected_log += "6 malloc_debug Backtrace of original free:\n";
1068 expected_log += "6 malloc_debug #00 pc 0xfa\n";
1069 expected_log += "6 malloc_debug #01 pc 0xeb\n";
1070 expected_log += "6 malloc_debug #02 pc 0xdc\n";
1071 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
1072 expected_log += "6 malloc_debug #00 pc 0x12\n";
1073 expected_log += "6 malloc_debug #01 pc 0x22\n";
1074 expected_log += "6 malloc_debug #02 pc 0x32\n";
1075 expected_log += "6 malloc_debug #03 pc 0x42\n";
1076 expected_log += DIVIDER;
1077 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1078 }
1079
TEST_F(MallocDebugTest,free_track_use_after_free_call_free)1080 TEST_F(MallocDebugTest, free_track_use_after_free_call_free) {
1081 Init("free_track=100 rear_guard");
1082
1083 // Free backtrace.
1084 backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
1085 // Backtrace at second free.
1086 backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
1087
1088 void* pointer = debug_malloc(200);
1089 ASSERT_TRUE(pointer != nullptr);
1090 memset(pointer, 0, 200);
1091 debug_free(pointer);
1092
1093 debug_free(pointer);
1094
1095 ASSERT_STREQ("", getFakeLogBuf().c_str());
1096 std::string expected_log(DIVIDER);
1097 expected_log += android::base::StringPrintf(
1098 "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (free)\n", pointer);
1099 expected_log += "6 malloc_debug Backtrace of original free:\n";
1100 expected_log += "6 malloc_debug #00 pc 0xfa\n";
1101 expected_log += "6 malloc_debug #01 pc 0xeb\n";
1102 expected_log += "6 malloc_debug #02 pc 0xdc\n";
1103 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
1104 expected_log += "6 malloc_debug #00 pc 0x12\n";
1105 expected_log += "6 malloc_debug #01 pc 0x22\n";
1106 expected_log += "6 malloc_debug #02 pc 0x32\n";
1107 expected_log += "6 malloc_debug #03 pc 0x42\n";
1108 expected_log += DIVIDER;
1109 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1110 }
1111
TEST_F(MallocDebugTest,free_track_header_tag_corrupted)1112 TEST_F(MallocDebugTest, free_track_header_tag_corrupted) {
1113 Init("free_track=100 free_track_backtrace_num_frames=0 rear_guard");
1114
1115 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
1116 ASSERT_TRUE(pointer != nullptr);
1117 memset(pointer, 0, 100);
1118 debug_free(pointer);
1119
1120 pointer[-get_tag_offset()] = 0x00;
1121
1122 ASSERT_STREQ("", getFakeLogBuf().c_str());
1123 ASSERT_STREQ("", getFakeLogPrint().c_str());
1124
1125 debug_finalize();
1126 initialized = false;
1127
1128 ASSERT_STREQ("", getFakeLogBuf().c_str());
1129 std::string expected_log(DIVIDER);
1130 expected_log += android::base::StringPrintf(
1131 "6 malloc_debug +++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x1cc7dc00 AFTER FREE\n",
1132 pointer);
1133 expected_log += DIVIDER;
1134 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1135 }
1136
TEST_F(MallocDebugTest,free_track_multiple_thread)1137 TEST_F(MallocDebugTest, free_track_multiple_thread) {
1138 Init("free_track=10 free_track_backtrace_num_frames=0");
1139
1140 std::vector<std::thread*> threads(1000);
1141 for (size_t i = 0; i < threads.size(); i++) {
1142 threads[i] = new std::thread([](){
1143 for (size_t j = 0; j < 100; j++) {
1144 void* mem = debug_malloc(100);
1145 write(0, mem, 0);
1146 debug_free(mem);
1147 }
1148 });
1149 }
1150 for (size_t i = 0; i < threads.size(); i++) {
1151 threads[i]->join();
1152 delete threads[i];
1153 }
1154
1155 ASSERT_STREQ("", getFakeLogBuf().c_str());
1156 ASSERT_STREQ("", getFakeLogPrint().c_str());
1157 }
1158
TEST_F(MallocDebugTest,free_track_pointer_modified_after_free)1159 TEST_F(MallocDebugTest, free_track_pointer_modified_after_free) {
1160 Init("free_track=4 fill_on_free=2 free_track_backtrace_num_frames=0");
1161
1162 void* pointers[5];
1163 for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
1164 pointers[i] = debug_malloc(100);
1165 ASSERT_TRUE(pointers[i] != nullptr);
1166 memset(pointers[i], 0, 100);
1167 }
1168
1169 debug_free(pointers[0]);
1170
1171 // overwrite the whole pointer, only expect errors on the fill bytes we check.
1172 memset(pointers[0], 0x20, 100);
1173
1174 for (size_t i = 1; i < sizeof(pointers) / sizeof(void*); i++) {
1175 debug_free(pointers[i]);
1176 }
1177
1178 std::string expected_log(DIVIDER);
1179 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n",
1180 pointers[0]);
1181 expected_log += "6 malloc_debug allocation[0] = 0x20 (expected 0xef)\n";
1182 expected_log += "6 malloc_debug allocation[1] = 0x20 (expected 0xef)\n";
1183 expected_log += DIVIDER;
1184 ASSERT_STREQ("", getFakeLogBuf().c_str());
1185 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1186 }
1187
TEST_F(MallocDebugTest,get_malloc_leak_info_invalid)1188 TEST_F(MallocDebugTest, get_malloc_leak_info_invalid) {
1189 Init("fill");
1190
1191 uint8_t* info;
1192 size_t overall_size;
1193 size_t info_size;
1194 size_t total_memory;
1195 size_t backtrace_size;
1196
1197 std::string expected_log("6 malloc_debug get_malloc_leak_info: At least one invalid parameter.\n");
1198
1199 debug_get_malloc_leak_info(nullptr, &overall_size, &info_size, &total_memory, &backtrace_size);
1200 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1201
1202 resetLogs();
1203 debug_get_malloc_leak_info(&info, nullptr, &info_size, &total_memory, &backtrace_size);
1204 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1205
1206 resetLogs();
1207 debug_get_malloc_leak_info(&info, &overall_size, nullptr, &total_memory, &backtrace_size);
1208 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1209
1210 resetLogs();
1211 debug_get_malloc_leak_info(&info, &overall_size, &info_size, nullptr, &backtrace_size);
1212 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1213
1214 resetLogs();
1215 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, nullptr);
1216 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1217 }
1218
TEST_F(MallocDebugTest,get_malloc_leak_info_not_enabled)1219 TEST_F(MallocDebugTest, get_malloc_leak_info_not_enabled) {
1220 Init("fill");
1221
1222 uint8_t* info;
1223 size_t overall_size;
1224 size_t info_size;
1225 size_t total_memory;
1226 size_t backtrace_size;
1227
1228 ASSERT_STREQ("", getFakeLogBuf().c_str());
1229 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1230 std::string expected_log(
1231 "6 malloc_debug get_malloc_leak_info: Allocations not being tracked, to enable "
1232 "set the option 'backtrace'.\n");
1233 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1234 }
1235
1236 struct InfoEntry {
1237 size_t size;
1238 size_t num_allocations;
1239 uintptr_t frames[0];
1240 } __attribute__((packed));
1241
TEST_F(MallocDebugTest,get_malloc_leak_info_empty)1242 TEST_F(MallocDebugTest, get_malloc_leak_info_empty) {
1243 Init("backtrace");
1244
1245 uint8_t* info;
1246 size_t overall_size;
1247 size_t info_size;
1248 size_t total_memory;
1249 size_t backtrace_size;
1250
1251 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1252 ASSERT_TRUE(info == nullptr);
1253 ASSERT_EQ(0U, overall_size);
1254 ASSERT_EQ(0U, info_size);
1255 ASSERT_EQ(0U, total_memory);
1256 ASSERT_EQ(0U, backtrace_size);
1257
1258 ASSERT_STREQ("", getFakeLogBuf().c_str());
1259 ASSERT_STREQ("", getFakeLogPrint().c_str());
1260 }
1261
TEST_F(MallocDebugTest,get_malloc_leak_info_single)1262 TEST_F(MallocDebugTest, get_malloc_leak_info_single) {
1263 Init("backtrace");
1264
1265 // Create the expected info buffer.
1266 size_t individual_size = GetInfoEntrySize(16);
1267 std::vector<uint8_t> expected_info(individual_size);
1268 memset(expected_info.data(), 0, individual_size);
1269
1270 InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
1271 entry->size = 200;
1272 entry->num_allocations = 1;
1273 entry->frames[0] = 0xf;
1274 entry->frames[1] = 0xe;
1275 entry->frames[2] = 0xd;
1276
1277 backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd});
1278
1279 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(entry->size));
1280 ASSERT_TRUE(pointer != nullptr);
1281 memset(pointer, 0, entry->size);
1282
1283 uint8_t* info;
1284 size_t overall_size;
1285 size_t info_size;
1286 size_t total_memory;
1287 size_t backtrace_size;
1288
1289 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1290 ASSERT_TRUE(info != nullptr);
1291 ASSERT_EQ(individual_size, overall_size);
1292 ASSERT_EQ(individual_size, info_size);
1293 ASSERT_EQ(200U, total_memory);
1294 ASSERT_EQ(16U, backtrace_size);
1295 ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0)
1296 << ShowDiffs(expected_info.data(), info, overall_size);
1297
1298 debug_free_malloc_leak_info(info);
1299
1300 debug_free(pointer);
1301
1302 ASSERT_STREQ("", getFakeLogBuf().c_str());
1303 ASSERT_STREQ("", getFakeLogPrint().c_str());
1304 }
1305
TEST_F(MallocDebugTest,get_malloc_leak_info_multi)1306 TEST_F(MallocDebugTest, get_malloc_leak_info_multi) {
1307 Init("backtrace=16");
1308
1309 // Create the expected info buffer.
1310 size_t individual_size = GetInfoEntrySize(16);
1311 std::vector<uint8_t> expected_info(individual_size * 3);
1312 memset(expected_info.data(), 0, individual_size * 3);
1313
1314 InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
1315 InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
1316 reinterpret_cast<uintptr_t>(entry0) + individual_size);
1317 InfoEntry* entry2 = reinterpret_cast<InfoEntry*>(
1318 reinterpret_cast<uintptr_t>(entry1) + individual_size);
1319
1320 // These values will be in the reverse order that we create.
1321 entry2->size = 500;
1322 entry2->num_allocations = 1;
1323 entry2->frames[0] = 0xf;
1324 entry2->frames[1] = 0xe;
1325 entry2->frames[2] = 0xd;
1326 entry2->frames[3] = 0xc;
1327
1328 backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
1329
1330 uint8_t* pointers[3];
1331
1332 pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry2->size));
1333 ASSERT_TRUE(pointers[0] != nullptr);
1334 memset(pointers[0], 0, entry2->size);
1335
1336 entry1->size = 4100;
1337 entry1->num_allocations = 1;
1338 for (size_t i = 0; i < 16; i++) {
1339 entry1->frames[i] = 0xbc000 + i;
1340 }
1341
1342 backtrace_fake_add(
1343 std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
1344 0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
1345 0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
1346
1347 pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
1348 ASSERT_TRUE(pointers[1] != nullptr);
1349 memset(pointers[1], 0, entry1->size);
1350
1351 entry0->size = 9000;
1352 entry0->num_allocations = 1;
1353
1354 entry0->frames[0] = 0x104;
1355 backtrace_fake_add(std::vector<uintptr_t> {0x104});
1356
1357 pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
1358 ASSERT_TRUE(pointers[2] != nullptr);
1359 memset(pointers[2], 0, entry0->size);
1360
1361 uint8_t* info;
1362 size_t overall_size;
1363 size_t info_size;
1364 size_t total_memory;
1365 size_t backtrace_size;
1366
1367 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1368 ASSERT_TRUE(info != nullptr);
1369 ASSERT_EQ(individual_size * 3, overall_size);
1370 ASSERT_EQ(individual_size, info_size);
1371 ASSERT_EQ(500U + 4100U + 9000U, total_memory);
1372 ASSERT_EQ(16U, backtrace_size);
1373 ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0)
1374 << ShowDiffs(expected_info.data(), info, overall_size);
1375
1376 debug_free_malloc_leak_info(info);
1377
1378 debug_free(pointers[0]);
1379 debug_free(pointers[1]);
1380 debug_free(pointers[2]);
1381
1382 ASSERT_STREQ("", getFakeLogBuf().c_str());
1383 ASSERT_STREQ("", getFakeLogPrint().c_str());
1384 }
1385
TEST_F(MallocDebugTest,get_malloc_backtrace_with_header)1386 TEST_F(MallocDebugTest, get_malloc_backtrace_with_header) {
1387 Init("backtrace=16 guard");
1388
1389 void* pointer = debug_malloc(100);
1390 ASSERT_TRUE(pointer != nullptr);
1391 memset(pointer, 0, 100);
1392 EXPECT_EQ(100U, debug_malloc_usable_size(pointer));
1393
1394 uint8_t* info;
1395 size_t overall_size;
1396 size_t info_size;
1397 size_t total_memory;
1398 size_t backtrace_size;
1399
1400 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1401 EXPECT_TRUE(info != nullptr);
1402 EXPECT_EQ(GetInfoEntrySize(16), overall_size);
1403 EXPECT_EQ(GetInfoEntrySize(16), info_size);
1404 EXPECT_EQ(100U, total_memory);
1405 EXPECT_EQ(16U, backtrace_size);
1406 debug_free_malloc_leak_info(info);
1407
1408 debug_free(pointer);
1409
1410 // There should be no pointers that have leaked.
1411 debug_finalize();
1412 initialized = false;
1413
1414 ASSERT_STREQ("", getFakeLogBuf().c_str());
1415 ASSERT_STREQ("", getFakeLogPrint().c_str());
1416 }
1417
SanitizeHeapData(const std::string & data)1418 static std::string SanitizeHeapData(const std::string& data) {
1419 if (data.empty()) {
1420 return data;
1421 }
1422
1423 // Remove the map data since it's not consistent.
1424 std::string sanitized;
1425 bool skip_map_data = false;
1426 bool map_data_found = false;
1427 for (auto& line : android::base::Split(data, "\n")) {
1428 if (skip_map_data) {
1429 if (line == "END") {
1430 if (map_data_found) {
1431 sanitized += "MAP_DATA\n";
1432 map_data_found = false;
1433 }
1434 skip_map_data = false;
1435 } else {
1436 map_data_found = true;
1437 continue;
1438 }
1439 }
1440
1441 if (android::base::StartsWith(line, "Build fingerprint:")) {
1442 sanitized += "Build fingerprint: ''\n";
1443 } else {
1444 if (line == "MAPS") {
1445 skip_map_data = true;
1446 }
1447 sanitized += line + '\n';
1448 }
1449 }
1450 return android::base::Trim(sanitized);
1451 }
1452
BacktraceDumpOnSignal(bool trigger_with_alloc)1453 void MallocDebugTest::BacktraceDumpOnSignal(bool trigger_with_alloc) {
1454 Init("backtrace=4");
1455
1456 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
1457 backtrace_fake_add(std::vector<uintptr_t> {0x300, 0x400});
1458 backtrace_fake_add(std::vector<uintptr_t> {0x500, 0x600});
1459
1460 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000});
1461 backtrace_fake_add(std::vector<uintptr_t> {0xa100, 0xb200});
1462 backtrace_fake_add(std::vector<uintptr_t> {0xa300, 0xb300});
1463
1464 std::vector<void*> pointers;
1465 zygote_child = true;
1466 pointers.push_back(debug_malloc(100));
1467 ASSERT_TRUE(pointers.back() != nullptr);
1468 pointers.push_back(debug_malloc(40));
1469 ASSERT_TRUE(pointers.back() != nullptr);
1470 pointers.push_back(debug_malloc(200));
1471 ASSERT_TRUE(pointers.back() != nullptr);
1472
1473 zygote_child = false;
1474 pointers.push_back(debug_malloc(10));
1475 ASSERT_TRUE(pointers.back() != nullptr);
1476 pointers.push_back(debug_malloc(50));
1477 ASSERT_TRUE(pointers.back() != nullptr);
1478 pointers.push_back(debug_malloc(5));
1479 ASSERT_TRUE(pointers.back() != nullptr);
1480
1481 // Dump all of the data accumulated so far.
1482 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 17) == 0);
1483 sleep(1);
1484
1485 // This triggers the dumping.
1486 if (trigger_with_alloc) {
1487 pointers.push_back(debug_malloc(23));
1488 ASSERT_TRUE(pointers.back() != nullptr);
1489 } else {
1490 debug_free(pointers.back());
1491 pointers.pop_back();
1492 }
1493
1494 for (auto* pointer : pointers) {
1495 debug_free(pointer);
1496 }
1497
1498 // Read all of the contents.
1499 std::string actual;
1500 std::string name = android::base::StringPrintf("%s.%d.txt", BACKTRACE_DUMP_PREFIX, getpid());
1501 ASSERT_TRUE(android::base::ReadFileToString(name, &actual));
1502 ASSERT_EQ(0, unlink(name.c_str()));
1503
1504 std::string sanitized(SanitizeHeapData(actual));
1505
1506 std::string expected =
1507 R"(Android Native Heap Dump v1.2
1508
1509 Build fingerprint: ''
1510
1511 Total memory: 405
1512 Allocation records: 6
1513 Backtrace size: 4
1514
1515 z 0 sz 50 num 1 bt a100 b200
1516 z 0 sz 10 num 1 bt a000 b000
1517 z 0 sz 5 num 1 bt a300 b300
1518 z 1 sz 200 num 1 bt 500 600
1519 z 1 sz 100 num 1 bt 100 200
1520 z 1 sz 40 num 1 bt 300 400
1521 MAPS
1522 MAP_DATA
1523 END)";
1524 ASSERT_STREQ(expected.c_str(), sanitized.c_str()) << "Actual data: \n" << actual;
1525
1526 ASSERT_STREQ("", getFakeLogBuf().c_str());
1527 std::string expected_log = android::base::StringPrintf(
1528 "6 malloc_debug Dumping to file: /data/local/tmp/backtrace_heap.%d.txt\n\n", getpid());
1529 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1530 }
1531
TEST_F(MallocDebugTest,backtrace_dump_on_signal_by_malloc)1532 TEST_F(MallocDebugTest, backtrace_dump_on_signal_by_malloc) {
1533 BacktraceDumpOnSignal(true);
1534 }
1535
TEST_F(MallocDebugTest,backtrace_dump_on_signal_by_free)1536 TEST_F(MallocDebugTest, backtrace_dump_on_signal_by_free) {
1537 BacktraceDumpOnSignal(false);
1538 }
1539
TEST_F(MallocDebugTest,backtrace_dump_on_exit)1540 TEST_F(MallocDebugTest, backtrace_dump_on_exit) {
1541 pid_t pid;
1542 if ((pid = fork()) == 0) {
1543 Init("backtrace=4 backtrace_dump_on_exit");
1544 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
1545 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000});
1546 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000, 0xc000});
1547
1548 std::vector<void*> pointers;
1549 pointers.push_back(debug_malloc(300));
1550 pointers.push_back(debug_malloc(400));
1551 pointers.push_back(debug_malloc(500));
1552
1553 // Call the exit function manually.
1554 debug_finalize();
1555 _exit(0);
1556 }
1557 ASSERT_NE(-1, pid);
1558 ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0)));
1559
1560 // Read all of the contents.
1561 std::string actual;
1562 std::string name = android::base::StringPrintf("%s.%d.exit.txt", BACKTRACE_DUMP_PREFIX, pid);
1563 ASSERT_TRUE(android::base::ReadFileToString(name, &actual));
1564 ASSERT_EQ(0, unlink(name.c_str()));
1565
1566 std::string sanitized(SanitizeHeapData(actual));
1567
1568 std::string expected =
1569 R"(Android Native Heap Dump v1.2
1570
1571 Build fingerprint: ''
1572
1573 Total memory: 1200
1574 Allocation records: 3
1575 Backtrace size: 4
1576
1577 z 0 sz 500 num 1 bt a000 b000 c000
1578 z 0 sz 400 num 1 bt a000 b000
1579 z 0 sz 300 num 1 bt 100 200
1580 MAPS
1581 MAP_DATA
1582 END)";
1583 ASSERT_STREQ(expected.c_str(), sanitized.c_str()) << "Actual data: \n" << actual;
1584
1585 ASSERT_STREQ("", getFakeLogBuf().c_str());
1586 ASSERT_STREQ("", getFakeLogPrint().c_str());
1587 }
1588
TEST_F(MallocDebugTest,backtrace_dump_on_exit_shared_backtrace)1589 TEST_F(MallocDebugTest, backtrace_dump_on_exit_shared_backtrace) {
1590 pid_t pid;
1591 if ((pid = fork()) == 0) {
1592 Init("backtrace=4 backtrace_dump_on_exit");
1593 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
1594 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000, 0xc000});
1595 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
1596
1597 std::vector<void*> pointers;
1598 pointers.push_back(debug_malloc(300));
1599 pointers.push_back(debug_malloc(400));
1600 pointers.push_back(debug_malloc(300));
1601
1602 // Call the exit function manually.
1603 debug_finalize();
1604 _exit(0);
1605 }
1606 ASSERT_NE(-1, pid);
1607 ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0)));
1608
1609 // Read all of the contents.
1610 std::string actual;
1611 std::string name = android::base::StringPrintf("%s.%d.exit.txt", BACKTRACE_DUMP_PREFIX, pid);
1612 ASSERT_TRUE(android::base::ReadFileToString(name, &actual));
1613 ASSERT_EQ(0, unlink(name.c_str()));
1614
1615 std::string sanitized(SanitizeHeapData(actual));
1616
1617 std::string expected =
1618 R"(Android Native Heap Dump v1.2
1619
1620 Build fingerprint: ''
1621
1622 Total memory: 1000
1623 Allocation records: 2
1624 Backtrace size: 4
1625
1626 z 0 sz 400 num 1 bt a000 b000 c000
1627 z 0 sz 300 num 2 bt 100 200
1628 MAPS
1629 MAP_DATA
1630 END)";
1631 ASSERT_STREQ(expected.c_str(), sanitized.c_str()) << "Actual data: \n" << actual;
1632
1633 ASSERT_STREQ("", getFakeLogBuf().c_str());
1634 ASSERT_STREQ("", getFakeLogPrint().c_str());
1635 }
1636
TEST_F(MallocDebugTest,backtrace_full_dump_on_exit)1637 TEST_F(MallocDebugTest, backtrace_full_dump_on_exit) {
1638 pid_t pid;
1639 if ((pid = fork()) == 0) {
1640 std::shared_ptr<unwindstack::MapInfo> empty_map;
1641 Init("backtrace=4 backtrace_full backtrace_dump_on_exit");
1642 BacktraceUnwindFake(
1643 std::vector<unwindstack::FrameData>{{0, 0x100, 0x1100, 0, "fake1", 10, empty_map},
1644 {1, 0x200, 0x1200, 0, "fake2", 20, empty_map}});
1645 std::shared_ptr<unwindstack::MapInfo> map_info =
1646 unwindstack::MapInfo::Create(0x10000, 0x20000, 0, PROT_READ | PROT_EXEC, "/data/fake.so");
1647 BacktraceUnwindFake(
1648 std::vector<unwindstack::FrameData>{{0, 0xa000, 0x1a000, 0, "level1", 0, map_info},
1649 {1, 0xb000, 0x1b000, 0, "level2", 10, map_info}});
1650 BacktraceUnwindFake(
1651 std::vector<unwindstack::FrameData>{{0, 0xa000, 0x1a000, 0, "func1", 0, empty_map},
1652 {1, 0xb000, 0x1b000, 0, "func2", 10, empty_map},
1653 {2, 0xc000, 0x1c000, 0, "", 30, empty_map}});
1654
1655 std::vector<void*> pointers;
1656 pointers.push_back(debug_malloc(300));
1657 pointers.push_back(debug_malloc(400));
1658 pointers.push_back(debug_malloc(500));
1659
1660 // Call the exit function manually.
1661 debug_finalize();
1662 _exit(0);
1663 }
1664 ASSERT_NE(-1, pid);
1665 ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0)));
1666
1667 // Read all of the contents.
1668 std::string actual;
1669 std::string name = android::base::StringPrintf("%s.%d.exit.txt", BACKTRACE_DUMP_PREFIX, pid);
1670 ASSERT_TRUE(android::base::ReadFileToString(name, &actual));
1671 ASSERT_EQ(0, unlink(name.c_str()));
1672
1673 std::string sanitized(SanitizeHeapData(actual));
1674
1675 std::string expected =
1676 R"(Android Native Heap Dump v1.2
1677
1678 Build fingerprint: ''
1679
1680 Total memory: 1200
1681 Allocation records: 3
1682 Backtrace size: 4
1683
1684 z 0 sz 500 num 1 bt 1a000 1b000 1c000
1685 bt_info {"" a000 "func1" 0} {"" b000 "func2" a} {"" c000 "" 0}
1686 z 0 sz 400 num 1 bt 1a000 1b000
1687 bt_info {"/data/fake.so" a000 "level1" 0} {"/data/fake.so" b000 "level2" a}
1688 z 0 sz 300 num 1 bt 1100 1200
1689 bt_info {"" 100 "fake1" a} {"" 200 "fake2" 14}
1690 MAPS
1691 MAP_DATA
1692 END)";
1693 ASSERT_STREQ(expected.c_str(), sanitized.c_str()) << "Actual data: \n" << actual;
1694
1695 ASSERT_STREQ("", getFakeLogBuf().c_str());
1696 ASSERT_STREQ("", getFakeLogPrint().c_str());
1697 }
1698
TEST_F(MallocDebugTest,realloc_usable_size)1699 TEST_F(MallocDebugTest, realloc_usable_size) {
1700 Init("front_guard");
1701
1702 // Verify that if the usable size > size of alloc, that realloc
1703 // copies the bytes in the usable size not just the size.
1704 // This assumes that an allocation of size 1 returns usable size > 1.
1705 // If this isn't true, this test is not going to do anything.
1706 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(1));
1707 ASSERT_TRUE(pointer != nullptr);
1708 size_t usable_size = debug_malloc_usable_size(pointer);
1709 memset(pointer, 0xaa, usable_size);
1710 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, usable_size + 10));
1711 ASSERT_TRUE(pointer != nullptr);
1712 ASSERT_LE(usable_size + 10, debug_malloc_usable_size(pointer));
1713 for (size_t i = 0; i < usable_size; i++) {
1714 ASSERT_EQ(0xaa, pointer[i]) << "Failed compare at byte " << i;
1715 }
1716 debug_free(pointer);
1717
1718 ASSERT_STREQ("", getFakeLogBuf().c_str());
1719 ASSERT_STREQ("", getFakeLogPrint().c_str());
1720 }
1721
TEST_F(MallocDebugTest,backtrace_enable_on_signal)1722 TEST_F(MallocDebugTest, backtrace_enable_on_signal) {
1723 Init("backtrace_enable_on_signal=20");
1724
1725 size_t individual_size = GetInfoEntrySize(20);
1726
1727 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1728 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300, 0x400});
1729 backtrace_fake_add(std::vector<uintptr_t> {0x500, 0xa00, 0xb00});
1730
1731 // First allocation should not actually attempt to get the backtrace.
1732 void* pointer = debug_malloc(10);
1733 ASSERT_TRUE(pointer != nullptr);
1734
1735 uint8_t* info;
1736 size_t overall_size;
1737 size_t info_size;
1738 size_t total_memory;
1739 size_t backtrace_size;
1740
1741 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1742 ASSERT_TRUE(info == nullptr);
1743 ASSERT_EQ(0U, overall_size);
1744 ASSERT_EQ(0U, info_size);
1745 ASSERT_EQ(0U, total_memory);
1746 ASSERT_EQ(0U, backtrace_size);
1747 debug_free(pointer);
1748
1749 debug_free_malloc_leak_info(info);
1750
1751 // Send the signal to enable.
1752 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 19) == 0);
1753 sleep(1);
1754
1755 pointer = debug_malloc(100);
1756 ASSERT_TRUE(pointer != nullptr);
1757
1758 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1759 ASSERT_TRUE(info != nullptr);
1760 ASSERT_EQ(individual_size, overall_size);
1761 ASSERT_EQ(individual_size, info_size);
1762 ASSERT_EQ(100U, total_memory);
1763 ASSERT_EQ(20U, backtrace_size);
1764 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1765 ASSERT_EQ(0xbc000U, ips[0]);
1766 ASSERT_EQ(0xecd00U, ips[1]);
1767 ASSERT_EQ(0x12000U, ips[2]);
1768 for (size_t i = 3; i < 20; i++) {
1769 ASSERT_EQ(0U, ips[i]);
1770 }
1771
1772 debug_free(pointer);
1773
1774 debug_free_malloc_leak_info(info);
1775
1776 // Send the signal to disable.
1777 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 19) == 0);
1778 sleep(1);
1779
1780 pointer = debug_malloc(200);
1781 ASSERT_TRUE(pointer != nullptr);
1782
1783 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1784 ASSERT_TRUE(info == nullptr);
1785 ASSERT_EQ(0U, overall_size);
1786 ASSERT_EQ(0U, info_size);
1787 ASSERT_EQ(0U, total_memory);
1788 ASSERT_EQ(0U, backtrace_size);
1789
1790 debug_free(pointer);
1791
1792 debug_free_malloc_leak_info(info);
1793
1794 ASSERT_STREQ("", getFakeLogBuf().c_str());
1795 ASSERT_STREQ("", getFakeLogPrint().c_str());
1796 }
1797
TEST_F(MallocDebugTest,backtrace_same_stack)1798 TEST_F(MallocDebugTest, backtrace_same_stack) {
1799 Init("backtrace=4");
1800
1801 size_t individual_size = GetInfoEntrySize(4);
1802
1803 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1804 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1805 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1806 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1807
1808 void* pointers[4];
1809 pointers[0] = debug_malloc(10);
1810 ASSERT_TRUE(pointers[0] != nullptr);
1811 pointers[1] = debug_malloc(10);
1812 ASSERT_TRUE(pointers[1] != nullptr);
1813 pointers[2] = debug_malloc(10);
1814 ASSERT_TRUE(pointers[2] != nullptr);
1815 pointers[3] = debug_malloc(100);
1816 ASSERT_TRUE(pointers[3] != nullptr);
1817
1818 uint8_t* info;
1819 size_t overall_size;
1820 size_t info_size;
1821 size_t total_memory;
1822 size_t backtrace_size;
1823
1824 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1825 ASSERT_TRUE(info != nullptr);
1826 ASSERT_EQ(individual_size * 2, overall_size);
1827 ASSERT_EQ(individual_size, info_size);
1828 EXPECT_EQ(130U, total_memory);
1829 EXPECT_EQ(4U, backtrace_size);
1830 EXPECT_EQ(100U, *reinterpret_cast<size_t*>(&info[0]));
1831 EXPECT_EQ(1U, *reinterpret_cast<size_t*>(&info[sizeof(size_t)]));
1832 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1833 EXPECT_EQ(0xbc000U, ips[0]);
1834 EXPECT_EQ(0xecd00U, ips[1]);
1835 EXPECT_EQ(0x12000U, ips[2]);
1836
1837 EXPECT_EQ(10U, *reinterpret_cast<size_t*>(&info[individual_size]));
1838 EXPECT_EQ(3U, *reinterpret_cast<size_t*>(&info[sizeof(size_t) + individual_size]));
1839 ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t) + individual_size]);
1840 EXPECT_EQ(0xbc000U, ips[0]);
1841 EXPECT_EQ(0xecd00U, ips[1]);
1842 EXPECT_EQ(0x12000U, ips[2]);
1843
1844 debug_free_malloc_leak_info(info);
1845
1846 debug_free(pointers[0]);
1847 debug_free(pointers[1]);
1848 debug_free(pointers[2]);
1849 debug_free(pointers[3]);
1850
1851 ASSERT_STREQ("", getFakeLogBuf().c_str());
1852 ASSERT_STREQ("", getFakeLogPrint().c_str());
1853 }
1854
TEST_F(MallocDebugTest,backtrace_same_stack_zygote)1855 TEST_F(MallocDebugTest, backtrace_same_stack_zygote) {
1856 Init("backtrace=4");
1857
1858 size_t individual_size = GetInfoEntrySize(4);
1859
1860 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1861 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1862 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1863 backtrace_fake_add(std::vector<uintptr_t> {0xbc000});
1864
1865 zygote_child = true;
1866
1867 void* pointers[4];
1868 pointers[0] = debug_malloc(100);
1869 ASSERT_TRUE(pointers[0] != nullptr);
1870 pointers[1] = debug_malloc(100);
1871 ASSERT_TRUE(pointers[1] != nullptr);
1872 pointers[2] = debug_malloc(100);
1873 ASSERT_TRUE(pointers[2] != nullptr);
1874 pointers[3] = debug_malloc(100);
1875 ASSERT_TRUE(pointers[3] != nullptr);
1876
1877 uint8_t* info;
1878 size_t overall_size;
1879 size_t info_size;
1880 size_t total_memory;
1881 size_t backtrace_size;
1882
1883 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1884 ASSERT_TRUE(info != nullptr);
1885 ASSERT_EQ(individual_size * 2, overall_size);
1886 EXPECT_EQ(individual_size, info_size);
1887 EXPECT_EQ(400U, total_memory);
1888 EXPECT_EQ(4U, backtrace_size);
1889
1890 EXPECT_EQ(0x80000064U, *reinterpret_cast<size_t*>(&info[0]));
1891 EXPECT_EQ(3U, *reinterpret_cast<size_t*>(&info[sizeof(size_t)]));
1892 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1893 EXPECT_EQ(0xbc000U, ips[0]);
1894 EXPECT_EQ(0xecd00U, ips[1]);
1895 EXPECT_EQ(0x12000U, ips[2]);
1896
1897 EXPECT_EQ(0x80000064U, *reinterpret_cast<size_t*>(&info[individual_size]));
1898 EXPECT_EQ(1U, *reinterpret_cast<size_t*>(&info[sizeof(size_t) + individual_size]));
1899 ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t) + individual_size]);
1900 EXPECT_EQ(0xbc000U, ips[0]);
1901 EXPECT_EQ(0U, ips[1]);
1902
1903 debug_free_malloc_leak_info(info);
1904
1905 debug_free(pointers[0]);
1906 debug_free(pointers[1]);
1907 debug_free(pointers[2]);
1908 debug_free(pointers[3]);
1909
1910 ASSERT_STREQ("", getFakeLogBuf().c_str());
1911 ASSERT_STREQ("", getFakeLogPrint().c_str());
1912 }
1913
TEST_F(MallocDebugTest,backtrace_same_stack_mix_zygote)1914 TEST_F(MallocDebugTest, backtrace_same_stack_mix_zygote) {
1915 Init("backtrace=4");
1916
1917 size_t individual_size = GetInfoEntrySize(4);
1918
1919 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1920 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1921 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1922 backtrace_fake_add(std::vector<uintptr_t> {0xbc000});
1923
1924 zygote_child = true;
1925 void* pointers[4];
1926 pointers[0] = debug_malloc(40);
1927 ASSERT_TRUE(pointers[0] != nullptr);
1928 pointers[1] = debug_malloc(40);
1929 ASSERT_TRUE(pointers[1] != nullptr);
1930
1931 zygote_child = false;
1932 pointers[2] = debug_malloc(40);
1933 ASSERT_TRUE(pointers[2] != nullptr);
1934 pointers[3] = debug_malloc(100);
1935 ASSERT_TRUE(pointers[3] != nullptr);
1936
1937 uint8_t* info;
1938 size_t overall_size;
1939 size_t info_size;
1940 size_t total_memory;
1941 size_t backtrace_size;
1942
1943 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1944 ASSERT_TRUE(info != nullptr);
1945 ASSERT_EQ(individual_size * 3, overall_size);
1946 ASSERT_EQ(individual_size, info_size);
1947 EXPECT_EQ(220U, total_memory);
1948 EXPECT_EQ(4U, backtrace_size);
1949
1950 EXPECT_EQ(100U, *reinterpret_cast<size_t*>(&info[0]));
1951 EXPECT_EQ(1U, *reinterpret_cast<size_t*>(&info[sizeof(size_t)]));
1952 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1953 EXPECT_EQ(0xbc000U, ips[0]);
1954 EXPECT_EQ(0U, ips[1]);
1955
1956 EXPECT_EQ(40U, *reinterpret_cast<size_t*>(&info[individual_size]));
1957 EXPECT_EQ(1U, *reinterpret_cast<size_t*>(&info[sizeof(size_t) + individual_size]));
1958 ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t) + individual_size]);
1959 EXPECT_EQ(0xbc000U, ips[0]);
1960 EXPECT_EQ(0xecd00U, ips[1]);
1961 EXPECT_EQ(0x12000U, ips[2]);
1962
1963 EXPECT_EQ(0x80000028U, *reinterpret_cast<size_t*>(&info[2 * individual_size]));
1964 EXPECT_EQ(2U, *reinterpret_cast<size_t*>(&info[sizeof(size_t) + 2 * individual_size]));
1965 ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t) + 2 * individual_size]);
1966 EXPECT_EQ(0xbc000U, ips[0]);
1967 EXPECT_EQ(0xecd00U, ips[1]);
1968 EXPECT_EQ(0x12000U, ips[2]);
1969
1970 debug_free_malloc_leak_info(info);
1971
1972 debug_free(pointers[0]);
1973 debug_free(pointers[1]);
1974 debug_free(pointers[2]);
1975 debug_free(pointers[3]);
1976
1977 ASSERT_STREQ("", getFakeLogBuf().c_str());
1978 ASSERT_STREQ("", getFakeLogPrint().c_str());
1979 }
1980
TEST_F(MallocDebugTest,backtrace_frame_data_nullptr_same_size)1981 TEST_F(MallocDebugTest, backtrace_frame_data_nullptr_same_size) {
1982 Init("backtrace=4");
1983
1984 size_t individual_size = GetInfoEntrySize(4);
1985
1986 void* pointers[4];
1987 pointers[0] = debug_malloc(100);
1988 ASSERT_TRUE(pointers[0] != nullptr);
1989 pointers[1] = debug_malloc(100);
1990 ASSERT_TRUE(pointers[1] != nullptr);
1991 pointers[2] = debug_malloc(100);
1992 ASSERT_TRUE(pointers[2] != nullptr);
1993 pointers[3] = debug_malloc(100);
1994 ASSERT_TRUE(pointers[3] != nullptr);
1995
1996 uint8_t* info;
1997 size_t overall_size;
1998 size_t info_size;
1999 size_t total_memory;
2000 size_t backtrace_size;
2001
2002 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
2003 ASSERT_TRUE(info != nullptr);
2004 ASSERT_EQ(individual_size, overall_size);
2005 EXPECT_EQ(individual_size, info_size);
2006 EXPECT_EQ(400U, total_memory);
2007 EXPECT_EQ(4U, backtrace_size);
2008
2009 EXPECT_EQ(100U, *reinterpret_cast<size_t*>(&info[0]));
2010 EXPECT_EQ(4U, *reinterpret_cast<size_t*>(&info[sizeof(size_t)]));
2011 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
2012 EXPECT_EQ(0U, ips[0]);
2013
2014 debug_free_malloc_leak_info(info);
2015
2016 debug_free(pointers[0]);
2017 debug_free(pointers[1]);
2018 debug_free(pointers[2]);
2019 debug_free(pointers[3]);
2020
2021 ASSERT_STREQ("", getFakeLogBuf().c_str());
2022 ASSERT_STREQ("", getFakeLogPrint().c_str());
2023 }
2024
TEST_F(MallocDebugTest,overflow)2025 TEST_F(MallocDebugTest, overflow) {
2026 Init("guard fill_on_free");
2027
2028 void* pointer = debug_malloc(SIZE_MAX);
2029 ASSERT_TRUE(pointer == nullptr);
2030 ASSERT_EQ(ENOMEM, errno);
2031
2032 pointer = debug_calloc(1, SIZE_MAX);
2033 ASSERT_TRUE(pointer == nullptr);
2034 ASSERT_EQ(ENOMEM, errno);
2035
2036 pointer = debug_calloc(SIZE_MAX, 1);
2037 ASSERT_TRUE(pointer == nullptr);
2038 ASSERT_EQ(ENOMEM, errno);
2039
2040 pointer = debug_calloc(SIZE_MAX/100, 100);
2041 ASSERT_TRUE(pointer == nullptr);
2042 ASSERT_EQ(ENOMEM, errno);
2043
2044 pointer = debug_calloc(100, SIZE_MAX/100);
2045 ASSERT_TRUE(pointer == nullptr);
2046 ASSERT_EQ(ENOMEM, errno);
2047
2048 const size_t size_t_bits = sizeof(size_t) * 8;
2049 const size_t sqrt_size_t = 1ULL << (size_t_bits/2);
2050 pointer = debug_calloc(sqrt_size_t + 1, sqrt_size_t);
2051 ASSERT_TRUE(pointer == nullptr);
2052 ASSERT_EQ(ENOMEM, errno);
2053
2054 pointer = debug_realloc(nullptr, SIZE_MAX);
2055 ASSERT_TRUE(pointer == nullptr);
2056 ASSERT_EQ(ENOMEM, errno);
2057
2058 pointer = debug_malloc(100);
2059 ASSERT_TRUE(pointer != nullptr);
2060 memset(pointer, 0xd0, 100);
2061
2062 void* realloc_pointer = debug_realloc(pointer, SIZE_MAX);
2063 ASSERT_TRUE(realloc_pointer == nullptr);
2064 // Verify the pointer was not freed.
2065 for (size_t i = 0; i < 100; i++) {
2066 ASSERT_EQ(0xd0, reinterpret_cast<uint8_t*>(pointer)[i]) << "Failed checking byte " << i;
2067 }
2068 debug_free(pointer);
2069
2070 ASSERT_STREQ("", getFakeLogBuf().c_str());
2071 ASSERT_STREQ("", getFakeLogPrint().c_str());
2072 }
2073
VerifyZygoteSet(size_t memory_bytes)2074 static void VerifyZygoteSet(size_t memory_bytes) {
2075 size_t expected_info_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
2076 std::vector<uint8_t> expected_info(expected_info_size);
2077 memset(expected_info.data(), 0, expected_info_size);
2078 InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
2079 entry->size = memory_bytes | (1U << 31);
2080 entry->num_allocations = 1;
2081 entry->frames[0] = 0x1;
2082
2083 uint8_t* info;
2084 size_t overall_size;
2085 size_t info_size;
2086 size_t total_memory;
2087 size_t backtrace_size;
2088
2089 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
2090 ASSERT_EQ(expected_info_size, overall_size);
2091 ASSERT_EQ(expected_info_size, info_size);
2092 ASSERT_EQ(memory_bytes, total_memory);
2093 ASSERT_EQ(16U, backtrace_size);
2094 ASSERT_TRUE(memcmp(info, expected_info.data(), expected_info_size) == 0)
2095 << ShowDiffs(info, expected_info.data(), expected_info_size);
2096
2097 debug_free_malloc_leak_info(info);
2098 }
2099
TEST_F(MallocDebugTest,zygote_set)2100 TEST_F(MallocDebugTest, zygote_set) {
2101 // Set all of the options.
2102 Init("guard fill backtrace leak_track free_track=2");
2103
2104 zygote_child = true;
2105
2106 backtrace_fake_add(std::vector<uintptr_t> {0x1});
2107
2108 void* pointer = debug_malloc(100);
2109 ASSERT_TRUE(pointer != nullptr);
2110 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
2111 memset(pointer, 0, 100);
2112 VerifyZygoteSet(100);
2113 ASSERT_FALSE(HasFatalFailure());
2114 debug_free(pointer);
2115
2116 backtrace_fake_add(std::vector<uintptr_t> {0x1});
2117 pointer = debug_calloc(10, 20);
2118 ASSERT_TRUE(pointer != nullptr);
2119 ASSERT_EQ(200U, debug_malloc_usable_size(pointer));
2120 VerifyZygoteSet(200);
2121 ASSERT_FALSE(HasFatalFailure());
2122 debug_free(pointer);
2123
2124 backtrace_fake_add(std::vector<uintptr_t> {0x1});
2125 pointer = debug_memalign(128, 300);
2126 ASSERT_TRUE(pointer != nullptr);
2127 ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
2128 memset(pointer, 0, 300);
2129 VerifyZygoteSet(300);
2130 ASSERT_FALSE(HasFatalFailure());
2131 debug_free(pointer);
2132
2133 backtrace_fake_add(std::vector<uintptr_t> {0x1});
2134 pointer = debug_malloc(500);
2135 ASSERT_TRUE(pointer != nullptr);
2136 ASSERT_EQ(500U, debug_malloc_usable_size(pointer));
2137 memset(pointer, 0, 500);
2138 VerifyZygoteSet(500);
2139 ASSERT_FALSE(HasFatalFailure());
2140
2141 backtrace_fake_add(std::vector<uintptr_t> {0x1});
2142 pointer = debug_realloc(pointer, 300);
2143 ASSERT_TRUE(pointer != nullptr);
2144 ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
2145 VerifyZygoteSet(300);
2146 ASSERT_FALSE(HasFatalFailure());
2147 debug_free(pointer);
2148
2149 ASSERT_STREQ("", getFakeLogBuf().c_str());
2150 ASSERT_STREQ("", getFakeLogPrint().c_str());
2151 }
2152
TEST_F(MallocDebugTest,max_size)2153 TEST_F(MallocDebugTest, max_size) {
2154 Init("guard");
2155
2156 void* pointer = debug_malloc(1U << 31);
2157 ASSERT_TRUE(pointer == nullptr);
2158
2159 pointer = debug_calloc(1, 1U << 31);
2160 ASSERT_TRUE(pointer == nullptr);
2161
2162 pointer = debug_calloc(1U << 31, 1);
2163 ASSERT_TRUE(pointer == nullptr);
2164
2165 pointer = debug_memalign(16, 1U << 31);
2166 ASSERT_TRUE(pointer == nullptr);
2167
2168 ASSERT_STREQ("", getFakeLogBuf().c_str());
2169 ASSERT_STREQ("", getFakeLogPrint().c_str());
2170 }
2171
TEST_F(MallocDebugTest,debug_mallinfo)2172 TEST_F(MallocDebugTest, debug_mallinfo) {
2173 SKIP_WITH_HWASAN;
2174 Init("guard");
2175
2176 void* pointer = debug_malloc(150);
2177 ASSERT_TRUE(pointer != nullptr);
2178
2179 struct mallinfo mi = debug_mallinfo();
2180 EXPECT_NE(0U, mi.uordblks);
2181
2182 debug_free(pointer);
2183
2184 ASSERT_STREQ("", getFakeLogBuf().c_str());
2185 ASSERT_STREQ("", getFakeLogPrint().c_str());
2186 }
2187
TEST_F(MallocDebugTest,debug_mallopt)2188 TEST_F(MallocDebugTest, debug_mallopt) {
2189 Init("guard");
2190
2191 void* pointer = debug_malloc(150);
2192 ASSERT_TRUE(pointer != nullptr);
2193
2194 EXPECT_EQ(0, debug_mallopt(-1000, 1));
2195
2196 debug_free(pointer);
2197
2198 ASSERT_STREQ("", getFakeLogBuf().c_str());
2199 ASSERT_STREQ("", getFakeLogPrint().c_str());
2200 }
2201
TEST_F(MallocDebugTest,debug_posix_memalign)2202 TEST_F(MallocDebugTest, debug_posix_memalign) {
2203 Init("guard");
2204
2205 void* pointer;
2206 ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 300));
2207 ASSERT_TRUE(pointer != nullptr);
2208 debug_free(pointer);
2209
2210 ASSERT_EQ(EINVAL, debug_posix_memalign(&pointer, 11, 300));
2211
2212 ASSERT_EQ(ENOMEM, debug_posix_memalign(&pointer, 16, SIZE_MAX));
2213
2214 ASSERT_STREQ("", getFakeLogBuf().c_str());
2215 ASSERT_STREQ("", getFakeLogPrint().c_str());
2216 }
2217
2218 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
TEST_F(MallocDebugTest,debug_pvalloc)2219 TEST_F(MallocDebugTest, debug_pvalloc) {
2220 Init("guard");
2221
2222 size_t pagesize = getpagesize();
2223 void* pointer = debug_pvalloc(1);
2224 ASSERT_TRUE(pointer != nullptr);
2225 ASSERT_EQ(pagesize, debug_malloc_usable_size(pointer));
2226 uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
2227 ASSERT_EQ(0U, value);
2228 debug_free(pointer);
2229 }
2230
TEST_F(MallocDebugTest,debug_valloc)2231 TEST_F(MallocDebugTest, debug_valloc) {
2232 Init("guard");
2233
2234 size_t pagesize = getpagesize();
2235 void* pointer = debug_valloc(100);
2236 ASSERT_TRUE(pointer != nullptr);
2237 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
2238 uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
2239 ASSERT_EQ(0U, value);
2240 debug_free(pointer);
2241 }
2242 #endif
2243
VerifyRecordAllocs(const std::string & record_filename)2244 void VerifyRecordAllocs(const std::string& record_filename) {
2245 std::vector<std::string> expected;
2246
2247 void* pointer = debug_malloc(10);
2248 ASSERT_TRUE(pointer != nullptr);
2249 expected.push_back(android::base::StringPrintf("%d: malloc %p 10", getpid(), pointer));
2250 debug_free(pointer);
2251 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2252
2253 pointer = debug_calloc(20, 1);
2254 ASSERT_TRUE(pointer != nullptr);
2255 expected.push_back(android::base::StringPrintf("%d: calloc %p 20 1", getpid(), pointer));
2256 debug_free(pointer);
2257 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2258
2259 pointer = debug_realloc(nullptr, 30);
2260 ASSERT_TRUE(pointer != nullptr);
2261 expected.push_back(android::base::StringPrintf("%d: realloc %p 0x0 30", getpid(), pointer));
2262 void* old_pointer = pointer;
2263 pointer = debug_realloc(pointer, 2048);
2264 ASSERT_TRUE(pointer != nullptr);
2265 expected.push_back(
2266 android::base::StringPrintf("%d: realloc %p %p 2048", getpid(), pointer, old_pointer));
2267 debug_realloc(pointer, 0);
2268 expected.push_back(android::base::StringPrintf("%d: realloc 0x0 %p 0", getpid(), pointer));
2269
2270 pointer = debug_memalign(16, 40);
2271 ASSERT_TRUE(pointer != nullptr);
2272 expected.push_back(android::base::StringPrintf("%d: memalign %p 16 40", getpid(), pointer));
2273 debug_free(pointer);
2274 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2275
2276 pointer = debug_aligned_alloc(32, 64);
2277 ASSERT_TRUE(pointer != nullptr);
2278 expected.push_back(android::base::StringPrintf("%d: memalign %p 32 64", getpid(), pointer));
2279 debug_free(pointer);
2280 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2281
2282 ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 50));
2283 ASSERT_TRUE(pointer != nullptr);
2284 expected.push_back(android::base::StringPrintf("%d: memalign %p 32 50", getpid(), pointer));
2285 debug_free(pointer);
2286 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2287
2288 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
2289 pointer = debug_pvalloc(60);
2290 ASSERT_TRUE(pointer != nullptr);
2291 expected.push_back(android::base::StringPrintf("%d: memalign %p 4096 4096", getpid(), pointer));
2292 debug_free(pointer);
2293 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2294
2295 pointer = debug_valloc(70);
2296 ASSERT_TRUE(pointer != nullptr);
2297 expected.push_back(android::base::StringPrintf("%d: memalign %p 4096 70", getpid(), pointer));
2298 debug_free(pointer);
2299 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2300 #endif
2301
2302 // Dump all of the data accumulated so far.
2303 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2304
2305 // Read all of the contents.
2306 std::string actual;
2307 ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
2308
2309 VerifyRecords(expected, actual);
2310
2311 ASSERT_STREQ("", getFakeLogBuf().c_str());
2312 ASSERT_STREQ("", getFakeLogPrint().c_str());
2313 }
2314
TEST_F(MallocDebugTest,record_allocs_no_header)2315 TEST_F(MallocDebugTest, record_allocs_no_header) {
2316 InitRecordAllocs("record_allocs");
2317
2318 VerifyRecordAllocs(record_filename);
2319 }
2320
TEST_F(MallocDebugTest,record_allocs_with_header)2321 TEST_F(MallocDebugTest, record_allocs_with_header) {
2322 InitRecordAllocs("record_allocs front_guard");
2323
2324 VerifyRecordAllocs(record_filename);
2325 }
2326
TEST_F(MallocDebugTest,record_allocs_max)2327 TEST_F(MallocDebugTest, record_allocs_max) {
2328 InitRecordAllocs("record_allocs=5");
2329
2330 std::vector<std::string> expected;
2331
2332 void* pointer = debug_malloc(10);
2333 ASSERT_TRUE(pointer != nullptr);
2334 expected.push_back(android::base::StringPrintf("%d: malloc %p 10", getpid(), pointer));
2335 debug_free(pointer);
2336 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2337
2338 pointer = debug_malloc(20);
2339 ASSERT_TRUE(pointer != nullptr);
2340 expected.push_back(android::base::StringPrintf("%d: malloc %p 20", getpid(), pointer));
2341 debug_free(pointer);
2342 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2343
2344 pointer = debug_malloc(1024);
2345 ASSERT_TRUE(pointer != nullptr);
2346 expected.push_back(android::base::StringPrintf("%d: malloc %p 1024", getpid(), pointer));
2347 debug_free(pointer);
2348
2349 // Dump all of the data accumulated so far.
2350 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2351
2352 // Read all of the contents.
2353 std::string actual;
2354 ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
2355
2356 VerifyRecords(expected, actual);
2357
2358 ASSERT_STREQ("", getFakeLogBuf().c_str());
2359 ASSERT_STREQ(
2360 "4 malloc_debug Maximum number of records added, all new operations will be dropped.\n",
2361 getFakeLogPrint().c_str());
2362 }
2363
TEST_F(MallocDebugTest,record_allocs_thread_done)2364 TEST_F(MallocDebugTest, record_allocs_thread_done) {
2365 InitRecordAllocs("record_allocs=5");
2366
2367 static pid_t tid = 0;
2368 static void* pointer = nullptr;
2369 std::thread thread([](){
2370 tid = gettid();
2371 pointer = debug_malloc(100);
2372 write(0, pointer, 0);
2373 debug_free(pointer);
2374 });
2375 thread.join();
2376
2377 std::vector<std::string> expected;
2378 expected.push_back(android::base::StringPrintf("%d: malloc %p 100", tid, pointer));
2379 expected.push_back(android::base::StringPrintf("%d: free %p", tid, pointer));
2380 expected.push_back(android::base::StringPrintf("%d: thread_done 0x0", tid));
2381
2382 // Dump all of the data accumulated so far.
2383 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2384
2385 // Read all of the contents.
2386 std::string actual;
2387 ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
2388
2389 VerifyRecords(expected, actual);
2390
2391 ASSERT_STREQ("", getFakeLogBuf().c_str());
2392 ASSERT_STREQ("", getFakeLogPrint().c_str());
2393 }
2394
TEST_F(MallocDebugTest,record_allocs_file_name_fail)2395 TEST_F(MallocDebugTest, record_allocs_file_name_fail) {
2396 InitRecordAllocs("record_allocs=5");
2397
2398 // Delete the records file and create a symbolic link there to
2399 // make sure the create file will fail.
2400 unlink(record_filename.c_str());
2401
2402 ASSERT_EQ(0, symlink("/data/local/tmp/does_not_exist", record_filename.c_str()));
2403
2404 std::vector<std::string> expected;
2405
2406 void* pointer = debug_malloc(10);
2407 ASSERT_TRUE(pointer != nullptr);
2408 expected.push_back(android::base::StringPrintf("%d: malloc %p 10", getpid(), pointer));
2409 debug_free(pointer);
2410 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2411
2412 // Dump all of the data accumulated so far.
2413 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2414
2415 // Read all of the contents.
2416 std::string actual;
2417 ASSERT_FALSE(android::base::ReadFileToString(record_filename, &actual));
2418
2419 // Unlink the file so the next dump passes.
2420 ASSERT_EQ(0, unlink(record_filename.c_str()));
2421
2422 // Dump all of the data accumulated so far.
2423 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2424
2425 ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
2426
2427 VerifyRecords(expected, actual);
2428
2429 ASSERT_STREQ("", getFakeLogBuf().c_str());
2430 std::string expected_log = android::base::StringPrintf(
2431 "6 malloc_debug Cannot create record alloc file %s: Too many symbolic links encountered\n",
2432 record_filename.c_str());
2433 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
2434 }
2435
TEST_F(MallocDebugTest,record_allocs_no_entries_to_write)2436 TEST_F(MallocDebugTest, record_allocs_no_entries_to_write) {
2437 InitRecordAllocs("record_allocs=5");
2438
2439 kill(getpid(), SIGRTMAX - 18);
2440
2441 std::string actual;
2442 ASSERT_FALSE(android::base::ReadFileToString(record_filename, &actual));
2443
2444 ASSERT_STREQ("", getFakeLogBuf().c_str());
2445 ASSERT_STREQ("4 malloc_debug No alloc entries to write.\n", getFakeLogPrint().c_str());
2446 }
2447
TEST_F(MallocDebugTest,record_allocs_write_entries_does_not_allocate)2448 TEST_F(MallocDebugTest, record_allocs_write_entries_does_not_allocate) {
2449 InitRecordAllocs("record_allocs=5");
2450
2451 std::vector<std::string> expected;
2452
2453 void* pointer = debug_malloc(10);
2454 ASSERT_TRUE(pointer != nullptr);
2455 expected.push_back(android::base::StringPrintf("%d: malloc %p 10", getpid(), pointer));
2456 debug_free(pointer);
2457 expected.push_back(android::base::StringPrintf("%d: free %p", getpid(), pointer));
2458
2459 malloc_disable();
2460 kill(getpid(), SIGRTMAX - 18);
2461 malloc_enable();
2462
2463 std::string actual;
2464 ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
2465
2466 VerifyRecords(expected, actual);
2467
2468 ASSERT_STREQ("", getFakeLogBuf().c_str());
2469 ASSERT_STREQ("", getFakeLogPrint().c_str());
2470 }
2471
TEST_F(MallocDebugTest,record_allocs_on_exit)2472 TEST_F(MallocDebugTest, record_allocs_on_exit) {
2473 InitRecordAllocs("record_allocs record_allocs_on_exit");
2474
2475 // The filename created on exit always appends the pid.
2476 // Modify the variable so the file is deleted at the end of the test.
2477 record_filename += '.' + std::to_string(getpid());
2478
2479 std::vector<std::string> expected;
2480 void* ptr = debug_malloc(100);
2481 expected.push_back(android::base::StringPrintf("%d: malloc %p 100", getpid(), ptr));
2482 ptr = debug_malloc(200);
2483 expected.push_back(android::base::StringPrintf("%d: malloc %p 200", getpid(), ptr));
2484 ptr = debug_malloc(400);
2485 expected.push_back(android::base::StringPrintf("%d: malloc %p 400", getpid(), ptr));
2486
2487 // Call the exit function manually.
2488 debug_finalize();
2489
2490 // Read all of the contents.
2491 std::string actual;
2492 ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
2493 VerifyRecords(expected, actual);
2494
2495 ASSERT_STREQ("", getFakeLogBuf().c_str());
2496 ASSERT_STREQ("", getFakeLogPrint().c_str());
2497 }
2498
TEST_F(MallocDebugTest,record_allocs_present_bytes_check)2499 TEST_F(MallocDebugTest, record_allocs_present_bytes_check) {
2500 InitRecordAllocs("record_allocs record_allocs_on_exit");
2501
2502 // The filename created on exit always appends the pid.
2503 // Modify the variable so the file is deleted at the end of the test.
2504 record_filename += '.' + std::to_string(getpid());
2505
2506 std::vector<memory_trace::Entry> expected;
2507 void* ptr = debug_malloc(100);
2508 expected.push_back(memory_trace::Entry{
2509 .type = memory_trace::MALLOC, .ptr = reinterpret_cast<uint64_t>(ptr), .size = 100});
2510
2511 // Make the entire allocation present.
2512 memset(ptr, 1, 100);
2513
2514 int64_t real_size = debug_malloc_usable_size(ptr);
2515 debug_free(ptr);
2516 expected.push_back(memory_trace::Entry{.type = memory_trace::FREE,
2517 .ptr = reinterpret_cast<uint64_t>(ptr),
2518 .present_bytes = real_size});
2519
2520 ptr = debug_malloc(4096);
2521 expected.push_back(memory_trace::Entry{
2522 .type = memory_trace::MALLOC, .ptr = reinterpret_cast<uint64_t>(ptr), .size = 4096});
2523
2524 memset(ptr, 1, 4096);
2525 real_size = debug_malloc_usable_size(ptr);
2526 void* new_ptr = debug_realloc(ptr, 8192);
2527 expected.push_back(memory_trace::Entry{.type = memory_trace::REALLOC,
2528 .ptr = reinterpret_cast<uint64_t>(new_ptr),
2529 .size = 8192,
2530 .u.old_ptr = reinterpret_cast<uint64_t>(ptr),
2531 .present_bytes = real_size});
2532
2533 memset(new_ptr, 1, 8192);
2534 real_size = debug_malloc_usable_size(new_ptr);
2535 debug_free(new_ptr);
2536 expected.push_back(memory_trace::Entry{.type = memory_trace::FREE,
2537 .ptr = reinterpret_cast<uint64_t>(new_ptr),
2538 .present_bytes = real_size});
2539
2540 ptr = debug_malloc(4096);
2541 expected.push_back(memory_trace::Entry{
2542 .type = memory_trace::MALLOC, .ptr = reinterpret_cast<uint64_t>(ptr), .size = 4096});
2543 memset(ptr, 1, 4096);
2544
2545 // Verify a free realloc does update the present bytes.
2546 real_size = debug_malloc_usable_size(ptr);
2547 EXPECT_TRUE(debug_realloc(ptr, 0) == nullptr);
2548 expected.push_back(memory_trace::Entry{.type = memory_trace::REALLOC,
2549 .ptr = 0,
2550 .u.old_ptr = reinterpret_cast<uint64_t>(ptr),
2551 .present_bytes = real_size});
2552
2553 // Call the exit function manually.
2554 debug_finalize();
2555
2556 // Read all of the contents.
2557 std::string actual;
2558 ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
2559 VerifyRecordEntries(expected, actual);
2560
2561 ASSERT_STREQ("", getFakeLogBuf().c_str());
2562 ASSERT_STREQ("", getFakeLogPrint().c_str());
2563 }
2564
TEST_F(MallocDebugTest,record_allocs_not_all_bytes_present)2565 TEST_F(MallocDebugTest, record_allocs_not_all_bytes_present) {
2566 InitRecordAllocs("record_allocs record_allocs_on_exit");
2567
2568 // The filename created on exit always appends the pid.
2569 // Modify the variable so the file is deleted at the end of the test.
2570 record_filename += '.' + std::to_string(getpid());
2571
2572 std::vector<memory_trace::Entry> expected;
2573 size_t pagesize = getpagesize();
2574 void* ptr = debug_memalign(pagesize, pagesize * 8);
2575 ASSERT_TRUE(ptr != nullptr);
2576 expected.push_back(memory_trace::Entry{.type = memory_trace::MEMALIGN,
2577 .ptr = reinterpret_cast<uint64_t>(ptr),
2578 .size = pagesize * 8,
2579 .u.align = pagesize});
2580
2581 // Mark only some pages in use.
2582 uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
2583 // Make sure the memory is not in use.
2584 ASSERT_EQ(0, madvise(ptr, pagesize * 8, MADV_DONTNEED));
2585 // Dirty three non-consecutive pages.
2586 data[0] = 1;
2587 data[pagesize * 2] = 1;
2588 data[pagesize * 4] = 1;
2589
2590 debug_free(ptr);
2591 expected.push_back(memory_trace::Entry{.type = memory_trace::FREE,
2592 .ptr = reinterpret_cast<uint64_t>(ptr),
2593 .present_bytes = static_cast<int64_t>(pagesize) * 3});
2594
2595 // Call the exit function manually.
2596 debug_finalize();
2597
2598 // Read all of the contents.
2599 std::string actual;
2600 ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
2601 VerifyRecordEntries(expected, actual);
2602
2603 ASSERT_STREQ("", getFakeLogBuf().c_str());
2604 ASSERT_STREQ("", getFakeLogPrint().c_str());
2605 }
2606
TEST_F(MallocDebugTest,verify_pointers)2607 TEST_F(MallocDebugTest, verify_pointers) {
2608 Init("verify_pointers");
2609
2610 void* pointer = debug_malloc(10);
2611 memset(pointer, 0, 10);
2612 debug_free(pointer);
2613
2614 ASSERT_STREQ("", getFakeLogBuf().c_str());
2615 ASSERT_STREQ("", getFakeLogPrint().c_str());
2616
2617 debug_free(pointer);
2618 ASSERT_EQ(0U, debug_malloc_usable_size(pointer));
2619 ASSERT_EQ(nullptr, debug_realloc(pointer, 1000));
2620
2621 ASSERT_STREQ("", getFakeLogBuf().c_str());
2622 std::string free_pointer_str(
2623 android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p UNKNOWN POINTER (free)\n",
2624 pointer));
2625 std::string usable_pointer_str(
2626 android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p UNKNOWN POINTER (malloc_usable_size)\n",
2627 pointer));
2628 std::string realloc_pointer_str(
2629 android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p UNKNOWN POINTER (realloc)\n",
2630 pointer));
2631 std::string backtrace_str("6 malloc_debug Backtrace at time of failure:\n");
2632 backtrace_str += "6 malloc_debug Backtrace failed to get any frames.\n";
2633
2634 std::string expected_log(DIVIDER + free_pointer_str + backtrace_str + DIVIDER);
2635 expected_log += DIVIDER + usable_pointer_str + backtrace_str + DIVIDER;
2636 expected_log += DIVIDER + realloc_pointer_str + backtrace_str + DIVIDER;
2637 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
2638
2639 resetLogs();
2640
2641 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
2642 backtrace_fake_add(std::vector<uintptr_t> {0x300, 0x400});
2643 backtrace_fake_add(std::vector<uintptr_t> {0x500, 0x600});
2644 debug_free(pointer);
2645 ASSERT_EQ(0U, debug_malloc_usable_size(pointer));
2646 ASSERT_EQ(nullptr, debug_realloc(pointer, 1000));
2647
2648 ASSERT_STREQ("", getFakeLogBuf().c_str());
2649 expected_log = DIVIDER + free_pointer_str;
2650 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
2651 expected_log += "6 malloc_debug #00 pc 0x100\n";
2652 expected_log += "6 malloc_debug #01 pc 0x200\n";
2653 expected_log += DIVIDER;
2654 expected_log += DIVIDER + usable_pointer_str;
2655 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
2656 expected_log += "6 malloc_debug #00 pc 0x300\n";
2657 expected_log += "6 malloc_debug #01 pc 0x400\n";
2658 expected_log += DIVIDER;
2659 expected_log += DIVIDER + realloc_pointer_str;
2660 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
2661 expected_log += "6 malloc_debug #00 pc 0x500\n";
2662 expected_log += "6 malloc_debug #01 pc 0x600\n";
2663 expected_log += DIVIDER;
2664 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
2665 }
2666
TEST_F(MallocDebugTest,abort_on_error_log_error)2667 TEST_F(MallocDebugTest, abort_on_error_log_error) {
2668 Init("abort_on_error verify_pointers");
2669
2670 void* pointer = debug_malloc(10);
2671 memset(pointer, 0, 10);
2672 debug_free(pointer);
2673
2674 ASSERT_STREQ("", getFakeLogBuf().c_str());
2675 ASSERT_STREQ("", getFakeLogPrint().c_str());
2676
2677 EXPECT_DEATH(debug_free(pointer), "");
2678 }
2679
TEST_F(MallocDebugTest,abort_on_error_guard_corrupted)2680 TEST_F(MallocDebugTest, abort_on_error_guard_corrupted) {
2681 Init("abort_on_error front_guard=32");
2682
2683 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
2684 ASSERT_TRUE(pointer != nullptr);
2685 pointer[-16] = 0x00;
2686 EXPECT_DEATH(debug_free(pointer), "");
2687 pointer[-16] = 0xaa;
2688 debug_free(pointer);
2689 }
2690
TEST_F(MallocDebugTest,abort_on_error_use_after_free)2691 TEST_F(MallocDebugTest, abort_on_error_use_after_free) {
2692 Init("abort_on_error free_track=100 free_track_backtrace_num_frames=0");
2693
2694 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
2695 ASSERT_TRUE(pointer != nullptr);
2696 memset(pointer, 0, 100);
2697 debug_free(pointer);
2698
2699 pointer[56] = 0x91;
2700
2701 EXPECT_DEATH(debug_finalize(), "");
2702
2703 pointer[56] = 0xef;
2704 }
2705
TEST_F(MallocDebugTest,abort_on_error_header_tag_corrupted)2706 TEST_F(MallocDebugTest, abort_on_error_header_tag_corrupted) {
2707 Init("abort_on_error free_track=100 free_track_backtrace_num_frames=0 rear_guard");
2708
2709 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
2710 ASSERT_TRUE(pointer != nullptr);
2711 memset(pointer, 0, 100);
2712 debug_free(pointer);
2713
2714 uint8_t tag_value = pointer[-get_tag_offset()];
2715 pointer[-get_tag_offset()] = 0x00;
2716
2717 EXPECT_DEATH(debug_finalize(), "");
2718
2719 pointer[-get_tag_offset()] = tag_value;
2720 }
2721
TEST_F(MallocDebugTest,malloc_info_no_pointer_tracking)2722 TEST_F(MallocDebugTest, malloc_info_no_pointer_tracking) {
2723 SKIP_WITH_HWASAN;
2724 Init("fill");
2725
2726 TemporaryFile tf;
2727 ASSERT_TRUE(tf.fd != -1);
2728 FILE* fp = fdopen(tf.fd, "w+");
2729 tf.release();
2730 ASSERT_TRUE(fp != nullptr);
2731 ASSERT_EQ(0, debug_malloc_info(0, fp));
2732 ASSERT_EQ(0, fclose(fp));
2733
2734 std::string contents;
2735 ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
2736
2737 tinyxml2::XMLDocument doc;
2738 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(contents.c_str()));
2739 auto root = doc.FirstChildElement();
2740 ASSERT_TRUE(root != nullptr);
2741 ASSERT_STREQ("malloc", root->Name());
2742 // Don't care what the underyling implementation says, just that it's
2743 // not generated by debug malloc.
2744 ASSERT_STRNE("debug-malloc-1", root->Attribute("version"));
2745 }
2746
TEST_F(MallocDebugTest,malloc_info_with_pointer_tracking)2747 TEST_F(MallocDebugTest, malloc_info_with_pointer_tracking) {
2748 Init("verify_pointers");
2749
2750 std::unique_ptr<void, decltype(debug_free)*> ptr1(debug_malloc(1000), debug_free);
2751 ASSERT_TRUE(ptr1.get() != nullptr);
2752 std::unique_ptr<void, decltype(debug_free)*> ptr2(debug_malloc(1000), debug_free);
2753 ASSERT_TRUE(ptr2.get() != nullptr);
2754 std::unique_ptr<void, decltype(debug_free)*> ptr3(debug_malloc(500), debug_free);
2755 ASSERT_TRUE(ptr3.get() != nullptr);
2756 std::unique_ptr<void, decltype(debug_free)*> ptr4(debug_malloc(1200), debug_free);
2757 ASSERT_TRUE(ptr4.get() != nullptr);
2758
2759 TemporaryFile tf;
2760 ASSERT_TRUE(tf.fd != -1);
2761 FILE* fp = fdopen(tf.fd, "w+");
2762 tf.release();
2763 ASSERT_TRUE(fp != nullptr);
2764 ASSERT_EQ(0, debug_malloc_info(0, fp));
2765 ASSERT_EQ(0, fclose(fp));
2766
2767 std::string contents;
2768 ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
2769
2770 SCOPED_TRACE(testing::Message() << "Output:\n" << contents);
2771
2772 tinyxml2::XMLDocument doc;
2773 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(contents.c_str()));
2774 auto root = doc.FirstChildElement();
2775 ASSERT_TRUE(root != nullptr);
2776 ASSERT_STREQ("malloc", root->Name());
2777 ASSERT_STREQ("debug-malloc-1", root->Attribute("version"));
2778
2779 auto alloc = root->FirstChildElement();
2780 ASSERT_TRUE(alloc != nullptr);
2781 ASSERT_STREQ("allocation", alloc->Name());
2782 int val;
2783 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->QueryIntAttribute("nr", &val));
2784 ASSERT_EQ(0, val);
2785 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("size")->QueryIntText(&val));
2786 ASSERT_EQ(1200, val);
2787 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("total")->QueryIntText(&val));
2788 ASSERT_EQ(1, val);
2789
2790 alloc = alloc->NextSiblingElement();
2791 ASSERT_TRUE(alloc != nullptr);
2792 ASSERT_STREQ("allocation", alloc->Name());
2793 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->QueryIntAttribute("nr", &val));
2794 ASSERT_EQ(1, val);
2795 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("size")->QueryIntText(&val));
2796 ASSERT_EQ(1000, val);
2797 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("total")->QueryIntText(&val));
2798 ASSERT_EQ(2, val);
2799
2800 alloc = alloc->NextSiblingElement();
2801 ASSERT_TRUE(alloc != nullptr);
2802 ASSERT_STREQ("allocation", alloc->Name());
2803 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->QueryIntAttribute("nr", &val));
2804 ASSERT_EQ(2, val);
2805 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("size")->QueryIntText(&val));
2806 ASSERT_EQ(500, val);
2807 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("total")->QueryIntText(&val));
2808 ASSERT_EQ(1, val);
2809 }
2810
AllocPtrsWithBacktrace(std::vector<void * > * ptrs)2811 static void AllocPtrsWithBacktrace(std::vector<void*>* ptrs) {
2812 backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
2813 void* ptr = debug_malloc(1024);
2814 ASSERT_TRUE(ptr != nullptr);
2815 memset(ptr, 0, 1024);
2816 ptrs->push_back(ptr);
2817
2818 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002});
2819 ptr = debug_malloc(500);
2820 ASSERT_TRUE(ptr != nullptr);
2821 memset(ptr, 0, 500);
2822 ptrs->push_back(ptr);
2823
2824 backtrace_fake_add(std::vector<uintptr_t> {0x104});
2825 ptr = debug_malloc(100);
2826 ASSERT_TRUE(ptr != nullptr);
2827 memset(ptr, 0, 100);
2828 ptrs->push_back(ptr);
2829 }
2830
2831 static constexpr std::string_view kDumpInfo = R"(Android Native Heap Dump v1.2
2832
2833 Build fingerprint: ''
2834
2835 Total memory: 1624
2836 Allocation records: 3
2837 Backtrace size: 16
2838
2839 z 0 sz 1024 num 1 bt f e d c
2840 z 0 sz 500 num 1 bt bc000 bc001 bc002
2841 z 0 sz 100 num 1 bt 104
2842 MAPS
2843 MAP_DATA
2844 END)";
2845
TEST_F(MallocDebugTest,debug_write_malloc_leak_info)2846 TEST_F(MallocDebugTest, debug_write_malloc_leak_info) {
2847 Init("backtrace=16");
2848
2849 std::vector<void*> ptrs;
2850 AllocPtrsWithBacktrace(&ptrs);
2851
2852 TemporaryFile tf;
2853 ASSERT_TRUE(tf.fd != -1);
2854 close(tf.fd);
2855 tf.release();
2856 FILE* fp = fopen(tf.path, "w+");
2857 ASSERT_TRUE(fp != nullptr);
2858
2859 ASSERT_TRUE(debug_write_malloc_leak_info(fp));
2860
2861 fclose(fp);
2862
2863 for (auto ptr : ptrs) {
2864 debug_free(ptr);
2865 }
2866 ptrs.clear();
2867
2868 std::string expected(kDumpInfo);
2869
2870 std::string contents;
2871 ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
2872 contents = SanitizeHeapData(contents);
2873 ASSERT_EQ(expected, contents);
2874 ASSERT_STREQ("", getFakeLogBuf().c_str());
2875 ASSERT_STREQ("", getFakeLogPrint().c_str());
2876 }
2877
TEST_F(MallocDebugTest,debug_write_malloc_leak_info_extra_data)2878 TEST_F(MallocDebugTest, debug_write_malloc_leak_info_extra_data) {
2879 Init("backtrace=16");
2880
2881 std::vector<void*> ptrs;
2882 AllocPtrsWithBacktrace(&ptrs);
2883
2884 TemporaryFile tf;
2885 ASSERT_TRUE(tf.fd != -1);
2886 close(tf.fd);
2887 tf.release();
2888 FILE* fp = fopen(tf.path, "w+");
2889 ASSERT_TRUE(fp != nullptr);
2890
2891 fprintf(fp, "This message should appear before the output.\n");
2892 ASSERT_TRUE(debug_write_malloc_leak_info(fp));
2893 fprintf(fp, "This message should appear after the output.\n");
2894
2895 fclose(fp);
2896
2897 for (auto ptr : ptrs) {
2898 debug_free(ptr);
2899 }
2900 ptrs.clear();
2901
2902 std::string expected = "This message should appear before the output.\n"
2903 + std::string(kDumpInfo)
2904 + "\nThis message should appear after the output.";
2905
2906 std::string contents;
2907 ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
2908 contents = SanitizeHeapData(contents);
2909 ASSERT_EQ(expected, contents);
2910 ASSERT_STREQ("", getFakeLogBuf().c_str());
2911 ASSERT_STREQ("", getFakeLogPrint().c_str());
2912 }
2913
TEST_F(MallocDebugTest,dump_heap)2914 TEST_F(MallocDebugTest, dump_heap) {
2915 Init("backtrace=16");
2916
2917 std::vector<void*> ptrs;
2918 AllocPtrsWithBacktrace(&ptrs);
2919
2920 TemporaryFile tf;
2921 ASSERT_TRUE(tf.fd != -1);
2922 close(tf.fd);
2923 tf.release();
2924 debug_dump_heap(tf.path);
2925
2926 for (auto ptr : ptrs) {
2927 debug_free(ptr);
2928 }
2929 ptrs.clear();
2930
2931 std::string expected(kDumpInfo);
2932
2933 std::string contents;
2934 ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
2935 contents = SanitizeHeapData(contents);
2936 ASSERT_EQ(expected, contents);
2937 ASSERT_STREQ("", getFakeLogBuf().c_str());
2938 std::string expected_log = std::string("6 malloc_debug Dumping to file: ") + tf.path + "\n\n";
2939 ASSERT_EQ(expected_log, getFakeLogPrint());
2940 }
2941
LogUnreachableMemory(bool,size_t)2942 extern "C" bool LogUnreachableMemory(bool, size_t) {
2943 static bool return_value = false;
2944 return_value = !return_value;
2945 return return_value;
2946 }
2947
TEST_F(MallocDebugTest,check_unreachable_on_signal)2948 TEST_F(MallocDebugTest, check_unreachable_on_signal) {
2949 Init("check_unreachable_on_signal");
2950
2951 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 16) == 0);
2952 sleep(1);
2953
2954 // The first unreachable check will pass.
2955 void* pointer = debug_malloc(110);
2956 ASSERT_TRUE(pointer != nullptr);
2957
2958 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 16) == 0);
2959 sleep(1);
2960
2961 // The second unreachable check will fail.
2962 debug_free(pointer);
2963
2964 ASSERT_STREQ("", getFakeLogBuf().c_str());
2965 std::string expected_log = "4 malloc_debug Starting to check for unreachable memory.\n";
2966 ASSERT_STREQ(
2967 "4 malloc_debug Starting to check for unreachable memory.\n"
2968 "4 malloc_debug Starting to check for unreachable memory.\n"
2969 "6 malloc_debug Unreachable check failed, run setenforce 0 and try again.\n",
2970 getFakeLogPrint().c_str());
2971 }
2972
TEST_F(MallocDebugTest,log_allocator_stats_on_signal)2973 TEST_F(MallocDebugTest, log_allocator_stats_on_signal) {
2974 Init("log_allocator_stats_on_signal");
2975
2976 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 15) == 0);
2977 sleep(1);
2978
2979 // The first unreachable check will pass.
2980 void* pointer = debug_malloc(110);
2981 ASSERT_TRUE(pointer != nullptr);
2982 debug_free(pointer);
2983
2984 ASSERT_STREQ("", getFakeLogBuf().c_str());
2985 if (!running_with_hwasan()) {
2986 // Do an exact match because the mallopt should not fail in normal operation.
2987 ASSERT_STREQ("4 malloc_debug Logging allocator stats...\n", getFakeLogPrint().c_str());
2988 } else {
2989 // mallopt fails with hwasan, so just verify that the message is present.
2990 ASSERT_MATCH(getFakeLogPrint(), "4 malloc_debug Logging allocator stats...\\n");
2991 }
2992 }
2993
TEST_F(MallocDebugTest,log_allocator_stats_on_exit)2994 TEST_F(MallocDebugTest, log_allocator_stats_on_exit) {
2995 Init("log_allocator_stats_on_exit");
2996
2997 void* pointer = debug_malloc(110);
2998 ASSERT_TRUE(pointer != nullptr);
2999 debug_free(pointer);
3000
3001 debug_finalize();
3002
3003 ASSERT_STREQ("", getFakeLogBuf().c_str());
3004 if (!running_with_hwasan()) {
3005 // Do an exact match because the mallopt should not fail in normal operation.
3006 ASSERT_STREQ("4 malloc_debug Logging allocator stats...\n", getFakeLogPrint().c_str());
3007 } else {
3008 // mallopt fails with hwasan, so just verify that the message is present.
3009 ASSERT_MATCH(getFakeLogPrint(), "4 malloc_debug Logging allocator stats...\\n");
3010 }
3011 }
3012
TEST_F(MallocDebugTest,backtrace_only_some_sizes_with_backtrace_size)3013 TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_size) {
3014 Init("leak_track backtrace backtrace_size=120");
3015
3016 backtrace_fake_add(std::vector<uintptr_t>{0x1000, 0x2000, 0x3000});
3017
3018 void* pointer1 = debug_malloc(119);
3019 ASSERT_TRUE(pointer1 != nullptr);
3020
3021 backtrace_fake_add(std::vector<uintptr_t>{0xa000, 0xb000, 0xc000, 0xd000});
3022
3023 void* pointer2 = debug_malloc(120);
3024 ASSERT_TRUE(pointer2 != nullptr);
3025
3026 backtrace_fake_add(std::vector<uintptr_t>{0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
3027
3028 void* pointer3 = debug_malloc(121);
3029 ASSERT_TRUE(pointer3 != nullptr);
3030
3031 debug_finalize();
3032 initialized = false;
3033
3034 ASSERT_STREQ("", getFakeLogBuf().c_str());
3035 std::string expected_log = android::base::StringPrintf(
3036 "6 malloc_debug +++ malloc_testing leaked block of size 121 at %p (leak 1 of 3)\n", pointer3);
3037
3038 expected_log += android::base::StringPrintf(
3039 "6 malloc_debug +++ malloc_testing leaked block of size 120 at %p (leak 2 of 3)\n", pointer2);
3040 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
3041 expected_log += "6 malloc_debug #00 pc 0x1000\n";
3042 expected_log += "6 malloc_debug #01 pc 0x2000\n";
3043 expected_log += "6 malloc_debug #02 pc 0x3000\n";
3044
3045 expected_log += android::base::StringPrintf(
3046 "6 malloc_debug +++ malloc_testing leaked block of size 119 at %p (leak 3 of 3)\n", pointer1);
3047 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
3048 }
3049
TEST_F(MallocDebugTest,backtrace_only_some_sizes_with_backtrace_min_size)3050 TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_min_size) {
3051 Init("leak_track backtrace backtrace_min_size=1000");
3052
3053 backtrace_fake_add(std::vector<uintptr_t>{0x1000, 0x2000, 0x3000});
3054
3055 void* pointer1 = debug_malloc(500);
3056 ASSERT_TRUE(pointer1 != nullptr);
3057
3058 backtrace_fake_add(std::vector<uintptr_t>{0xa000, 0xb000, 0xc000, 0xd000});
3059
3060 void* pointer2 = debug_malloc(1000);
3061 ASSERT_TRUE(pointer2 != nullptr);
3062
3063 backtrace_fake_add(std::vector<uintptr_t>{0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
3064
3065 void* pointer3 = debug_malloc(1001);
3066 ASSERT_TRUE(pointer3 != nullptr);
3067
3068 debug_finalize();
3069 initialized = false;
3070
3071 ASSERT_STREQ("", getFakeLogBuf().c_str());
3072 std::string expected_log = android::base::StringPrintf(
3073 "6 malloc_debug +++ malloc_testing leaked block of size 1001 at %p (leak 1 of 3)\n",
3074 pointer3);
3075 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
3076 expected_log += "6 malloc_debug #00 pc 0xa000\n";
3077 expected_log += "6 malloc_debug #01 pc 0xb000\n";
3078 expected_log += "6 malloc_debug #02 pc 0xc000\n";
3079 expected_log += "6 malloc_debug #03 pc 0xd000\n";
3080
3081 expected_log += android::base::StringPrintf(
3082 "6 malloc_debug +++ malloc_testing leaked block of size 1000 at %p (leak 2 of 3)\n",
3083 pointer2);
3084 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
3085 expected_log += "6 malloc_debug #00 pc 0x1000\n";
3086 expected_log += "6 malloc_debug #01 pc 0x2000\n";
3087 expected_log += "6 malloc_debug #02 pc 0x3000\n";
3088
3089 expected_log += android::base::StringPrintf(
3090 "6 malloc_debug +++ malloc_testing leaked block of size 500 at %p (leak 3 of 3)\n", pointer1);
3091 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
3092 }
3093
TEST_F(MallocDebugTest,backtrace_only_some_sizes_with_backtrace_max_size)3094 TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_max_size) {
3095 Init("leak_track backtrace backtrace_max_size=1000");
3096
3097 backtrace_fake_add(std::vector<uintptr_t>{0x1000, 0x2000, 0x3000});
3098
3099 void* pointer1 = debug_malloc(1000);
3100 ASSERT_TRUE(pointer1 != nullptr);
3101
3102 backtrace_fake_add(std::vector<uintptr_t>{0xa000, 0xb000, 0xc000, 0xd000});
3103
3104 void* pointer2 = debug_malloc(1001);
3105 ASSERT_TRUE(pointer2 != nullptr);
3106
3107 backtrace_fake_add(std::vector<uintptr_t>{0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
3108
3109 void* pointer3 = debug_malloc(5000);
3110 ASSERT_TRUE(pointer3 != nullptr);
3111
3112 debug_finalize();
3113 initialized = false;
3114
3115 ASSERT_STREQ("", getFakeLogBuf().c_str());
3116 std::string expected_log = android::base::StringPrintf(
3117 "6 malloc_debug +++ malloc_testing leaked block of size 5000 at %p (leak 1 of 3)\n",
3118 pointer3);
3119
3120 expected_log += android::base::StringPrintf(
3121 "6 malloc_debug +++ malloc_testing leaked block of size 1001 at %p (leak 2 of 3)\n",
3122 pointer2);
3123
3124 expected_log += android::base::StringPrintf(
3125 "6 malloc_debug +++ malloc_testing leaked block of size 1000 at %p (leak 3 of 3)\n",
3126 pointer1);
3127 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
3128 expected_log += "6 malloc_debug #00 pc 0x1000\n";
3129 expected_log += "6 malloc_debug #01 pc 0x2000\n";
3130 expected_log += "6 malloc_debug #02 pc 0x3000\n";
3131
3132 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
3133 }
3134
TEST_F(MallocDebugTest,backtrace_only_some_sizes_with_backtrace_min_max_size)3135 TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_min_max_size) {
3136 Init("leak_track backtrace backtrace_min_size=50 backtrace_max_size=1000");
3137
3138 backtrace_fake_add(std::vector<uintptr_t>{0x1000, 0x2000, 0x3000});
3139
3140 void* pointer1 = debug_malloc(49);
3141 ASSERT_TRUE(pointer1 != nullptr);
3142
3143 backtrace_fake_add(std::vector<uintptr_t>{0xa000, 0xb000, 0xc000, 0xd000});
3144
3145 void* pointer2 = debug_malloc(50);
3146 ASSERT_TRUE(pointer2 != nullptr);
3147
3148 backtrace_fake_add(std::vector<uintptr_t>{0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
3149
3150 void* pointer3 = debug_malloc(1000);
3151 ASSERT_TRUE(pointer3 != nullptr);
3152
3153 backtrace_fake_add(std::vector<uintptr_t>{0x1a000, 0x1b000, 0x1c000, 0x1d000, 0x1e000});
3154
3155 void* pointer4 = debug_malloc(1001);
3156 ASSERT_TRUE(pointer4 != nullptr);
3157
3158 debug_finalize();
3159 initialized = false;
3160
3161 ASSERT_STREQ("", getFakeLogBuf().c_str());
3162 std::string expected_log = android::base::StringPrintf(
3163 "6 malloc_debug +++ malloc_testing leaked block of size 1001 at %p (leak 1 of 4)\n",
3164 pointer4);
3165
3166 expected_log += android::base::StringPrintf(
3167 "6 malloc_debug +++ malloc_testing leaked block of size 1000 at %p (leak 2 of 4)\n",
3168 pointer3);
3169 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
3170 expected_log += "6 malloc_debug #00 pc 0xa000\n";
3171 expected_log += "6 malloc_debug #01 pc 0xb000\n";
3172 expected_log += "6 malloc_debug #02 pc 0xc000\n";
3173 expected_log += "6 malloc_debug #03 pc 0xd000\n";
3174
3175 expected_log += android::base::StringPrintf(
3176 "6 malloc_debug +++ malloc_testing leaked block of size 50 at %p (leak 3 of 4)\n", pointer2);
3177 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
3178 expected_log += "6 malloc_debug #00 pc 0x1000\n";
3179 expected_log += "6 malloc_debug #01 pc 0x2000\n";
3180 expected_log += "6 malloc_debug #02 pc 0x3000\n";
3181
3182 expected_log += android::base::StringPrintf(
3183 "6 malloc_debug +++ malloc_testing leaked block of size 49 at %p (leak 4 of 4)\n", pointer1);
3184
3185 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
3186 }
3187