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