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