• 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 <stdlib.h>
20 #include <string.h>
21 #include <sys/cdefs.h>
22 #include <sys/param.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #include <algorithm>
27 #include <thread>
28 #include <vector>
29 #include <utility>
30 
31 #include <gtest/gtest.h>
32 
33 #include <android-base/stringprintf.h>
34 
35 #include <private/bionic_macros.h>
36 #include <private/bionic_malloc_dispatch.h>
37 
38 #include "Config.h"
39 #include "malloc_debug.h"
40 
41 #include "log_fake.h"
42 #include "backtrace_fake.h"
43 
44 __BEGIN_DECLS
45 
46 int property_set(const char*, const char*);
47 bool debug_initialize(const MallocDispatch*, int*);
48 void debug_finalize();
49 
50 void* debug_malloc(size_t);
51 void debug_free(void*);
52 void* debug_calloc(size_t, size_t);
53 void* debug_realloc(void*, size_t);
54 int debug_posix_memalign(void**, size_t, size_t);
55 void* debug_memalign(size_t, size_t);
56 size_t debug_malloc_usable_size(void*);
57 void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
58 void debug_free_malloc_leak_info(uint8_t*);
59 
60 struct mallinfo debug_mallinfo();
61 
62 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
63 void* debug_pvalloc(size_t);
64 void* debug_valloc(size_t);
65 #endif
66 
67 __END_DECLS
68 
69 constexpr char DIVIDER[] =
70     "6 malloc_debug *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n";
71 
72 constexpr uint32_t BACKTRACE_HEADER = 0x1;
73 
get_tag_offset(uint32_t flags=0,size_t backtrace_frames=0)74 static size_t get_tag_offset(uint32_t flags = 0, size_t backtrace_frames = 0) {
75   size_t offset = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
76   if (flags & BACKTRACE_HEADER) {
77     offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames, MINIMUM_ALIGNMENT_BYTES);
78   }
79   return offset;
80 }
81 
82 class MallocDebugTest : public ::testing::Test {
83  protected:
SetUp()84   void SetUp() override {
85     initialized = false;
86     resetLogs();
87     backtrace_fake_clear_all();
88   }
89 
TearDown()90   void TearDown() override {
91     if (initialized) {
92       debug_finalize();
93     }
94   }
95 
Init(const char * property_value)96   void Init(const char* property_value) {
97     property_set("libc.debug.malloc.options", property_value);
98     zygote = 0;
99     ASSERT_TRUE(debug_initialize(&dispatch, &zygote));
100     initialized = true;
101   }
102 
103   bool initialized;
104 
105   int zygote;
106 
107   static MallocDispatch dispatch;
108 };
109 
110 MallocDispatch MallocDebugTest::dispatch = {
111   calloc,
112   free,
113   mallinfo,
114   malloc,
115   malloc_usable_size,
116   memalign,
117   posix_memalign,
118 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
119   nullptr,
120 #endif
121   realloc,
122 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
123   nullptr,
124 #endif
125   nullptr,
126   nullptr,
127   nullptr,
128 };
129 
VerifyAllocCalls()130 void VerifyAllocCalls() {
131   size_t alloc_size = 1024;
132 
133   // Verify debug_malloc.
134   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(alloc_size));
135   ASSERT_TRUE(pointer != nullptr);
136   for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
137     ASSERT_EQ(0xeb, pointer[i]);
138   }
139   debug_free(pointer);
140 
141   // Verify debug_calloc.
142   pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, alloc_size));
143   ASSERT_TRUE(pointer != nullptr);
144   for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
145     ASSERT_EQ(0, pointer[i]) << "Failed at byte " << i;
146   }
147   debug_free(pointer);
148 
149   pointer = reinterpret_cast<uint8_t*>(debug_memalign(128, alloc_size));
150   ASSERT_TRUE(pointer != nullptr);
151   for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
152     ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
153   }
154   debug_free(pointer);
155 
156   pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, alloc_size));
157   ASSERT_TRUE(pointer != nullptr);
158   for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
159     ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
160   }
161   memset(pointer, 0xff, alloc_size);
162   // Increase the size, verify the extra length is initialized to 0xeb,
163   // but the rest is 0xff.
164   pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size * 2));
165   ASSERT_TRUE(pointer != nullptr);
166   for (size_t i = 0; i < alloc_size; i++) {
167     ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
168   }
169   for (size_t i = alloc_size; i < debug_malloc_usable_size(pointer); i++) {
170     ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
171   }
172   memset(pointer, 0xff, debug_malloc_usable_size(pointer));
173   // Shrink the size and verify nothing changes.
174   pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size));
175   ASSERT_TRUE(pointer != nullptr);
176   for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
177     ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
178   }
179   // This should free the pointer.
180   pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
181   ASSERT_TRUE(pointer == nullptr);
182 
183   ASSERT_STREQ("", getFakeLogBuf().c_str());
184   ASSERT_STREQ("", getFakeLogPrint().c_str());
185 }
186 
TEST_F(MallocDebugTest,fill_generic)187 TEST_F(MallocDebugTest, fill_generic) {
188   Init("fill");
189   VerifyAllocCalls();
190 }
191 
TEST_F(MallocDebugTest,fill_on_alloc_generic)192 TEST_F(MallocDebugTest, fill_on_alloc_generic) {
193   Init("fill_on_alloc");
194   VerifyAllocCalls();
195 }
196 
TEST_F(MallocDebugTest,fill_on_alloc_partial)197 TEST_F(MallocDebugTest, fill_on_alloc_partial) {
198   Init("fill_on_alloc=25");
199 
200   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
201   ASSERT_TRUE(pointer != nullptr);
202   for (size_t i = 0; i < 25; i++) {
203     ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
204   }
205   debug_free(pointer);
206 
207   ASSERT_STREQ("", getFakeLogBuf().c_str());
208   ASSERT_STREQ("", getFakeLogPrint().c_str());
209 }
210 
TEST_F(MallocDebugTest,fill_on_free)211 TEST_F(MallocDebugTest, fill_on_free) {
212   Init("fill_on_free free_track free_track_backtrace_num_frames=0");
213 
214   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
215   ASSERT_TRUE(pointer != nullptr);
216   size_t usable_size = debug_malloc_usable_size(pointer);
217   memset(pointer, 0, usable_size);
218   debug_free(pointer);
219 
220   for (size_t i = 0; i < usable_size; i++) {
221     ASSERT_EQ(0xef, pointer[i]) << "Failed at byte " << i;
222   }
223 
224   ASSERT_STREQ("", getFakeLogBuf().c_str());
225   ASSERT_STREQ("", getFakeLogPrint().c_str());
226 }
227 
TEST_F(MallocDebugTest,fill_on_free_partial)228 TEST_F(MallocDebugTest, fill_on_free_partial) {
229   Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
230 
231   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
232   ASSERT_TRUE(pointer != nullptr);
233   size_t usable_size = debug_malloc_usable_size(pointer);
234   memset(pointer, 0, usable_size);
235   debug_free(pointer);
236 
237   for (size_t i = 0; i < 30; i++) {
238     ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
239   }
240   for (size_t i = 30; i < usable_size; i++) {
241     ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
242   }
243 
244   ASSERT_STREQ("", getFakeLogBuf().c_str());
245   ASSERT_STREQ("", getFakeLogPrint().c_str());
246 }
247 
TEST_F(MallocDebugTest,free_track_partial)248 TEST_F(MallocDebugTest, free_track_partial) {
249   Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
250 
251   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
252   ASSERT_TRUE(pointer != nullptr);
253   size_t usable_size = debug_malloc_usable_size(pointer);
254   memset(pointer, 0, usable_size);
255   debug_free(pointer);
256 
257   for (size_t i = 0; i < 30; i++) {
258     ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
259   }
260   for (size_t i = 30; i < usable_size; i++) {
261     ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
262   }
263 
264   debug_finalize();
265   initialized = false;
266 
267   ASSERT_STREQ("", getFakeLogBuf().c_str());
268   ASSERT_STREQ("", getFakeLogPrint().c_str());
269 }
270 
TEST_F(MallocDebugTest,all_options)271 TEST_F(MallocDebugTest, all_options) {
272   Init("guard backtrace fill expand_alloc free_track leak_track");
273   VerifyAllocCalls();
274 }
275 
TEST_F(MallocDebugTest,expand_alloc)276 TEST_F(MallocDebugTest, expand_alloc) {
277   Init("expand_alloc=1024");
278 
279   void* pointer = debug_malloc(10);
280   ASSERT_TRUE(pointer != nullptr);
281   ASSERT_LE(1034U, debug_malloc_usable_size(pointer));
282   debug_free(pointer);
283 
284   pointer = debug_calloc(1, 20);
285   ASSERT_TRUE(pointer != nullptr);
286   ASSERT_LE(1044U, debug_malloc_usable_size(pointer));
287   debug_free(pointer);
288 
289   pointer = debug_memalign(128, 15);
290   ASSERT_TRUE(pointer != nullptr);
291   ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
292   debug_free(pointer);
293 
294   pointer = debug_realloc(nullptr, 30);
295   ASSERT_TRUE(pointer != nullptr);
296   ASSERT_LE(1054U, debug_malloc_usable_size(pointer));
297   pointer = debug_realloc(pointer, 100);
298   ASSERT_LE(1124U, debug_malloc_usable_size(pointer));
299   debug_free(pointer);
300 
301   ASSERT_STREQ("", getFakeLogBuf().c_str());
302   ASSERT_STREQ("", getFakeLogPrint().c_str());
303 }
304 
TEST_F(MallocDebugTest,front_guard)305 TEST_F(MallocDebugTest, front_guard) {
306   Init("front_guard=32");
307 
308   // Create a buffer for doing comparisons.
309   std::vector<uint8_t> buffer(32);
310   memset(buffer.data(), 0xaa, buffer.size());
311 
312   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
313   ASSERT_TRUE(pointer != nullptr);
314   ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
315   memset(pointer, 0xff, 100);
316   debug_free(pointer);
317 
318   // Loop through a bunch alignments.
319   for (size_t alignment = 1; alignment <= 256; alignment++) {
320     pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
321     ASSERT_TRUE(pointer != nullptr);
322     ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
323     size_t alignment_mask = alignment - 1;
324     if (!powerof2(alignment)) {
325       alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
326     }
327     ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask);
328     memset(pointer, 0xff, 100);
329     debug_free(pointer);
330   }
331 
332   pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
333   ASSERT_TRUE(pointer != nullptr);
334   ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
335   for (size_t i = 0; i < 100; i++) {
336     ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
337   }
338   debug_free(pointer);
339 
340   pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
341   ASSERT_TRUE(pointer != nullptr);
342   ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
343   memset(pointer, 0xff, 100);
344   pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
345   ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
346   memset(pointer, 0xff, 200);
347   pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
348   ASSERT_TRUE(pointer == nullptr);
349 
350   ASSERT_STREQ("", getFakeLogBuf().c_str());
351   ASSERT_STREQ("", getFakeLogPrint().c_str());
352 }
353 
TEST_F(MallocDebugTest,realloc_memalign_memory)354 TEST_F(MallocDebugTest, realloc_memalign_memory) {
355   Init("rear_guard");
356 
357   void* pointer = debug_memalign(1024, 100);
358   ASSERT_TRUE(pointer != nullptr);
359   memset(pointer, 0, 100);
360 
361   pointer = debug_realloc(pointer, 1024);
362   ASSERT_TRUE(pointer != nullptr);
363   ASSERT_EQ(1024U, debug_malloc_usable_size(pointer));
364   memset(pointer, 0, 1024);
365   debug_free(pointer);
366 
367   ASSERT_STREQ("", getFakeLogBuf().c_str());
368   ASSERT_STREQ("", getFakeLogPrint().c_str());
369 }
370 
TEST_F(MallocDebugTest,front_guard_corrupted)371 TEST_F(MallocDebugTest, front_guard_corrupted) {
372   Init("front_guard=32");
373 
374   backtrace_fake_add(std::vector<uintptr_t> {0x1, 0x2, 0x3});
375 
376   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
377   ASSERT_TRUE(pointer != nullptr);
378   pointer[-32] = 0x00;
379   pointer[-15] = 0x02;
380   debug_free(pointer);
381 
382   std::string expected_log(DIVIDER);
383   expected_log += android::base::StringPrintf(
384       "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED FRONT GUARD\n", pointer);
385   expected_log += "6 malloc_debug   allocation[-32] = 0x00 (expected 0xaa)\n";
386   expected_log += "6 malloc_debug   allocation[-15] = 0x02 (expected 0xaa)\n";
387   expected_log += "6 malloc_debug Backtrace at time of failure:\n";
388   expected_log += "6 malloc_debug   #00 pc 0x1\n";
389   expected_log += "6 malloc_debug   #01 pc 0x2\n";
390   expected_log += "6 malloc_debug   #02 pc 0x3\n";
391   expected_log += DIVIDER;
392   ASSERT_STREQ("", getFakeLogBuf().c_str());
393   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
394 }
395 
TEST_F(MallocDebugTest,rear_guard)396 TEST_F(MallocDebugTest, rear_guard) {
397   Init("rear_guard=32");
398 
399   // Create a buffer for doing comparisons.
400   std::vector<uint8_t> buffer(32);
401   memset(buffer.data(), 0xbb, buffer.size());
402 
403   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
404   ASSERT_TRUE(pointer != nullptr);
405   ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
406   ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
407   memset(pointer, 0xff, 100);
408   debug_free(pointer);
409 
410   // Loop through a bunch alignments.
411   for (size_t alignment = 1; alignment <= 256; alignment++) {
412     pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
413     ASSERT_TRUE(pointer != nullptr);
414     ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
415     ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
416     size_t alignment_mask = alignment - 1;
417     if (!powerof2(alignment)) {
418       alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
419     }
420     ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask)
421         << "Failed at alignment " << alignment << " mask " << alignment_mask;
422     memset(pointer, 0xff, 100);
423     debug_free(pointer);
424   }
425 
426   pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
427   ASSERT_TRUE(pointer != nullptr);
428   ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
429   ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
430   for (size_t i = 0; i < 100; i++) {
431     ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
432   }
433   debug_free(pointer);
434 
435   pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
436   ASSERT_TRUE(pointer != nullptr);
437   ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
438   memset(pointer, 0xff, 100);
439   pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
440   ASSERT_TRUE(memcmp(buffer.data(), &pointer[200], buffer.size()) == 0);
441   for (size_t i = 0; i < 100; i++) {
442     ASSERT_EQ(0xff, pointer[i]) << "debug_realloc not copied byte at " << i;
443   }
444   memset(pointer, 0xff, 200);
445   pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
446   ASSERT_TRUE(pointer == nullptr);
447 
448   ASSERT_STREQ("", getFakeLogBuf().c_str());
449   ASSERT_STREQ("", getFakeLogPrint().c_str());
450 }
451 
TEST_F(MallocDebugTest,rear_guard_corrupted)452 TEST_F(MallocDebugTest, rear_guard_corrupted) {
453   Init("rear_guard=32");
454 
455   backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
456 
457   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
458   ASSERT_TRUE(pointer != nullptr);
459   pointer[130] = 0xbf;
460   pointer[131] = 0x00;
461   debug_free(pointer);
462 
463   std::string expected_log(DIVIDER);
464   expected_log += android::base::StringPrintf(
465       "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
466   expected_log += "6 malloc_debug   allocation[130] = 0xbf (expected 0xbb)\n";
467   expected_log += "6 malloc_debug   allocation[131] = 0x00 (expected 0xbb)\n";
468   expected_log += "6 malloc_debug Backtrace at time of failure:\n";
469   expected_log += "6 malloc_debug   #00 pc 0x100\n";
470   expected_log += "6 malloc_debug   #01 pc 0x200\n";
471   expected_log += "6 malloc_debug   #02 pc 0x300\n";
472   expected_log += DIVIDER;
473 
474   ASSERT_STREQ("", getFakeLogBuf().c_str());
475   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
476 }
477 
TEST_F(MallocDebugTest,rear_guard_corrupted_after_realloc_shrink)478 TEST_F(MallocDebugTest, rear_guard_corrupted_after_realloc_shrink) {
479   Init("rear_guard=32");
480 
481   backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
482 
483   void* pointer = debug_malloc(200);
484   ASSERT_TRUE(pointer != nullptr);
485   memset(pointer, 0, 200);
486 
487   uint8_t* pointer_shrink = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 100));
488   pointer_shrink[130] = 0xbf;
489   pointer_shrink[131] = 0x00;
490   debug_free(pointer);
491 
492   // When shrinking sizes, the same pointer should be returned.
493   ASSERT_EQ(pointer, pointer_shrink);
494 
495   std::string expected_log(DIVIDER);
496   expected_log += android::base::StringPrintf(
497       "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
498   expected_log += "6 malloc_debug   allocation[130] = 0xbf (expected 0xbb)\n";
499   expected_log += "6 malloc_debug   allocation[131] = 0x00 (expected 0xbb)\n";
500   expected_log += "6 malloc_debug Backtrace at time of failure:\n";
501   expected_log += "6 malloc_debug   #00 pc 0x100\n";
502   expected_log += "6 malloc_debug   #01 pc 0x200\n";
503   expected_log += "6 malloc_debug   #02 pc 0x300\n";
504   expected_log += DIVIDER;
505 
506   ASSERT_STREQ("", getFakeLogBuf().c_str());
507   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
508 }
509 
TEST_F(MallocDebugTest,tag_corrupted)510 TEST_F(MallocDebugTest, tag_corrupted) {
511   Init("rear_guard=32");
512 
513   backtrace_fake_add(std::vector<uintptr_t> {0xa, 0xb, 0xc});
514 
515   backtrace_fake_add(std::vector<uintptr_t> {0xaa, 0xbb, 0xcc});
516 
517   backtrace_fake_add(std::vector<uintptr_t> {0xaaa, 0xbbb, 0xccc});
518 
519   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
520   ASSERT_TRUE(pointer != nullptr);
521   uint8_t saved = pointer[-get_tag_offset()];
522   pointer[-get_tag_offset()] = 0x00;
523   ASSERT_EQ(0U, debug_malloc_usable_size(pointer));
524   ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
525   debug_free(pointer);
526 
527   // Fix the pointer and really free it.
528   pointer[-get_tag_offset()] = saved;
529   debug_free(pointer);
530 
531   std::string expected_log(DIVIDER);
532   expected_log += android::base::StringPrintf(
533       "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (malloc_usable_size)\n",
534       pointer);
535   expected_log += "6 malloc_debug Backtrace at time of failure:\n";
536   expected_log += "6 malloc_debug   #00 pc 0xa\n";
537   expected_log += "6 malloc_debug   #01 pc 0xb\n";
538   expected_log += "6 malloc_debug   #02 pc 0xc\n";
539   expected_log += DIVIDER;
540 
541   expected_log += DIVIDER;
542   expected_log += android::base::StringPrintf(
543       "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (realloc)\n",
544       pointer);
545   expected_log += "6 malloc_debug Backtrace at time of failure:\n";
546   expected_log += "6 malloc_debug   #00 pc 0xaa\n";
547   expected_log += "6 malloc_debug   #01 pc 0xbb\n";
548   expected_log += "6 malloc_debug   #02 pc 0xcc\n";
549   expected_log += DIVIDER;
550 
551   expected_log += DIVIDER;
552   expected_log += android::base::StringPrintf(
553       "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (free)\n",
554       pointer);
555   expected_log += "6 malloc_debug Backtrace at time of failure:\n";
556   expected_log += "6 malloc_debug   #00 pc 0xaaa\n";
557   expected_log += "6 malloc_debug   #01 pc 0xbbb\n";
558   expected_log += "6 malloc_debug   #02 pc 0xccc\n";
559   expected_log += DIVIDER;
560 
561   ASSERT_STREQ("", getFakeLogBuf().c_str());
562   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
563 }
564 
TEST_F(MallocDebugTest,leak_track_no_frees)565 TEST_F(MallocDebugTest, leak_track_no_frees) {
566   Init("leak_track");
567 
568   void* pointer1 = debug_malloc(200);
569   ASSERT_TRUE(pointer1 != nullptr);
570   memset(pointer1, 0, 200);
571 
572   void* pointer2 = debug_malloc(128);
573   ASSERT_TRUE(pointer2 != nullptr);
574   memset(pointer2, 0, 128);
575 
576   void* pointer3 = debug_malloc(1024);
577   ASSERT_TRUE(pointer3 != nullptr);
578   memset(pointer3, 0, 1024);
579 
580   debug_finalize();
581   initialized = false;
582 
583   ASSERT_STREQ("", getFakeLogBuf().c_str());
584   std::string expected_log = android::base::StringPrintf(
585         "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
586       pointer3);
587   expected_log += android::base::StringPrintf(
588         "6 malloc_debug +++ malloc_testing leaked block of size 200 at %p (leak 2 of 3)\n",
589       pointer1);
590   expected_log += android::base::StringPrintf(
591         "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 3 of 3)\n",
592       pointer2);
593   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
594 }
595 
TEST_F(MallocDebugTest,leak_track_no_frees_with_backtrace)596 TEST_F(MallocDebugTest, leak_track_no_frees_with_backtrace) {
597   Init("leak_track backtrace");
598 
599   backtrace_fake_add(std::vector<uintptr_t> {0x1000, 0x2000, 0x3000});
600 
601   void* pointer1 = debug_malloc(100);
602   ASSERT_TRUE(pointer1 != nullptr);
603   memset(pointer1, 0, 100);
604 
605   backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000, 0xc000, 0xd000});
606 
607   void* pointer2 = debug_malloc(128);
608   ASSERT_TRUE(pointer2 != nullptr);
609   memset(pointer2, 0, 128);
610 
611   backtrace_fake_add(std::vector<uintptr_t> {0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
612 
613   void* pointer3 = debug_malloc(1024);
614   ASSERT_TRUE(pointer3 != nullptr);
615   memset(pointer3, 0, 1024);
616 
617   debug_finalize();
618   initialized = false;
619 
620   ASSERT_STREQ("", getFakeLogBuf().c_str());
621   std::string expected_log = android::base::StringPrintf(
622       "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
623       pointer3);
624   expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
625   expected_log += "6 malloc_debug   #00 pc 0xfe000\n";
626   expected_log += "6 malloc_debug   #01 pc 0xde000\n";
627   expected_log += "6 malloc_debug   #02 pc 0xce000\n";
628   expected_log += "6 malloc_debug   #03 pc 0xbe000\n";
629   expected_log += "6 malloc_debug   #04 pc 0xae000\n";
630 
631   expected_log += android::base::StringPrintf(
632       "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 2 of 3)\n",
633       pointer2);
634   expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
635   expected_log += "6 malloc_debug   #00 pc 0xa000\n";
636   expected_log += "6 malloc_debug   #01 pc 0xb000\n";
637   expected_log += "6 malloc_debug   #02 pc 0xc000\n";
638   expected_log += "6 malloc_debug   #03 pc 0xd000\n";
639 
640   expected_log += android::base::StringPrintf(
641       "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 3 of 3)\n",
642       pointer1);
643   expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
644   expected_log += "6 malloc_debug   #00 pc 0x1000\n";
645   expected_log += "6 malloc_debug   #01 pc 0x2000\n";
646   expected_log += "6 malloc_debug   #02 pc 0x3000\n";
647 
648   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
649 }
650 
TEST_F(MallocDebugTest,leak_track_frees)651 TEST_F(MallocDebugTest, leak_track_frees) {
652   Init("leak_track");
653 
654   void* pointer1 = debug_malloc(390);
655   ASSERT_TRUE(pointer1 != nullptr);
656   memset(pointer1, 0, 390);
657   debug_free(pointer1);
658 
659   pointer1 = debug_malloc(100);
660   ASSERT_TRUE(pointer1 != nullptr);
661   memset(pointer1, 0, 100);
662 
663   void* pointer2 = debug_malloc(250);
664   ASSERT_TRUE(pointer2 != nullptr);
665   memset(pointer2, 0, 250);
666   debug_free(pointer2);
667 
668   pointer2 = debug_malloc(450);
669   ASSERT_TRUE(pointer2 != nullptr);
670   memset(pointer2, 0, 450);
671 
672   void* pointer3 = debug_malloc(999);
673   ASSERT_TRUE(pointer3 != nullptr);
674   memset(pointer3, 0, 999);
675   debug_free(pointer2);
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 999 at %p (leak 1 of 2)\n",
683       pointer3);
684   expected_log += android::base::StringPrintf(
685       "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 2 of 2)\n",
686       pointer1);
687   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
688 }
689 
TEST_F(MallocDebugTest,free_track)690 TEST_F(MallocDebugTest, free_track) {
691   Init("free_track=5 free_track_backtrace_num_frames=0");
692 
693   void* pointers[10];
694   for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
695     pointers[i] = debug_malloc(100 + i);
696     ASSERT_TRUE(pointers[i] != nullptr);
697     memset(pointers[i], 0, 100 + i);
698     debug_free(pointers[i]);
699   }
700 
701   // Large allocations (> 4096) to verify large allocation checks.
702   void* pointer = debug_malloc(8192);
703   ASSERT_TRUE(pointer != nullptr);
704   memset(pointer, 0, 8192);
705   debug_free(pointer);
706 
707   pointer = debug_malloc(9000);
708   ASSERT_TRUE(pointer != nullptr);
709   memset(pointer, 0, 9000);
710   debug_free(pointer);
711 
712   ASSERT_STREQ("", getFakeLogBuf().c_str());
713   ASSERT_STREQ("", getFakeLogPrint().c_str());
714 }
715 
TEST_F(MallocDebugTest,free_track_use_after_free)716 TEST_F(MallocDebugTest, free_track_use_after_free) {
717   Init("free_track=5 free_track_backtrace_num_frames=0");
718 
719   uint8_t* pointers[5];
720   for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
721     pointers[i] = reinterpret_cast<uint8_t*>(debug_malloc(100 + i));
722     ASSERT_TRUE(pointers[i] != nullptr);
723     memset(pointers[i], 0, 100 + i);
724     debug_free(pointers[i]);
725   }
726 
727   // Stomp on the data.
728   pointers[0][20] = 0xaf;
729   pointers[0][99] = 0x12;
730 
731   pointers[3][3] = 0x34;
732 
733   // Large allocations (> 4096) to verify large allocation checks.
734   uint8_t* pointer1_large = reinterpret_cast<uint8_t*>(debug_malloc(8192));
735   ASSERT_TRUE(pointer1_large != nullptr);
736   memset(pointer1_large, 0, 8192);
737   debug_free(pointer1_large);
738 
739   pointer1_large[4095] = 0x90;
740   pointer1_large[4100] = 0x56;
741   pointer1_large[8191] = 0x89;
742 
743   uint8_t* pointer2_large = reinterpret_cast<uint8_t*>(debug_malloc(9000));
744   ASSERT_TRUE(pointer2_large != nullptr);
745   memset(pointer2_large, 0, 9000);
746   debug_free(pointer2_large);
747 
748   pointer2_large[8200] = 0x78;
749 
750   // Do a bunch of alloc and free to verify the above frees are checked.
751   for (size_t i = 0; i < 10; i++) {
752     void* flush_pointer = debug_malloc(100+i);
753     ASSERT_TRUE(flush_pointer != nullptr);
754     memset(flush_pointer, 0, 100 + i);
755     debug_free(flush_pointer);
756   }
757 
758   ASSERT_STREQ("", getFakeLogBuf().c_str());
759   std::string expected_log(DIVIDER);
760   expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[0]);
761   expected_log += "6 malloc_debug   allocation[20] = 0xaf (expected 0xef)\n";
762   expected_log += "6 malloc_debug   allocation[99] = 0x12 (expected 0xef)\n";
763   expected_log += DIVIDER;
764   expected_log += DIVIDER;
765   expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[3]);
766   expected_log += "6 malloc_debug   allocation[3] = 0x34 (expected 0xef)\n";
767   expected_log += DIVIDER;
768   expected_log += DIVIDER;
769   expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer1_large);
770   expected_log += "6 malloc_debug   allocation[4095] = 0x90 (expected 0xef)\n";
771   expected_log += "6 malloc_debug   allocation[4100] = 0x56 (expected 0xef)\n";
772   expected_log += "6 malloc_debug   allocation[8191] = 0x89 (expected 0xef)\n";
773   expected_log += DIVIDER;
774   expected_log += DIVIDER;
775   expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer2_large);
776   expected_log += "6 malloc_debug   allocation[8200] = 0x78 (expected 0xef)\n";
777   expected_log += DIVIDER;
778   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
779 }
780 
TEST_F(MallocDebugTest,free_track_use_after_free_finalize)781 TEST_F(MallocDebugTest, free_track_use_after_free_finalize) {
782   Init("free_track=100 free_track_backtrace_num_frames=0");
783 
784   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
785   ASSERT_TRUE(pointer != nullptr);
786   memset(pointer, 0, 100);
787   debug_free(pointer);
788 
789   pointer[56] = 0x91;
790 
791   ASSERT_STREQ("", getFakeLogBuf().c_str());
792   ASSERT_STREQ("", getFakeLogPrint().c_str());
793 
794   debug_finalize();
795   initialized = false;
796 
797   ASSERT_STREQ("", getFakeLogBuf().c_str());
798   std::string expected_log(DIVIDER);
799   expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
800   expected_log += "6 malloc_debug   allocation[56] = 0x91 (expected 0xef)\n";
801   expected_log += DIVIDER;
802   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
803 }
804 
TEST_F(MallocDebugTest,free_track_use_after_free_with_backtrace)805 TEST_F(MallocDebugTest, free_track_use_after_free_with_backtrace) {
806   Init("free_track=100");
807 
808   // Free backtrace.
809   backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
810 
811   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(200));
812   ASSERT_TRUE(pointer != nullptr);
813   memset(pointer, 0, 200);
814   debug_free(pointer);
815 
816   pointer[101] = 0xab;
817 
818   ASSERT_STREQ("", getFakeLogBuf().c_str());
819   ASSERT_STREQ("", getFakeLogPrint().c_str());
820 
821   debug_finalize();
822   initialized = false;
823 
824   ASSERT_STREQ("", getFakeLogBuf().c_str());
825   std::string expected_log(DIVIDER);
826   expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
827   expected_log += "6 malloc_debug   allocation[101] = 0xab (expected 0xef)\n";
828   expected_log += "6 malloc_debug Backtrace at time of free:\n";
829   expected_log += "6 malloc_debug   #00 pc 0xfa\n";
830   expected_log += "6 malloc_debug   #01 pc 0xeb\n";
831   expected_log += "6 malloc_debug   #02 pc 0xdc\n";
832   expected_log += DIVIDER;
833   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
834 }
835 
TEST_F(MallocDebugTest,free_track_use_after_free_call_realloc)836 TEST_F(MallocDebugTest, free_track_use_after_free_call_realloc) {
837   Init("free_track=100");
838 
839   // Free backtrace.
840   backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
841   // Backtrace at realloc.
842   backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
843 
844   void* pointer = debug_malloc(200);
845   ASSERT_TRUE(pointer != nullptr);
846   memset(pointer, 0, 200);
847   debug_free(pointer);
848 
849   // Choose a size that should not trigger a realloc to verify tag is
850   // verified early.
851   ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
852 
853   ASSERT_STREQ("", getFakeLogBuf().c_str());
854   std::string expected_log(DIVIDER);
855   expected_log += android::base::StringPrintf(
856       "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (realloc)\n", pointer);
857   expected_log += "6 malloc_debug Backtrace of original free:\n";
858   expected_log += "6 malloc_debug   #00 pc 0xfa\n";
859   expected_log += "6 malloc_debug   #01 pc 0xeb\n";
860   expected_log += "6 malloc_debug   #02 pc 0xdc\n";
861   expected_log += "6 malloc_debug Backtrace at time of failure:\n";
862   expected_log += "6 malloc_debug   #00 pc 0x12\n";
863   expected_log += "6 malloc_debug   #01 pc 0x22\n";
864   expected_log += "6 malloc_debug   #02 pc 0x32\n";
865   expected_log += "6 malloc_debug   #03 pc 0x42\n";
866   expected_log += DIVIDER;
867   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
868 }
869 
TEST_F(MallocDebugTest,free_track_use_after_free_call_free)870 TEST_F(MallocDebugTest, free_track_use_after_free_call_free) {
871   Init("free_track=100");
872 
873   // Free backtrace.
874   backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
875   // Backtrace at second free.
876   backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
877 
878   void* pointer = debug_malloc(200);
879   ASSERT_TRUE(pointer != nullptr);
880   memset(pointer, 0, 200);
881   debug_free(pointer);
882 
883   debug_free(pointer);
884 
885   ASSERT_STREQ("", getFakeLogBuf().c_str());
886   std::string expected_log(DIVIDER);
887   expected_log += android::base::StringPrintf(
888       "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (free)\n", pointer);
889   expected_log += "6 malloc_debug Backtrace of original free:\n";
890   expected_log += "6 malloc_debug   #00 pc 0xfa\n";
891   expected_log += "6 malloc_debug   #01 pc 0xeb\n";
892   expected_log += "6 malloc_debug   #02 pc 0xdc\n";
893   expected_log += "6 malloc_debug Backtrace at time of failure:\n";
894   expected_log += "6 malloc_debug   #00 pc 0x12\n";
895   expected_log += "6 malloc_debug   #01 pc 0x22\n";
896   expected_log += "6 malloc_debug   #02 pc 0x32\n";
897   expected_log += "6 malloc_debug   #03 pc 0x42\n";
898   expected_log += DIVIDER;
899   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
900 }
901 
TEST_F(MallocDebugTest,free_track_header_tag_corrupted)902 TEST_F(MallocDebugTest, free_track_header_tag_corrupted) {
903   Init("free_track=100 free_track_backtrace_num_frames=0");
904 
905   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
906   ASSERT_TRUE(pointer != nullptr);
907   memset(pointer, 0, 100);
908   debug_free(pointer);
909 
910   pointer[-get_tag_offset()] = 0x00;
911 
912   ASSERT_STREQ("", getFakeLogBuf().c_str());
913   ASSERT_STREQ("", getFakeLogPrint().c_str());
914 
915   debug_finalize();
916   initialized = false;
917 
918   ASSERT_STREQ("", getFakeLogBuf().c_str());
919   std::string expected_log(DIVIDER);
920   expected_log += android::base::StringPrintf(
921       "6 malloc_debug +++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x1cc7dc00 AFTER FREE\n",
922       pointer);
923   expected_log += DIVIDER;
924   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
925 }
926 
TEST_F(MallocDebugTest,free_track_multiple_thread)927 TEST_F(MallocDebugTest, free_track_multiple_thread) {
928   Init("free_track=10 free_track_backtrace_num_frames=0");
929 
930   std::vector<std::thread*> threads(1000);
931   for (size_t i = 0; i < threads.size(); i++) {
932     threads[i] = new std::thread([](){
933       for (size_t j = 0; j < 100; j++) {
934         void* mem = debug_malloc(100);
935         write(0, mem, 0);
936         debug_free(mem);
937       }
938     });
939   }
940   for (size_t i = 0; i < threads.size(); i++) {
941     threads[i]->join();
942     delete threads[i];
943   }
944 
945   ASSERT_STREQ("", getFakeLogBuf().c_str());
946   ASSERT_STREQ("", getFakeLogPrint().c_str());
947 }
948 
TEST_F(MallocDebugTest,get_malloc_leak_info_invalid)949 TEST_F(MallocDebugTest, get_malloc_leak_info_invalid) {
950   Init("fill");
951 
952   uint8_t* info;
953   size_t overall_size;
954   size_t info_size;
955   size_t total_memory;
956   size_t backtrace_size;
957 
958   std::string expected_log("6 malloc_debug get_malloc_leak_info: At least one invalid parameter.\n");
959 
960   debug_get_malloc_leak_info(nullptr, &overall_size, &info_size, &total_memory, &backtrace_size);
961   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
962 
963   resetLogs();
964   debug_get_malloc_leak_info(&info, nullptr, &info_size, &total_memory, &backtrace_size);
965   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
966 
967   resetLogs();
968   debug_get_malloc_leak_info(&info, &overall_size, nullptr, &total_memory, &backtrace_size);
969   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
970 
971   resetLogs();
972   debug_get_malloc_leak_info(&info, &overall_size, &info_size, nullptr, &backtrace_size);
973   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
974 
975   resetLogs();
976   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, nullptr);
977   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
978 }
979 
TEST_F(MallocDebugTest,get_malloc_leak_info_not_enabled)980 TEST_F(MallocDebugTest, get_malloc_leak_info_not_enabled) {
981   Init("fill");
982 
983   uint8_t* info;
984   size_t overall_size;
985   size_t info_size;
986   size_t total_memory;
987   size_t backtrace_size;
988 
989   ASSERT_STREQ("", getFakeLogBuf().c_str());
990   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
991   std::string expected_log(
992       "6 malloc_debug get_malloc_leak_info: Allocations not being tracked, to enable "
993       "set the option 'backtrace'.\n");
994   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
995 }
996 
997 struct InfoEntry {
998   size_t size;
999   size_t num_frames;
1000   uintptr_t frames[0];
1001 } __attribute__((packed));
1002 
TEST_F(MallocDebugTest,get_malloc_leak_info_empty)1003 TEST_F(MallocDebugTest, get_malloc_leak_info_empty) {
1004   Init("backtrace");
1005 
1006   uint8_t* info;
1007   size_t overall_size;
1008   size_t info_size;
1009   size_t total_memory;
1010   size_t backtrace_size;
1011 
1012   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1013   ASSERT_TRUE(info == nullptr);
1014   ASSERT_EQ(0U, overall_size);
1015   ASSERT_EQ(0U, info_size);
1016   ASSERT_EQ(0U, total_memory);
1017   ASSERT_EQ(0U, backtrace_size);
1018 
1019   ASSERT_STREQ("", getFakeLogBuf().c_str());
1020   ASSERT_STREQ("", getFakeLogPrint().c_str());
1021 }
1022 
TEST_F(MallocDebugTest,get_malloc_leak_info_single)1023 TEST_F(MallocDebugTest, get_malloc_leak_info_single) {
1024   Init("backtrace");
1025 
1026   // Create the expected info buffer.
1027   size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1028   std::vector<uint8_t> expected_info(individual_size);
1029   memset(expected_info.data(), 0, individual_size);
1030 
1031   InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
1032   entry->size = 200;
1033   entry->num_frames = 3;
1034   entry->frames[0] = 0xf;
1035   entry->frames[1] = 0xe;
1036   entry->frames[2] = 0xd;
1037 
1038   backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd});
1039 
1040   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(entry->size));
1041   ASSERT_TRUE(pointer != nullptr);
1042   memset(pointer, 0, entry->size);
1043 
1044   uint8_t* info;
1045   size_t overall_size;
1046   size_t info_size;
1047   size_t total_memory;
1048   size_t backtrace_size;
1049 
1050   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1051   ASSERT_TRUE(info != nullptr);
1052   ASSERT_EQ(individual_size, overall_size);
1053   ASSERT_EQ(individual_size, info_size);
1054   ASSERT_EQ(200U, total_memory);
1055   ASSERT_EQ(16U, backtrace_size);
1056   ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
1057 
1058   debug_free_malloc_leak_info(info);
1059 
1060   debug_free(pointer);
1061 
1062   ASSERT_STREQ("", getFakeLogBuf().c_str());
1063   ASSERT_STREQ("", getFakeLogPrint().c_str());
1064 }
1065 
TEST_F(MallocDebugTest,get_malloc_leak_info_multi)1066 TEST_F(MallocDebugTest, get_malloc_leak_info_multi) {
1067   Init("backtrace=16");
1068 
1069   // Create the expected info buffer.
1070   size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1071   std::vector<uint8_t> expected_info(individual_size * 3);
1072   memset(expected_info.data(), 0, individual_size * 3);
1073 
1074   InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
1075   InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
1076       reinterpret_cast<uintptr_t>(entry0) + individual_size);
1077   InfoEntry* entry2 = reinterpret_cast<InfoEntry*>(
1078       reinterpret_cast<uintptr_t>(entry1) + individual_size);
1079 
1080   // These values will be in the reverse order that we create.
1081   entry2->size = 500;
1082   entry2->num_frames = 4;
1083   entry2->frames[0] = 0xf;
1084   entry2->frames[1] = 0xe;
1085   entry2->frames[2] = 0xd;
1086   entry2->frames[3] = 0xc;
1087 
1088   backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
1089 
1090   uint8_t* pointers[3];
1091 
1092   pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry2->size));
1093   ASSERT_TRUE(pointers[0] != nullptr);
1094   memset(pointers[0], 0, entry2->size);
1095 
1096   entry1->size = 4100;
1097   entry1->num_frames = 16;
1098   for (size_t i = 0; i < 16; i++) {
1099     entry1->frames[i] = 0xbc000 + i;
1100   }
1101 
1102   backtrace_fake_add(
1103       std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
1104                               0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
1105                               0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
1106 
1107   pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
1108   ASSERT_TRUE(pointers[1] != nullptr);
1109   memset(pointers[1], 0, entry1->size);
1110 
1111   entry0->size = 9000;
1112   entry0->num_frames = 1;
1113 
1114   entry0->frames[0] = 0x104;
1115   backtrace_fake_add(std::vector<uintptr_t> {0x104});
1116 
1117   pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
1118   ASSERT_TRUE(pointers[2] != nullptr);
1119   memset(pointers[2], 0, entry0->size);
1120 
1121   uint8_t* info;
1122   size_t overall_size;
1123   size_t info_size;
1124   size_t total_memory;
1125   size_t backtrace_size;
1126 
1127   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1128   ASSERT_TRUE(info != nullptr);
1129   ASSERT_EQ(individual_size * 3, overall_size);
1130   ASSERT_EQ(individual_size, info_size);
1131   ASSERT_EQ(500U + 4100U + 9000U, total_memory);
1132   ASSERT_EQ(16U, backtrace_size);
1133   ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
1134 
1135   debug_free_malloc_leak_info(info);
1136 
1137   debug_free(pointers[0]);
1138   debug_free(pointers[1]);
1139   debug_free(pointers[2]);
1140 
1141   ASSERT_STREQ("", getFakeLogBuf().c_str());
1142   ASSERT_STREQ("", getFakeLogPrint().c_str());
1143 }
1144 
TEST_F(MallocDebugTest,get_malloc_leak_info_multi_skip_empty_backtrace)1145 TEST_F(MallocDebugTest, get_malloc_leak_info_multi_skip_empty_backtrace) {
1146   Init("backtrace=16");
1147 
1148   // Create the expected info buffer.
1149   size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1150   std::vector<uint8_t> expected_info(individual_size * 2);
1151   memset(expected_info.data(), 0, individual_size * 2);
1152 
1153   InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
1154   InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
1155       reinterpret_cast<uintptr_t>(entry0) + individual_size);
1156 
1157   // These values will be in the reverse order that we create.
1158   entry1->size = 500;
1159   entry1->num_frames = 4;
1160   entry1->frames[0] = 0xf;
1161   entry1->frames[1] = 0xe;
1162   entry1->frames[2] = 0xd;
1163   entry1->frames[3] = 0xc;
1164 
1165   backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
1166 
1167   uint8_t* pointers[3];
1168 
1169   pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
1170   ASSERT_TRUE(pointers[0] != nullptr);
1171   memset(pointers[0], 0, entry1->size);
1172 
1173   entry0->size = 4100;
1174   entry0->num_frames = 16;
1175   for (size_t i = 0; i < 16; i++) {
1176     entry0->frames[i] = 0xbc000 + i;
1177   }
1178 
1179   backtrace_fake_add(
1180       std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
1181                               0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
1182                               0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
1183 
1184   pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
1185   ASSERT_TRUE(pointers[1] != nullptr);
1186   memset(pointers[1], 0, entry0->size);
1187 
1188   pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(10000));
1189   ASSERT_TRUE(pointers[2] != nullptr);
1190   memset(pointers[2], 0, 10000);
1191 
1192   uint8_t* info;
1193   size_t overall_size;
1194   size_t info_size;
1195   size_t total_memory;
1196   size_t backtrace_size;
1197 
1198   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1199   ASSERT_TRUE(info != nullptr);
1200   ASSERT_EQ(individual_size * 2, overall_size);
1201   ASSERT_EQ(individual_size, info_size);
1202   ASSERT_EQ(500U + 4100U, total_memory);
1203   ASSERT_EQ(16U, backtrace_size);
1204   ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
1205 
1206   debug_free_malloc_leak_info(info);
1207 
1208   debug_free(pointers[0]);
1209   debug_free(pointers[1]);
1210   debug_free(pointers[2]);
1211 
1212   ASSERT_STREQ("", getFakeLogBuf().c_str());
1213   ASSERT_STREQ("", getFakeLogPrint().c_str());
1214 }
1215 
TEST_F(MallocDebugTest,realloc_usable_size)1216 TEST_F(MallocDebugTest, realloc_usable_size) {
1217   Init("front_guard");
1218 
1219   // Verify that if the usable size > size of alloc, that realloc
1220   // copies the bytes in the usable size not just the size.
1221   // This assumes that an allocation of size 1 returns usable size > 1.
1222   // If this isn't true, this test is not going to do anything.
1223   uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(1));
1224   ASSERT_TRUE(pointer != nullptr);
1225   size_t usable_size = debug_malloc_usable_size(pointer);
1226   memset(pointer, 0xaa, usable_size);
1227   pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, usable_size + 10));
1228   ASSERT_TRUE(pointer != nullptr);
1229   ASSERT_LE(usable_size + 10, debug_malloc_usable_size(pointer));
1230   for (size_t i = 0; i < usable_size; i++) {
1231     ASSERT_EQ(0xaa, pointer[i]) << "Failed compare at byte " << i;
1232   }
1233   debug_free(pointer);
1234 
1235   ASSERT_STREQ("", getFakeLogBuf().c_str());
1236   ASSERT_STREQ("", getFakeLogPrint().c_str());
1237 }
1238 
TEST_F(MallocDebugTest,backtrace_enable_on_signal)1239 TEST_F(MallocDebugTest, backtrace_enable_on_signal) {
1240   Init("backtrace_enable_on_signal=20");
1241 
1242   size_t individual_size = 2 * sizeof(size_t) + 20 * sizeof(uintptr_t);
1243 
1244   backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1245   backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300, 0x400});
1246   backtrace_fake_add(std::vector<uintptr_t> {0x500, 0xa00, 0xb00});
1247 
1248   // First allocation should not actually attempt to get the backtrace.
1249   void* pointer = debug_malloc(10);
1250   ASSERT_TRUE(pointer != nullptr);
1251 
1252   uint8_t* info;
1253   size_t overall_size;
1254   size_t info_size;
1255   size_t total_memory;
1256   size_t backtrace_size;
1257 
1258   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1259   ASSERT_TRUE(info == nullptr);
1260   ASSERT_EQ(0U, overall_size);
1261   ASSERT_EQ(0U, info_size);
1262   ASSERT_EQ(0U, total_memory);
1263   ASSERT_EQ(0U, backtrace_size);
1264   debug_free(pointer);
1265 
1266   debug_free_malloc_leak_info(info);
1267 
1268   // Send the signal to enable.
1269   ASSERT_TRUE(kill(getpid(), SIGRTMIN + 10) == 0);
1270   sleep(1);
1271 
1272   pointer = debug_malloc(100);
1273   ASSERT_TRUE(pointer != nullptr);
1274 
1275   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1276   ASSERT_TRUE(info != nullptr);
1277   ASSERT_EQ(individual_size, overall_size);
1278   ASSERT_EQ(individual_size, info_size);
1279   ASSERT_EQ(100U, total_memory);
1280   ASSERT_EQ(20U, backtrace_size);
1281   uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1282   ASSERT_EQ(0xbc000U, ips[0]);
1283   ASSERT_EQ(0xecd00U, ips[1]);
1284   ASSERT_EQ(0x12000U, ips[2]);
1285   for (size_t i = 3; i < 20; i++) {
1286     ASSERT_EQ(0U, ips[i]);
1287   }
1288 
1289   debug_free(pointer);
1290 
1291   debug_free_malloc_leak_info(info);
1292 
1293   // Send the signal to disable.
1294   ASSERT_TRUE(kill(getpid(), SIGRTMIN + 10) == 0);
1295   sleep(1);
1296 
1297   pointer = debug_malloc(200);
1298   ASSERT_TRUE(pointer != nullptr);
1299 
1300   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1301   ASSERT_TRUE(info == nullptr);
1302   ASSERT_EQ(0U, overall_size);
1303   ASSERT_EQ(0U, info_size);
1304   ASSERT_EQ(0U, total_memory);
1305   ASSERT_EQ(0U, backtrace_size);
1306 
1307   debug_free(pointer);
1308 
1309   debug_free_malloc_leak_info(info);
1310 
1311   ASSERT_STREQ("", getFakeLogBuf().c_str());
1312   std::string expected_log = android::base::StringPrintf(
1313       "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
1314       SIGRTMIN + 10, getpid());
1315   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1316 }
1317 
TEST_F(MallocDebugTest,overflow)1318 TEST_F(MallocDebugTest, overflow) {
1319   Init("guard fill_on_free");
1320 
1321   void* pointer = debug_malloc(SIZE_MAX);
1322   ASSERT_TRUE(pointer == nullptr);
1323   ASSERT_EQ(ENOMEM, errno);
1324 
1325   pointer = debug_calloc(1, SIZE_MAX);
1326   ASSERT_TRUE(pointer == nullptr);
1327   ASSERT_EQ(ENOMEM, errno);
1328 
1329   pointer = debug_calloc(SIZE_MAX, 1);
1330   ASSERT_TRUE(pointer == nullptr);
1331   ASSERT_EQ(ENOMEM, errno);
1332 
1333   pointer = debug_calloc(SIZE_MAX/100, 100);
1334   ASSERT_TRUE(pointer == nullptr);
1335   ASSERT_EQ(ENOMEM, errno);
1336 
1337   pointer = debug_calloc(100, SIZE_MAX/100);
1338   ASSERT_TRUE(pointer == nullptr);
1339   ASSERT_EQ(ENOMEM, errno);
1340 
1341   const size_t size_t_bits = sizeof(size_t) * 8;
1342   const size_t sqrt_size_t = 1ULL << (size_t_bits/2);
1343   pointer = debug_calloc(sqrt_size_t + 1, sqrt_size_t);
1344   ASSERT_TRUE(pointer == nullptr);
1345   ASSERT_EQ(ENOMEM, errno);
1346 
1347   pointer = debug_realloc(nullptr, SIZE_MAX);
1348   ASSERT_TRUE(pointer == nullptr);
1349   ASSERT_EQ(ENOMEM, errno);
1350 
1351   pointer = debug_malloc(100);
1352   ASSERT_TRUE(pointer != nullptr);
1353   memset(pointer, 0xd0, 100);
1354 
1355   void* realloc_pointer = debug_realloc(pointer, SIZE_MAX);
1356   ASSERT_TRUE(realloc_pointer == nullptr);
1357   // Verify the pointer was not freed.
1358   for (size_t i = 0; i < 100; i++) {
1359     ASSERT_EQ(0xd0, reinterpret_cast<uint8_t*>(pointer)[i]) << "Failed checking byte " << i;
1360   }
1361   debug_free(pointer);
1362 
1363   ASSERT_STREQ("", getFakeLogBuf().c_str());
1364   ASSERT_STREQ("", getFakeLogPrint().c_str());
1365 }
1366 
VerifyZygoteSet(size_t memory_bytes)1367 static void VerifyZygoteSet(size_t memory_bytes) {
1368   size_t expected_info_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1369   std::vector<uint8_t> expected_info(expected_info_size);
1370   memset(expected_info.data(), 0, expected_info_size);
1371   InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
1372   entry->size = memory_bytes | (1U << 31);
1373   entry->num_frames = 1;
1374   entry->frames[0] = 0x1;
1375 
1376   uint8_t* info;
1377   size_t overall_size;
1378   size_t info_size;
1379   size_t total_memory;
1380   size_t backtrace_size;
1381 
1382   debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1383   ASSERT_EQ(expected_info_size, overall_size);
1384   ASSERT_EQ(expected_info_size, info_size);
1385   ASSERT_EQ(memory_bytes, total_memory);
1386   ASSERT_EQ(16U, backtrace_size);
1387   ASSERT_TRUE(memcmp(info, expected_info.data(), expected_info_size) == 0);
1388 
1389   debug_free_malloc_leak_info(info);
1390 }
1391 
TEST_F(MallocDebugTest,zygote_set)1392 TEST_F(MallocDebugTest, zygote_set) {
1393   // Set all of the options.
1394   Init("guard fill backtrace leak_track free_track=2");
1395 
1396   zygote = 1;
1397 
1398   backtrace_fake_add(std::vector<uintptr_t> {0x1});
1399 
1400   void* pointer = debug_malloc(100);
1401   ASSERT_TRUE(pointer != nullptr);
1402   ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
1403   memset(pointer, 0, 100);
1404   VerifyZygoteSet(100);
1405   debug_free(pointer);
1406 
1407   backtrace_fake_add(std::vector<uintptr_t> {0x1});
1408   pointer = debug_calloc(10, 20);
1409   ASSERT_TRUE(pointer != nullptr);
1410   ASSERT_EQ(200U, debug_malloc_usable_size(pointer));
1411   VerifyZygoteSet(200);
1412   debug_free(pointer);
1413 
1414   backtrace_fake_add(std::vector<uintptr_t> {0x1});
1415   pointer = debug_memalign(128, 300);
1416   ASSERT_TRUE(pointer != nullptr);
1417   ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
1418   memset(pointer, 0, 300);
1419   VerifyZygoteSet(300);
1420   debug_free(pointer);
1421 
1422   backtrace_fake_add(std::vector<uintptr_t> {0x1});
1423   pointer = debug_malloc(500);
1424   ASSERT_TRUE(pointer != nullptr);
1425   ASSERT_EQ(500U, debug_malloc_usable_size(pointer));
1426   memset(pointer, 0, 500);
1427   VerifyZygoteSet(500);
1428 
1429   backtrace_fake_add(std::vector<uintptr_t> {0x1});
1430   pointer = debug_realloc(pointer, 300);
1431   ASSERT_TRUE(pointer != nullptr);
1432   ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
1433   VerifyZygoteSet(300);
1434   debug_free(pointer);
1435 
1436   ASSERT_STREQ("", getFakeLogBuf().c_str());
1437   ASSERT_STREQ("", getFakeLogPrint().c_str());
1438 }
1439 
TEST_F(MallocDebugTest,max_size)1440 TEST_F(MallocDebugTest, max_size) {
1441   Init("guard");
1442 
1443   void* pointer = debug_malloc(1U << 31);
1444   ASSERT_TRUE(pointer == nullptr);
1445 
1446   pointer = debug_calloc(1, 1U << 31);
1447   ASSERT_TRUE(pointer == nullptr);
1448 
1449   pointer = debug_calloc(1U << 31, 1);
1450   ASSERT_TRUE(pointer == nullptr);
1451 
1452   pointer = debug_memalign(16, 1U << 31);
1453   ASSERT_TRUE(pointer == nullptr);
1454 
1455   ASSERT_STREQ("", getFakeLogBuf().c_str());
1456   ASSERT_STREQ("", getFakeLogPrint().c_str());
1457 }
1458 
TEST_F(MallocDebugTest,debug_mallinfo)1459 TEST_F(MallocDebugTest, debug_mallinfo) {
1460   Init("guard");
1461 
1462   void* pointer = debug_malloc(150);
1463   ASSERT_TRUE(pointer != nullptr);
1464 
1465   struct mallinfo mi = debug_mallinfo();
1466   EXPECT_NE(0U, mi.uordblks);
1467 
1468   debug_free(pointer);
1469 
1470   ASSERT_STREQ("", getFakeLogBuf().c_str());
1471   ASSERT_STREQ("", getFakeLogPrint().c_str());
1472 }
1473 
TEST_F(MallocDebugTest,debug_posix_memalign)1474 TEST_F(MallocDebugTest, debug_posix_memalign) {
1475   Init("guard");
1476 
1477   void* pointer;
1478   ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 300));
1479   ASSERT_TRUE(pointer != nullptr);
1480   debug_free(pointer);
1481 
1482   ASSERT_EQ(EINVAL, debug_posix_memalign(&pointer, 11, 300));
1483 
1484   ASSERT_EQ(ENOMEM, debug_posix_memalign(&pointer, 16, SIZE_MAX));
1485 
1486   ASSERT_STREQ("", getFakeLogBuf().c_str());
1487   ASSERT_STREQ("", getFakeLogPrint().c_str());
1488 }
1489 
1490 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
TEST_F(MallocDebugTest,debug_pvalloc)1491 TEST_F(MallocDebugTest, debug_pvalloc) {
1492   Init("guard");
1493 
1494   size_t pagesize = getpagesize();
1495   void* pointer = debug_pvalloc(1);
1496   ASSERT_TRUE(pointer != nullptr);
1497   ASSERT_EQ(pagesize, debug_malloc_usable_size(pointer));
1498   uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
1499   ASSERT_EQ(0U, value);
1500   debug_free(pointer);
1501 }
1502 
TEST_F(MallocDebugTest,debug_valloc)1503 TEST_F(MallocDebugTest, debug_valloc) {
1504   Init("guard");
1505 
1506   size_t pagesize = getpagesize();
1507   void* pointer = debug_valloc(100);
1508   ASSERT_TRUE(pointer != nullptr);
1509   ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
1510   uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
1511   ASSERT_EQ(0U, value);
1512   debug_free(pointer);
1513 }
1514 #endif
1515