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