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