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