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