malloc_debug_unit_tests.cpp revision 1e185a5056f85e281f699a92114b758591ae3b92
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 <vector>
28#include <utility>
29
30#include <gtest/gtest.h>
31
32#include <android-base/stringprintf.h>
33
34#include <private/bionic_macros.h>
35#include <private/bionic_malloc_dispatch.h>
36
37#include "malloc_debug.h"
38
39#include "log_fake.h"
40#include "backtrace_fake.h"
41
42__BEGIN_DECLS
43
44int property_set(const char*, const char*);
45bool debug_initialize(const MallocDispatch*, int*);
46void debug_finalize();
47
48void* debug_malloc(size_t);
49void debug_free(void*);
50void* debug_calloc(size_t, size_t);
51void* debug_realloc(void*, size_t);
52int debug_posix_memalign(void**, size_t, size_t);
53void* debug_memalign(size_t, size_t);
54size_t debug_malloc_usable_size(void*);
55void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
56void debug_free_malloc_leak_info(uint8_t*);
57
58struct mallinfo debug_mallinfo();
59
60#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
61void* debug_pvalloc(size_t);
62void* debug_valloc(size_t);
63#endif
64
65__END_DECLS
66
67constexpr char DIVIDER[] =
68    "6 malloc_debug *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n";
69
70constexpr uint32_t TRACK_HEADER = 0x2;
71constexpr uint32_t BACKTRACE_HEADER = 0x4;
72
73static size_t get_tag_offset(uint32_t flags = 0, size_t backtrace_frames = 0) {
74  size_t offset = BIONIC_ALIGN(sizeof(Header), sizeof(uintptr_t));
75  if (flags & TRACK_HEADER) {
76    offset += BIONIC_ALIGN(sizeof(TrackHeader), sizeof(uintptr_t));
77  }
78  if (flags & BACKTRACE_HEADER) {
79    offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames - 1, sizeof(uintptr_t));
80    offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames - 1, sizeof(uintptr_t));
81  }
82  return offset;
83}
84
85class MallocDebugTest : public ::testing::Test {
86 protected:
87  void SetUp() override {
88    initialized = false;
89    resetLogs();
90    backtrace_fake_clear_all();
91  }
92
93  void TearDown() override {
94    if (initialized) {
95      debug_finalize();
96    }
97  }
98
99  void Init(const char* property_value) {
100    property_set("libc.debug.malloc.options", property_value);
101    zygote = 0;
102    ASSERT_TRUE(debug_initialize(&dispatch, &zygote));
103    initialized = true;
104  }
105
106  bool initialized;
107
108  int zygote;
109
110  static MallocDispatch dispatch;
111};
112
113MallocDispatch MallocDebugTest::dispatch = {
114  calloc,
115  free,
116  mallinfo,
117  malloc,
118  malloc_usable_size,
119  memalign,
120  posix_memalign,
121#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
122  nullptr,
123#endif
124  realloc,
125#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
126  nullptr,
127#endif
128};
129
130void 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
187TEST_F(MallocDebugTest, fill_generic) {
188  Init("fill");
189  VerifyAllocCalls();
190}
191
192TEST_F(MallocDebugTest, fill_on_alloc_generic) {
193  Init("fill_on_alloc");
194  VerifyAllocCalls();
195}
196
197TEST_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
211TEST_F(MallocDebugTest, fill_on_free) {
212  Init("fill_on_free free_track");
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
228TEST_F(MallocDebugTest, fill_on_free_partial) {
229  Init("fill_on_free=30 free_track");
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
248TEST_F(MallocDebugTest, free_track_partial) {
249  Init("fill_on_free=30 free_track");
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
271TEST_F(MallocDebugTest, all_options) {
272  Init("guard backtrace fill expand_alloc free_track leak_track");
273  VerifyAllocCalls();
274}
275
276TEST_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
305TEST_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
354TEST_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
371TEST_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   pointer[-32] = 0x00 (expected 0xaa)\n";
386  expected_log += "6 malloc_debug   pointer[-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
396TEST_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
452TEST_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   pointer[130] = 0xbf (expected 0xbb)\n";
467  expected_log += "6 malloc_debug   pointer[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
478TEST_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   pointer[130] = 0xbf (expected 0xbb)\n";
499  expected_log += "6 malloc_debug   pointer[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
510TEST_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
565TEST_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
596TEST_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
651TEST_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
690TEST_F(MallocDebugTest, free_track) {
691  Init("free_track=5");
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
716TEST_F(MallocDebugTest, free_track_use_after_free) {
717  Init("free_track=5");
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   pointer[20] = 0xaf (expected 0xef)\n";
762  expected_log += "6 malloc_debug   pointer[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   pointer[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   pointer[4095] = 0x90 (expected 0xef)\n";
771  expected_log += "6 malloc_debug   pointer[4100] = 0x56 (expected 0xef)\n";
772  expected_log += "6 malloc_debug   pointer[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   pointer[8200] = 0x78 (expected 0xef)\n";
777  expected_log += DIVIDER;
778  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
779}
780
781TEST_F(MallocDebugTest, free_track_use_after_free_finalize) {
782  Init("free_track=100");
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   pointer[56] = 0x91 (expected 0xef)\n";
801  expected_log += DIVIDER;
802  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
803}
804
805TEST_F(MallocDebugTest, free_track_use_after_free_with_backtrace) {
806  Init("free_track=100 backtrace");
807
808  // Alloc backtrace.
809  backtrace_fake_add(std::vector<uintptr_t> {0xf0, 0xe, 0xd});
810  // Free backtrace.
811  backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
812
813  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(200));
814  ASSERT_TRUE(pointer != nullptr);
815  memset(pointer, 0, 200);
816  debug_free(pointer);
817
818  pointer[101] = 0xab;
819
820  ASSERT_STREQ("", getFakeLogBuf().c_str());
821  ASSERT_STREQ("", getFakeLogPrint().c_str());
822
823  debug_finalize();
824  initialized = false;
825
826  ASSERT_STREQ("", getFakeLogBuf().c_str());
827  std::string expected_log(DIVIDER);
828  expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
829  expected_log += "6 malloc_debug   pointer[101] = 0xab (expected 0xef)\n";
830  expected_log += "6 malloc_debug Backtrace at time of free:\n";
831  expected_log += "6 malloc_debug   #00 pc 0xfa\n";
832  expected_log += "6 malloc_debug   #01 pc 0xeb\n";
833  expected_log += "6 malloc_debug   #02 pc 0xdc\n";
834  expected_log += DIVIDER;
835  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
836}
837
838TEST_F(MallocDebugTest, get_malloc_leak_info_invalid) {
839  Init("fill");
840
841  uint8_t* info;
842  size_t overall_size;
843  size_t info_size;
844  size_t total_memory;
845  size_t backtrace_size;
846
847  std::string expected_log("6 malloc_debug get_malloc_leak_info: At least one invalid parameter.\n");
848
849  debug_get_malloc_leak_info(nullptr, &overall_size, &info_size, &total_memory, &backtrace_size);
850  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
851
852  resetLogs();
853  debug_get_malloc_leak_info(&info, nullptr, &info_size, &total_memory, &backtrace_size);
854  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
855
856  resetLogs();
857  debug_get_malloc_leak_info(&info, &overall_size, nullptr, &total_memory, &backtrace_size);
858  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
859
860  resetLogs();
861  debug_get_malloc_leak_info(&info, &overall_size, &info_size, nullptr, &backtrace_size);
862  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
863
864  resetLogs();
865  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, nullptr);
866  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
867}
868
869TEST_F(MallocDebugTest, get_malloc_leak_info_not_enabled) {
870  Init("fill");
871
872  uint8_t* info;
873  size_t overall_size;
874  size_t info_size;
875  size_t total_memory;
876  size_t backtrace_size;
877
878  ASSERT_STREQ("", getFakeLogBuf().c_str());
879  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
880  std::string expected_log(
881      "6 malloc_debug get_malloc_leak_info: Allocations not being tracked, to enable "
882      "set the option 'backtrace'.\n");
883  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
884}
885
886struct InfoEntry {
887  size_t size;
888  size_t num_frames;
889  uintptr_t frames[0];
890} __attribute__((packed));
891
892TEST_F(MallocDebugTest, get_malloc_leak_info_empty) {
893  Init("backtrace");
894
895  uint8_t* info;
896  size_t overall_size;
897  size_t info_size;
898  size_t total_memory;
899  size_t backtrace_size;
900
901  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
902  ASSERT_TRUE(info == nullptr);
903  ASSERT_EQ(0U, overall_size);
904  ASSERT_EQ(0U, info_size);
905  ASSERT_EQ(0U, total_memory);
906  ASSERT_EQ(0U, backtrace_size);
907
908  ASSERT_STREQ("", getFakeLogBuf().c_str());
909  ASSERT_STREQ("", getFakeLogPrint().c_str());
910}
911
912TEST_F(MallocDebugTest, get_malloc_leak_info_single) {
913  Init("backtrace");
914
915  // Create the expected info buffer.
916  size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
917  std::vector<uint8_t> expected_info(individual_size);
918  memset(expected_info.data(), 0, individual_size);
919
920  InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
921  entry->size = 200;
922  entry->num_frames = 3;
923  entry->frames[0] = 0xf;
924  entry->frames[1] = 0xe;
925  entry->frames[2] = 0xd;
926
927  backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd});
928
929  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(entry->size));
930  ASSERT_TRUE(pointer != nullptr);
931  memset(pointer, 0, entry->size);
932
933  uint8_t* info;
934  size_t overall_size;
935  size_t info_size;
936  size_t total_memory;
937  size_t backtrace_size;
938
939  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
940  ASSERT_TRUE(info != nullptr);
941  ASSERT_EQ(individual_size, overall_size);
942  ASSERT_EQ(individual_size, info_size);
943  ASSERT_EQ(200U, total_memory);
944  ASSERT_EQ(16U, backtrace_size);
945  ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
946
947  debug_free_malloc_leak_info(info);
948
949  debug_free(pointer);
950
951  ASSERT_STREQ("", getFakeLogBuf().c_str());
952  ASSERT_STREQ("", getFakeLogPrint().c_str());
953}
954
955TEST_F(MallocDebugTest, get_malloc_leak_info_multi) {
956  Init("backtrace=16");
957
958  // Create the expected info buffer.
959  size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
960  std::vector<uint8_t> expected_info(individual_size * 3);
961  memset(expected_info.data(), 0, individual_size * 3);
962
963  InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
964  InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
965      reinterpret_cast<uintptr_t>(entry0) + individual_size);
966  InfoEntry* entry2 = reinterpret_cast<InfoEntry*>(
967      reinterpret_cast<uintptr_t>(entry1) + individual_size);
968
969  // These values will be in the reverse order that we create.
970  entry2->size = 500;
971  entry2->num_frames = 4;
972  entry2->frames[0] = 0xf;
973  entry2->frames[1] = 0xe;
974  entry2->frames[2] = 0xd;
975  entry2->frames[3] = 0xc;
976
977  backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
978
979  uint8_t* pointers[3];
980
981  pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry2->size));
982  ASSERT_TRUE(pointers[0] != nullptr);
983  memset(pointers[0], 0, entry2->size);
984
985  entry1->size = 4100;
986  entry1->num_frames = 16;
987  for (size_t i = 0; i < 16; i++) {
988    entry1->frames[i] = 0xbc000 + i;
989  }
990
991  backtrace_fake_add(
992      std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
993                              0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
994                              0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
995
996  pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
997  ASSERT_TRUE(pointers[1] != nullptr);
998  memset(pointers[1], 0, entry1->size);
999
1000  entry0->size = 9000;
1001  entry0->num_frames = 1;
1002
1003  entry0->frames[0] = 0x104;
1004  backtrace_fake_add(std::vector<uintptr_t> {0x104});
1005
1006  pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
1007  ASSERT_TRUE(pointers[2] != nullptr);
1008  memset(pointers[2], 0, entry0->size);
1009
1010  uint8_t* info;
1011  size_t overall_size;
1012  size_t info_size;
1013  size_t total_memory;
1014  size_t backtrace_size;
1015
1016  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1017  ASSERT_TRUE(info != nullptr);
1018  ASSERT_EQ(individual_size * 3, overall_size);
1019  ASSERT_EQ(individual_size, info_size);
1020  ASSERT_EQ(500U + 4100U + 9000U, total_memory);
1021  ASSERT_EQ(16U, backtrace_size);
1022  ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
1023
1024  debug_free_malloc_leak_info(info);
1025
1026  debug_free(pointers[0]);
1027  debug_free(pointers[1]);
1028  debug_free(pointers[2]);
1029
1030  ASSERT_STREQ("", getFakeLogBuf().c_str());
1031  ASSERT_STREQ("", getFakeLogPrint().c_str());
1032}
1033
1034TEST_F(MallocDebugTest, get_malloc_leak_info_multi_skip_empty_backtrace) {
1035  Init("backtrace=16");
1036
1037  // Create the expected info buffer.
1038  size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1039  std::vector<uint8_t> expected_info(individual_size * 2);
1040  memset(expected_info.data(), 0, individual_size * 2);
1041
1042  InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
1043  InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
1044      reinterpret_cast<uintptr_t>(entry0) + individual_size);
1045
1046  // These values will be in the reverse order that we create.
1047  entry1->size = 500;
1048  entry1->num_frames = 4;
1049  entry1->frames[0] = 0xf;
1050  entry1->frames[1] = 0xe;
1051  entry1->frames[2] = 0xd;
1052  entry1->frames[3] = 0xc;
1053
1054  backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
1055
1056  uint8_t* pointers[3];
1057
1058  pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
1059  ASSERT_TRUE(pointers[0] != nullptr);
1060  memset(pointers[0], 0, entry1->size);
1061
1062  entry0->size = 4100;
1063  entry0->num_frames = 16;
1064  for (size_t i = 0; i < 16; i++) {
1065    entry0->frames[i] = 0xbc000 + i;
1066  }
1067
1068  backtrace_fake_add(
1069      std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
1070                              0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
1071                              0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
1072
1073  pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
1074  ASSERT_TRUE(pointers[1] != nullptr);
1075  memset(pointers[1], 0, entry0->size);
1076
1077  pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(10000));
1078  ASSERT_TRUE(pointers[2] != nullptr);
1079  memset(pointers[2], 0, 10000);
1080
1081  uint8_t* info;
1082  size_t overall_size;
1083  size_t info_size;
1084  size_t total_memory;
1085  size_t backtrace_size;
1086
1087  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1088  ASSERT_TRUE(info != nullptr);
1089  ASSERT_EQ(individual_size * 2, overall_size);
1090  ASSERT_EQ(individual_size, info_size);
1091  ASSERT_EQ(500U + 4100U, total_memory);
1092  ASSERT_EQ(16U, backtrace_size);
1093  ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
1094
1095  debug_free_malloc_leak_info(info);
1096
1097  debug_free(pointers[0]);
1098  debug_free(pointers[1]);
1099  debug_free(pointers[2]);
1100
1101  ASSERT_STREQ("", getFakeLogBuf().c_str());
1102  ASSERT_STREQ("", getFakeLogPrint().c_str());
1103}
1104
1105TEST_F(MallocDebugTest, realloc_usable_size) {
1106  Init("front_guard");
1107
1108  // Verify that if the usable size > size of alloc, that realloc
1109  // copies the bytes in the usable size not just the size.
1110  // This assumes that an allocation of size 1 returns usable size > 1.
1111  // If this isn't true, this test is not going to do anything.
1112  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(1));
1113  ASSERT_TRUE(pointer != nullptr);
1114  size_t usable_size = debug_malloc_usable_size(pointer);
1115  memset(pointer, 0xaa, usable_size);
1116  pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, usable_size + 10));
1117  ASSERT_TRUE(pointer != nullptr);
1118  ASSERT_LE(usable_size + 10, debug_malloc_usable_size(pointer));
1119  for (size_t i = 0; i < usable_size; i++) {
1120    ASSERT_EQ(0xaa, pointer[i]) << "Failed compare at byte " << i;
1121  }
1122  debug_free(pointer);
1123
1124  ASSERT_STREQ("", getFakeLogBuf().c_str());
1125  ASSERT_STREQ("", getFakeLogPrint().c_str());
1126}
1127
1128TEST_F(MallocDebugTest, backtrace_enable_on_signal) {
1129  Init("backtrace_enable_on_signal=20");
1130
1131  size_t individual_size = 2 * sizeof(size_t) + 20 * sizeof(uintptr_t);
1132
1133  backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1134  backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300, 0x400});
1135  backtrace_fake_add(std::vector<uintptr_t> {0x500, 0xa00, 0xb00});
1136
1137  // First allocation should not actually attempt to get the backtrace.
1138  void* pointer = debug_malloc(10);
1139  ASSERT_TRUE(pointer != nullptr);
1140
1141  uint8_t* info;
1142  size_t overall_size;
1143  size_t info_size;
1144  size_t total_memory;
1145  size_t backtrace_size;
1146
1147  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1148  ASSERT_TRUE(info == nullptr);
1149  ASSERT_EQ(0U, overall_size);
1150  ASSERT_EQ(0U, info_size);
1151  ASSERT_EQ(0U, total_memory);
1152  ASSERT_EQ(0U, backtrace_size);
1153  debug_free(pointer);
1154
1155  debug_free_malloc_leak_info(info);
1156
1157  // Send the signal to enable.
1158  ASSERT_TRUE(kill(getpid(), SIGRTMIN + 10) == 0);
1159  sleep(1);
1160
1161  pointer = debug_malloc(100);
1162  ASSERT_TRUE(pointer != nullptr);
1163
1164  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1165  ASSERT_TRUE(info != nullptr);
1166  ASSERT_EQ(individual_size, overall_size);
1167  ASSERT_EQ(individual_size, info_size);
1168  ASSERT_EQ(100U, total_memory);
1169  ASSERT_EQ(20U, backtrace_size);
1170  uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1171  ASSERT_EQ(0xbc000U, ips[0]);
1172  ASSERT_EQ(0xecd00U, ips[1]);
1173  ASSERT_EQ(0x12000U, ips[2]);
1174  for (size_t i = 3; i < 20; i++) {
1175    ASSERT_EQ(0U, ips[i]);
1176  }
1177
1178  debug_free(pointer);
1179
1180  debug_free_malloc_leak_info(info);
1181
1182  // Send the signal to disable.
1183  ASSERT_TRUE(kill(getpid(), SIGRTMIN + 10) == 0);
1184  sleep(1);
1185
1186  pointer = debug_malloc(200);
1187  ASSERT_TRUE(pointer != nullptr);
1188
1189  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1190  ASSERT_TRUE(info == nullptr);
1191  ASSERT_EQ(0U, overall_size);
1192  ASSERT_EQ(0U, info_size);
1193  ASSERT_EQ(0U, total_memory);
1194  ASSERT_EQ(0U, backtrace_size);
1195
1196  debug_free(pointer);
1197
1198  debug_free_malloc_leak_info(info);
1199
1200  ASSERT_STREQ("", getFakeLogBuf().c_str());
1201  std::string expected_log = android::base::StringPrintf(
1202      "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
1203      SIGRTMIN + 10, getpid());
1204  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1205}
1206
1207TEST_F(MallocDebugTest, overflow) {
1208  Init("guard fill_on_free");
1209
1210  void* pointer = debug_malloc(SIZE_MAX);
1211  ASSERT_TRUE(pointer == nullptr);
1212  ASSERT_EQ(ENOMEM, errno);
1213
1214  pointer = debug_calloc(1, SIZE_MAX);
1215  ASSERT_TRUE(pointer == nullptr);
1216  ASSERT_EQ(ENOMEM, errno);
1217
1218  pointer = debug_calloc(SIZE_MAX, 1);
1219  ASSERT_TRUE(pointer == nullptr);
1220  ASSERT_EQ(ENOMEM, errno);
1221
1222  pointer = debug_calloc(SIZE_MAX/100, 100);
1223  ASSERT_TRUE(pointer == nullptr);
1224  ASSERT_EQ(ENOMEM, errno);
1225
1226  pointer = debug_calloc(100, SIZE_MAX/100);
1227  ASSERT_TRUE(pointer == nullptr);
1228  ASSERT_EQ(ENOMEM, errno);
1229
1230  pointer = debug_realloc(nullptr, SIZE_MAX);
1231  ASSERT_TRUE(pointer == nullptr);
1232  ASSERT_EQ(ENOMEM, errno);
1233
1234  pointer = debug_malloc(100);
1235  ASSERT_TRUE(pointer != nullptr);
1236  memset(pointer, 0xd0, 100);
1237
1238  void* realloc_pointer = debug_realloc(pointer, SIZE_MAX);
1239  ASSERT_TRUE(realloc_pointer == nullptr);
1240  // Verify the pointer was not freed.
1241  for (size_t i = 0; i < 100; i++) {
1242    ASSERT_EQ(0xd0, reinterpret_cast<uint8_t*>(pointer)[i]) << "Failed checking byte " << i;
1243  }
1244  debug_free(pointer);
1245
1246  ASSERT_STREQ("", getFakeLogBuf().c_str());
1247  ASSERT_STREQ("", getFakeLogPrint().c_str());
1248}
1249
1250static void VerifyZygoteSet(size_t memory_bytes) {
1251  size_t expected_info_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1252  std::vector<uint8_t> expected_info(expected_info_size);
1253  memset(expected_info.data(), 0, expected_info_size);
1254  InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
1255  entry->size = memory_bytes | (1U << 31);
1256  entry->num_frames = 1;
1257  entry->frames[0] = 0x1;
1258
1259  uint8_t* info;
1260  size_t overall_size;
1261  size_t info_size;
1262  size_t total_memory;
1263  size_t backtrace_size;
1264
1265  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1266  ASSERT_EQ(expected_info_size, overall_size);
1267  ASSERT_EQ(expected_info_size, info_size);
1268  ASSERT_EQ(memory_bytes, total_memory);
1269  ASSERT_EQ(16U, backtrace_size);
1270  ASSERT_TRUE(memcmp(info, expected_info.data(), expected_info_size) == 0);
1271
1272  debug_free_malloc_leak_info(info);
1273}
1274
1275TEST_F(MallocDebugTest, zygote_set) {
1276  // Set all of the options.
1277  Init("guard fill backtrace leak_track free_track=2");
1278
1279  zygote = 1;
1280
1281  backtrace_fake_add(std::vector<uintptr_t> {0x1});
1282
1283  void* pointer = debug_malloc(100);
1284  ASSERT_TRUE(pointer != nullptr);
1285  ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
1286  memset(pointer, 0, 100);
1287  VerifyZygoteSet(100);
1288  debug_free(pointer);
1289
1290  backtrace_fake_add(std::vector<uintptr_t> {0x1});
1291  pointer = debug_calloc(10, 20);
1292  ASSERT_TRUE(pointer != nullptr);
1293  ASSERT_EQ(200U, debug_malloc_usable_size(pointer));
1294  VerifyZygoteSet(200);
1295  debug_free(pointer);
1296
1297  backtrace_fake_add(std::vector<uintptr_t> {0x1});
1298  pointer = debug_memalign(128, 300);
1299  ASSERT_TRUE(pointer != nullptr);
1300  ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
1301  memset(pointer, 0, 300);
1302  VerifyZygoteSet(300);
1303  debug_free(pointer);
1304
1305  backtrace_fake_add(std::vector<uintptr_t> {0x1});
1306  pointer = debug_malloc(500);
1307  ASSERT_TRUE(pointer != nullptr);
1308  ASSERT_EQ(500U, debug_malloc_usable_size(pointer));
1309  memset(pointer, 0, 500);
1310  VerifyZygoteSet(500);
1311
1312  backtrace_fake_add(std::vector<uintptr_t> {0x1});
1313  pointer = debug_realloc(pointer, 300);
1314  ASSERT_TRUE(pointer != nullptr);
1315  ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
1316  VerifyZygoteSet(300);
1317  debug_free(pointer);
1318
1319  ASSERT_STREQ("", getFakeLogBuf().c_str());
1320  ASSERT_STREQ("", getFakeLogPrint().c_str());
1321}
1322
1323TEST_F(MallocDebugTest, max_size) {
1324  Init("guard");
1325
1326  void* pointer = debug_malloc(1U << 31);
1327  ASSERT_TRUE(pointer == nullptr);
1328
1329  pointer = debug_calloc(1, 1U << 31);
1330  ASSERT_TRUE(pointer == nullptr);
1331
1332  pointer = debug_calloc(1U << 31, 1);
1333  ASSERT_TRUE(pointer == nullptr);
1334
1335  pointer = debug_memalign(16, 1U << 31);
1336  ASSERT_TRUE(pointer == nullptr);
1337
1338  ASSERT_STREQ("", getFakeLogBuf().c_str());
1339  ASSERT_STREQ("", getFakeLogPrint().c_str());
1340}
1341
1342TEST_F(MallocDebugTest, debug_mallinfo) {
1343  Init("guard");
1344
1345  void* pointer = debug_malloc(150);
1346  ASSERT_TRUE(pointer != nullptr);
1347
1348  struct mallinfo mi = debug_mallinfo();
1349  EXPECT_NE(0U, mi.uordblks);
1350
1351  debug_free(pointer);
1352
1353  ASSERT_STREQ("", getFakeLogBuf().c_str());
1354  ASSERT_STREQ("", getFakeLogPrint().c_str());
1355}
1356
1357TEST_F(MallocDebugTest, debug_posix_memalign) {
1358  Init("guard");
1359
1360  void* pointer;
1361  ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 300));
1362  ASSERT_TRUE(pointer != nullptr);
1363  debug_free(pointer);
1364
1365  ASSERT_EQ(EINVAL, debug_posix_memalign(&pointer, 11, 300));
1366
1367  ASSERT_EQ(ENOMEM, debug_posix_memalign(&pointer, 16, SIZE_MAX));
1368
1369  ASSERT_STREQ("", getFakeLogBuf().c_str());
1370  ASSERT_STREQ("", getFakeLogPrint().c_str());
1371}
1372
1373#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
1374TEST_F(MallocDebugTest, debug_pvalloc) {
1375  Init("guard");
1376
1377  size_t pagesize = getpagesize();
1378  void* pointer = debug_pvalloc(1);
1379  ASSERT_TRUE(pointer != nullptr);
1380  ASSERT_EQ(pagesize, debug_malloc_usable_size(pointer));
1381  uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
1382  ASSERT_EQ(0U, value);
1383  debug_free(pointer);
1384}
1385
1386TEST_F(MallocDebugTest, debug_valloc) {
1387  Init("guard");
1388
1389  size_t pagesize = getpagesize();
1390  void* pointer = debug_valloc(100);
1391  ASSERT_TRUE(pointer != nullptr);
1392  ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
1393  uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
1394  ASSERT_EQ(0U, value);
1395  debug_free(pointer);
1396}
1397#endif
1398