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