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