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