• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <poll.h>
32 #include <setjmp.h>
33 #include <signal.h>
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <sys/types.h>
38 #include <sys/wait.h>
39 #include <time.h>
40 #include <unistd.h>
41 
42 #include <android-base/file.h>
43 #include <android-base/stringprintf.h>
44 #include <android-base/test_utils.h>
45 #include <gtest/gtest.h>
46 #include <log/log_read.h>
47 
48 #include <atomic>
49 #include <mutex>
50 #include <random>
51 #include <string>
52 #include <thread>
53 #include <vector>
54 
55 #include <unwindstack/AndroidUnwinder.h>
56 
57 #include <bionic/malloc.h>
58 #include <tests/utils.h>
59 
60 // All DISABLED_ tests are designed to be executed after malloc debug
61 // is enabled. These tests don't run be default, and are executed
62 // by wrappers that will enable various malloc debug features.
63 
GetInitialArgs(const char *** args,size_t * num_args)64 extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) {
65   static const char* initial_args[] = {"--slow_threshold_ms=30000",
66                                        "--deadline_threshold_ms=1200000"};
67   *args = initial_args;
68   *num_args = 2;
69   return true;
70 }
71 
72 class LogReader {
73  public:
LogReader(pid_t pid,log_id log)74   LogReader(pid_t pid, log_id log) {
75     std::call_once(log_start_time_flag_, []() {
76       // Use this to figure out the point at which to start grabbing the log.
77       // This avoids accidentally grabbing data from a previous process with
78       // the same pid.
79       log_start_time_ = {};
80       logger_list* list = android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, 1000, 0);
81       if (list == nullptr) {
82         return;
83       }
84       log_msg log_msg;
85       int ret = android_logger_list_read(list, &log_msg);
86       android_logger_list_close(list);
87       if (ret <= 0) {
88         return;
89       }
90       log_start_time_.tv_sec = log_msg.entry.sec;
91       log_start_time_.tv_nsec = log_msg.entry.nsec;
92     });
93 
94     std::call_once(jmp_data_key_flag_, []() {
95       pthread_key_create(&jmp_data_key_, [](void* ptr) { free(ptr); });
96       signal(SIGUSR1, [](int) {
97         jmp_buf* jb = reinterpret_cast<jmp_buf*>(pthread_getspecific(jmp_data_key_));
98         if (jb != nullptr) {
99           // The thread reading the log is in a blocking read call that
100           // cannot be interrupted. In order to get out of this read loop,
101           // it's necessary to call longjmp when a SIGUSR1 signal is sent
102           // to the thread.
103           longjmp(*jb, 1);
104         }
105       });
106     });
107 
108     reader_.reset(new std::thread([this, pid, log] {
109       tid_.store(gettid(), std::memory_order_release);
110       logger_list* list;
111       while (true) {
112         // Do not use non-blocking mode so that the two threads
113         // are essentially asleep and not consuming any cpu.
114         list = android_logger_list_open(log, 0, 1000, pid);
115         if (list != nullptr) {
116           break;
117         }
118         // Wait for a short time for the log to become available.
119         usleep(1000);
120       }
121 
122       jmp_buf* jb = reinterpret_cast<jmp_buf*>(malloc(sizeof(jmp_buf)));
123       if (jb == nullptr) {
124         printf("Failed to allocate memory for jmp_buf\n");
125         return;
126       }
127       pthread_setspecific(jmp_data_key_, jb);
128       if (setjmp(*jb) != 0) {
129         // SIGUSR1 signal hit, we need to terminate the thread.
130         android_logger_list_free(list);
131         return;
132       }
133 
134       while (true) {
135         log_msg msg;
136         int actual = android_logger_list_read(list, &msg);
137         if (actual < 0) {
138           if (actual == -EINTR) {
139             // Interrupted retry.
140             continue;
141           }
142           // Unknown error.
143           break;
144         } else if (actual == 0) {
145           // Nothing left to read.
146           break;
147         }
148         // Do not allow SIGUSR1 while processing the log message.
149         // This avoids a deadlock if the thread is being terminated
150         // at this moment.
151         sigset64_t mask_set;
152         sigprocmask64(SIG_SETMASK, nullptr, &mask_set);
153         sigaddset64(&mask_set, SIGUSR1);
154         sigprocmask64(SIG_SETMASK, &mask_set, nullptr);
155 
156         {
157           // Lock while appending to the data.
158           std::lock_guard<std::mutex> guard(data_lock_);
159           char* msg_str = msg.msg();
160           // Make sure the message is not empty and recent.
161           if (msg_str != nullptr && (msg.entry.sec > log_start_time_.tv_sec ||
162                                      (msg.entry.sec == log_start_time_.tv_sec &&
163                                       msg.entry.nsec > log_start_time_.tv_nsec))) {
164             // Skip the tag part of the message.
165             char* tag = msg_str + 1;
166             msg_str = tag + strlen(tag) + 1;
167             log_data_ += msg_str;
168             if (log_data_.back() != '\n') {
169               log_data_ += '\n';
170             }
171           }
172         }
173 
174         // Re-enable SIGUSR1
175         sigprocmask64(SIG_SETMASK, nullptr, &mask_set);
176         sigdelset64(&mask_set, SIGUSR1);
177         sigprocmask64(SIG_SETMASK, &mask_set, nullptr);
178       }
179       android_logger_list_free(list);
180     }));
181   }
182 
~LogReader()183   virtual ~LogReader() {
184     tgkill(getpid(), tid_.load(std::memory_order_acquire), SIGUSR1);
185     reader_->join();
186   }
187 
GetLog()188   std::string GetLog() {
189     std::lock_guard<std::mutex> guard(data_lock_);
190     return log_data_;
191   }
192 
193  private:
194   std::unique_ptr<std::thread> reader_;
195   std::string log_data_;
196   std::mutex data_lock_;
197   std::atomic<pid_t> tid_;
198 
199   static std::once_flag jmp_data_key_flag_;
200   static pthread_key_t jmp_data_key_;
201 
202   static std::once_flag log_start_time_flag_;
203   static log_time log_start_time_;
204 };
205 
206 std::once_flag LogReader::jmp_data_key_flag_;
207 pthread_key_t LogReader::jmp_data_key_;
208 
209 std::once_flag LogReader::log_start_time_flag_;
210 log_time LogReader::log_start_time_;
211 
212 class MallocDebugSystemTest : public ::testing::Test {
213  protected:
SetUp()214   void SetUp() override {
215     expected_log_strings_.clear();
216     unexpected_log_strings_.clear();
217 
218     // All tests expect this message to be present.
219     expected_log_strings_.push_back("malloc debug enabled");
220   }
221 
Exec(const char * test_name,const char * debug_options,int expected_exit_code=0)222   void Exec(const char* test_name, const char* debug_options, int expected_exit_code = 0) {
223     std::random_device rd;
224     std::mt19937 generator(rd());
225     std::uniform_int_distribution<> rand_usleep_time(1, 10);
226     std::srand(std::time(nullptr));
227 
228     for (size_t i = 0; i < kMaxRetries; i++) {
229       ASSERT_NO_FATAL_FAILURE(InternalExec(test_name, debug_options, expected_exit_code));
230 
231       // Due to log messages sometimes getting lost, if a log message
232       // is not present, allow retrying the test.
233       std::string error_msg;
234       bool found_expected = CheckExpectedLogStrings(&error_msg);
235       if (!found_expected) {
236         ASSERT_NE(i, kMaxRetries - 1) << error_msg;
237         // Sleep a random amount of time to attempt to avoid tests syncing
238         // up and sending the log messages at the same time.
239         usleep(1000 * rand_usleep_time(generator));
240       }
241 
242       // This doesn't need to be retried since if the log message is
243       // present, that is an immediate fail.
244       ASSERT_NO_FATAL_FAILURE(VerifyUnexpectedLogStrings());
245       if (found_expected) {
246         break;
247       }
248     }
249   }
250 
InternalExec(const char * test_name,const char * debug_options,int expected_exit_code)251   void InternalExec(const char* test_name, const char* debug_options, int expected_exit_code) {
252     int fds[2];
253     ASSERT_NE(-1, pipe(fds));
254     ASSERT_NE(-1, fcntl(fds[0], F_SETFL, O_NONBLOCK));
255     if ((pid_ = fork()) == 0) {
256       ASSERT_EQ(0, setenv("LIBC_DEBUG_MALLOC_OPTIONS", debug_options, 1));
257       close(fds[0]);
258       close(STDIN_FILENO);
259       close(STDOUT_FILENO);
260       close(STDERR_FILENO);
261       ASSERT_NE(0, dup2(fds[1], STDOUT_FILENO));
262       ASSERT_NE(0, dup2(fds[1], STDERR_FILENO));
263 
264       std::vector<const char*> args;
265       // Get a copy of this argument so it doesn't disappear on us.
266       std::string exec(testing::internal::GetArgvs()[0]);
267       args.push_back(exec.c_str());
268       args.push_back("--gtest_also_run_disabled_tests");
269       std::string filter_arg = std::string("--gtest_filter=") + test_name;
270       args.push_back(filter_arg.c_str());
271       // Need this because some code depends on exit codes from the test run
272       // but the isolation runner does not support that.
273       args.push_back("--no_isolate");
274       args.push_back(nullptr);
275       execv(args[0], reinterpret_cast<char* const*>(const_cast<char**>(args.data())));
276       exit(20);
277     }
278     ASSERT_NE(-1, pid_);
279     close(fds[1]);
280 
281     // Create threads to read the log output from the forked process as
282     // soon as possible in case there is something flooding the log.
283     log_main_.reset(new LogReader(pid_, LOG_ID_MAIN));
284     log_crash_.reset(new LogReader(pid_, LOG_ID_CRASH));
285 
286     output_.clear();
287     std::vector<char> buffer(4096);
288     time_t start_time = time(nullptr);
289     bool read_done = false;
290     while (true) {
291       struct pollfd read_fd = {.fd = fds[0], .events = POLLIN};
292       if (TEMP_FAILURE_RETRY(poll(&read_fd, 1, 1)) > 0) {
293         ssize_t bytes = TEMP_FAILURE_RETRY(read(fds[0], buffer.data(), sizeof(buffer) - 1));
294         if (bytes == -1 && errno == EAGAIN) {
295           continue;
296         }
297         ASSERT_NE(-1, bytes);
298         if (bytes == 0) {
299           read_done = true;
300           break;
301         }
302         output_.append(buffer.data(), bytes);
303       }
304 
305       if ((time(nullptr) - start_time) > kReadOutputTimeoutSeconds) {
306         kill(pid_, SIGINT);
307         break;
308       }
309     }
310 
311     bool done = false;
312     int status;
313     start_time = time(nullptr);
314     while (true) {
315       int wait_pid = waitpid(pid_, &status, WNOHANG);
316       if (pid_ == wait_pid) {
317         done = true;
318         break;
319       }
320       if ((time(nullptr) - start_time) > kWaitpidTimeoutSeconds) {
321         break;
322       }
323     }
324     if (!done) {
325       kill(pid_, SIGKILL);
326       start_time = time(nullptr);
327       while (true) {
328         int kill_status;
329         int wait_pid = waitpid(pid_, &kill_status, WNOHANG);
330         if (wait_pid == pid_ || (time(nullptr) - start_time) > kWaitpidTimeoutSeconds) {
331           break;
332         }
333       }
334     }
335 
336     // Check timeout conditions first.
337     ASSERT_TRUE(read_done) << "Timed out while reading data, output:\n" << output_;
338     ASSERT_TRUE(done) << "Timed out waiting for waitpid, output:\n" << output_;
339 
340     ASSERT_FALSE(WIFSIGNALED(status)) << "Failed with signal " << WTERMSIG(status) << "\nOutput:\n"
341                                       << output_;
342     ASSERT_EQ(expected_exit_code, WEXITSTATUS(status)) << "Output:\n" << output_;
343   }
344 
CheckExpectedLogStrings(std::string * error_msg)345   bool CheckExpectedLogStrings(std::string* error_msg) {
346     time_t start = time(nullptr);
347     std::string missing_match;
348     std::string log_str;
349     while (true) {
350       log_str = log_main_->GetLog();
351       missing_match.clear();
352       // Look for the expected strings.
353       for (auto str : expected_log_strings_) {
354         if (log_str.find(str) == std::string::npos) {
355           missing_match = str;
356           break;
357         }
358       }
359       if (missing_match.empty()) {
360         return true;
361       }
362       if ((time(nullptr) - start) > kLogTimeoutSeconds) {
363         break;
364       }
365     }
366 
367     *error_msg = android::base::StringPrintf("Didn't find string '%s' in log output:\n%s",
368                                              missing_match.c_str(), log_str.c_str());
369     return false;
370   }
371 
VerifyUnexpectedLogStrings()372   void VerifyUnexpectedLogStrings() {
373     std::string log_str = log_main_->GetLog();
374     for (auto str : unexpected_log_strings_) {
375       ASSERT_TRUE(log_str.find(str) == std::string::npos)
376           << "Unexpectedly found string '" << str << "' in log output:\n"
377           << log_str;
378     }
379   }
380 
VerifyLeak(const char * test_prefix)381   void VerifyLeak(const char* test_prefix) {
382     struct FunctionInfo {
383       const char* name;
384       size_t size;
385     };
386     static FunctionInfo functions[] = {
387       {
388           "aligned_alloc",
389           1152,
390       },
391       {
392           "calloc",
393           1123,
394       },
395       {
396           "malloc",
397           1123,
398       },
399       {
400           "memalign",
401           1123,
402       },
403       {
404           "posix_memalign",
405           1123,
406       },
407       {
408           "reallocarray",
409           1123,
410       },
411       {
412           "realloc",
413           1123,
414       },
415 #if !defined(__LP64__)
416       {
417           "pvalloc",
418           4096,
419       },
420       {
421           "valloc",
422           1123,
423       }
424 #endif
425     };
426 
427     size_t match_len = expected_log_strings_.size() + 1;
428     expected_log_strings_.resize(match_len);
429     for (size_t i = 0; i < sizeof(functions) / sizeof(FunctionInfo); i++) {
430       SCOPED_TRACE(testing::Message()
431                    << functions[i].name << " expected size " << functions[i].size);
432 
433       expected_log_strings_[match_len - 1] =
434           android::base::StringPrintf("leaked block of size %zu at", functions[i].size);
435 
436       std::string test = std::string("MallocTests.DISABLED_") + test_prefix + functions[i].name;
437       ASSERT_NO_FATAL_FAILURE(Exec(test.c_str(), "verbose backtrace leak_track"));
438     }
439   }
440 
441   std::unique_ptr<LogReader> log_main_;
442   std::unique_ptr<LogReader> log_crash_;
443   pid_t pid_;
444   std::string output_;
445   std::vector<std::string> expected_log_strings_;
446   std::vector<std::string> unexpected_log_strings_;
447 
448   static constexpr size_t kReadOutputTimeoutSeconds = 180;
449   static constexpr size_t kWaitpidTimeoutSeconds = 10;
450   static constexpr size_t kLogTimeoutSeconds = 5;
451   static constexpr size_t kMaxRetries = 3;
452 };
453 
TEST(MallocTests,DISABLED_smoke)454 TEST(MallocTests, DISABLED_smoke) {
455   void* ptr = malloc(128);
456   free(ptr);
457 }
458 
TEST_F(MallocDebugSystemTest,smoke)459 TEST_F(MallocDebugSystemTest, smoke) {
460   Exec("MallocTests.DISABLED_smoke", "verbose backtrace");
461 }
462 
TEST_F(MallocDebugSystemTest,backtrace_full_smoke)463 TEST_F(MallocDebugSystemTest, backtrace_full_smoke) {
464   Exec("MallocTests.DISABLED_smoke", "verbose backtrace backtrace_full");
465 }
466 
SetAllocationLimit()467 static void SetAllocationLimit() {
468   // Set to a large value, this is only to enable the limit code and
469   // verify that malloc debug is still called properly.
470   size_t limit = 500 * 1024 * 1024;
471   ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
472 }
473 
AlignedAlloc()474 static void AlignedAlloc() {
475   void* ptr = aligned_alloc(64, 1152);
476   ASSERT_TRUE(ptr != nullptr);
477   memset(ptr, 0, 1152);
478 }
479 
TEST(MallocTests,DISABLED_leak_memory_aligned_alloc)480 TEST(MallocTests, DISABLED_leak_memory_aligned_alloc) {
481   AlignedAlloc();
482 }
483 
TEST(MallocTests,DISABLED_leak_memory_limit_aligned_alloc)484 TEST(MallocTests, DISABLED_leak_memory_limit_aligned_alloc) {
485   SetAllocationLimit();
486   AlignedAlloc();
487 }
488 
Calloc()489 static void Calloc() {
490   void* ptr = calloc(1, 1123);
491   ASSERT_TRUE(ptr != nullptr);
492   memset(ptr, 1, 1123);
493 }
494 
TEST(MallocTests,DISABLED_leak_memory_calloc)495 TEST(MallocTests, DISABLED_leak_memory_calloc) {
496   Calloc();
497 }
498 
TEST(MallocTests,DISABLED_leak_memory_limit_calloc)499 TEST(MallocTests, DISABLED_leak_memory_limit_calloc) {
500   SetAllocationLimit();
501   Calloc();
502 }
503 
Malloc()504 static void Malloc() {
505   void* ptr = malloc(1123);
506   ASSERT_TRUE(ptr != nullptr);
507   memset(ptr, 0, 1123);
508 }
509 
TEST(MallocTests,DISABLED_leak_memory_malloc)510 TEST(MallocTests, DISABLED_leak_memory_malloc) {
511   Malloc();
512 }
513 
TEST(MallocTests,DISABLED_leak_memory_limit_malloc)514 TEST(MallocTests, DISABLED_leak_memory_limit_malloc) {
515   SetAllocationLimit();
516   Malloc();
517 }
518 
Memalign()519 static void Memalign() {
520   void* ptr = memalign(64, 1123);
521   ASSERT_TRUE(ptr != nullptr);
522   memset(ptr, 0, 1123);
523 }
524 
TEST(MallocTests,DISABLED_leak_memory_memalign)525 TEST(MallocTests, DISABLED_leak_memory_memalign) {
526   Memalign();
527 }
528 
TEST(MallocTests,DISABLED_leak_memory_limit_memalign)529 TEST(MallocTests, DISABLED_leak_memory_limit_memalign) {
530   SetAllocationLimit();
531   Memalign();
532 }
533 
PosixMemalign()534 static void PosixMemalign() {
535   void* ptr;
536   ASSERT_EQ(0, posix_memalign(&ptr, 64, 1123));
537   ASSERT_TRUE(ptr != nullptr);
538   memset(ptr, 0, 1123);
539 }
540 
TEST(MallocTests,DISABLED_leak_memory_posix_memalign)541 TEST(MallocTests, DISABLED_leak_memory_posix_memalign) {
542   PosixMemalign();
543 }
544 
TEST(MallocTests,DISABLED_leak_memory_limit_posix_memalign)545 TEST(MallocTests, DISABLED_leak_memory_limit_posix_memalign) {
546   SetAllocationLimit();
547   PosixMemalign();
548 }
549 
Reallocarray()550 static void Reallocarray() {
551   void* ptr = reallocarray(nullptr, 1, 1123);
552   ASSERT_TRUE(ptr != nullptr);
553   memset(ptr, 0, 1123);
554 }
555 
TEST(MallocTests,DISABLED_leak_memory_reallocarray)556 TEST(MallocTests, DISABLED_leak_memory_reallocarray) {
557   Reallocarray();
558 }
559 
TEST(MallocTests,DISABLED_leak_memory_limit_reallocarray)560 TEST(MallocTests, DISABLED_leak_memory_limit_reallocarray) {
561   SetAllocationLimit();
562   Reallocarray();
563 }
564 
Realloc()565 static void Realloc() {
566   void* ptr = realloc(nullptr, 1123);
567   ASSERT_TRUE(ptr != nullptr);
568   memset(ptr, 0, 1123);
569 }
570 
TEST(MallocTests,DISABLED_leak_memory_realloc)571 TEST(MallocTests, DISABLED_leak_memory_realloc) {
572   Realloc();
573 }
574 
TEST(MallocTests,DISABLED_leak_memory_limit_realloc)575 TEST(MallocTests, DISABLED_leak_memory_limit_realloc) {
576   SetAllocationLimit();
577   Realloc();
578 }
579 
580 #if !defined(__LP64__)
581 extern "C" void* pvalloc(size_t);
582 
Pvalloc()583 static void Pvalloc() {
584   void* ptr = pvalloc(1123);
585   ASSERT_TRUE(ptr != nullptr);
586   memset(ptr, 0, 1123);
587 }
588 
TEST(MallocTests,DISABLED_leak_memory_pvalloc)589 TEST(MallocTests, DISABLED_leak_memory_pvalloc) {
590   Pvalloc();
591 }
592 
TEST(MallocTests,DISABLED_leak_memory_limit_pvalloc)593 TEST(MallocTests, DISABLED_leak_memory_limit_pvalloc) {
594   SetAllocationLimit();
595   Pvalloc();
596 }
597 
598 extern "C" void* valloc(size_t);
599 
Valloc()600 static void Valloc() {
601   void* ptr = valloc(1123);
602   ASSERT_TRUE(ptr != nullptr);
603   memset(ptr, 0, 1123);
604 }
605 
TEST(MallocTests,DISABLED_leak_memory_valloc)606 TEST(MallocTests, DISABLED_leak_memory_valloc) {
607   Valloc();
608 }
609 
TEST(MallocTests,DISABLED_leak_memory_limit_valloc)610 TEST(MallocTests, DISABLED_leak_memory_limit_valloc) {
611   SetAllocationLimit();
612   Valloc();
613 }
614 #endif
615 
TEST_F(MallocDebugSystemTest,verify_leak)616 TEST_F(MallocDebugSystemTest, verify_leak) {
617   VerifyLeak("leak_memory_");
618 }
619 
TEST_F(MallocDebugSystemTest,verify_leak_allocation_limit)620 TEST_F(MallocDebugSystemTest, verify_leak_allocation_limit) {
621   SKIP_WITH_HWASAN;
622   VerifyLeak("leak_memory_limit_");
623 }
624 
625 static constexpr int kExpectedExitCode = 30;
626 static constexpr size_t kMaxThreads = sizeof(uint32_t) * 8;
627 
TEST(MallocTests,DISABLED_exit_while_threads_allocating)628 TEST(MallocTests, DISABLED_exit_while_threads_allocating) {
629   std::atomic_uint32_t thread_mask = {};
630 
631   for (size_t i = 0; i < kMaxThreads; i++) {
632     std::thread malloc_thread([&thread_mask, i] {
633       while (true) {
634         void* ptr = malloc(100);
635         if (ptr == nullptr) {
636           exit(1000);
637         }
638         free(ptr);
639         thread_mask.fetch_or(1U << i);
640       }
641     });
642     malloc_thread.detach();
643   }
644 
645   // Wait until each thread has done at least one allocation.
646   while (thread_mask.load() != UINT32_MAX)
647     ;
648   exit(kExpectedExitCode);
649 }
650 
651 // Verify that exiting while other threads are doing malloc operations,
652 // that there are no crashes.
TEST_F(MallocDebugSystemTest,exit_while_threads_allocating)653 TEST_F(MallocDebugSystemTest, exit_while_threads_allocating) {
654   for (size_t i = 0; i < 100; i++) {
655     SCOPED_TRACE(::testing::Message() << "Run " << i);
656     ASSERT_NO_FATAL_FAILURE(Exec("MallocTests.DISABLED_exit_while_threads_allocating",
657                                  "verbose backtrace", kExpectedExitCode));
658 
659     std::string log_str = log_crash_->GetLog();
660     ASSERT_TRUE(log_str.find("Fatal signal") == std::string::npos)
661         << "Found crash in log.\nLog message: " << log_str << " pid: " << pid_;
662   }
663 }
664 
TEST(MallocTests,DISABLED_exit_while_threads_freeing_allocs_with_header)665 TEST(MallocTests, DISABLED_exit_while_threads_freeing_allocs_with_header) {
666   static constexpr size_t kMaxAllocsPerThread = 1000;
667   std::atomic_uint32_t thread_mask = {};
668   std::atomic_bool run;
669 
670   std::vector<std::vector<void*>> allocs(kMaxThreads);
671   // Pre-allocate a bunch of memory so that we can try to trigger
672   // the frees after the main thread finishes.
673   for (size_t i = 0; i < kMaxThreads; i++) {
674     for (size_t j = 0; j < kMaxAllocsPerThread; j++) {
675       void* ptr = malloc(8);
676       ASSERT_TRUE(ptr != nullptr);
677       allocs[i].push_back(ptr);
678     }
679   }
680 
681   for (size_t i = 0; i < kMaxThreads; i++) {
682     std::thread malloc_thread([&thread_mask, &run, &allocs, i] {
683       thread_mask.fetch_or(1U << i);
684       while (!run)
685         ;
686       for (auto ptr : allocs[i]) {
687         free(ptr);
688       }
689     });
690     malloc_thread.detach();
691   }
692 
693   // Wait until all threads are running.
694   while (thread_mask.load() != UINT32_MAX)
695     ;
696   run = true;
697   exit(kExpectedExitCode);
698 }
699 
TEST_F(MallocDebugSystemTest,exit_while_threads_freeing_allocs_with_header)700 TEST_F(MallocDebugSystemTest, exit_while_threads_freeing_allocs_with_header) {
701   for (size_t i = 0; i < 50; i++) {
702     SCOPED_TRACE(::testing::Message() << "Run " << i);
703     // Enable guard to force the use of a header.
704     ASSERT_NO_FATAL_FAILURE(
705         Exec("MallocTests.DISABLED_exit_while_threads_freeing_allocs_with_header", "verbose guard",
706              kExpectedExitCode));
707 
708     std::string log_str = log_crash_->GetLog();
709     ASSERT_TRUE(log_str.find("Fatal signal") == std::string::npos)
710         << "Found crash in log.\nLog message: " << log_str << " pid: " << pid_;
711   }
712 }
713 
TEST(MallocTests,DISABLED_write_leak_info)714 TEST(MallocTests, DISABLED_write_leak_info) {
715   TemporaryFile tf;
716   ASSERT_TRUE(tf.fd != -1);
717 
718   FILE* fp = fdopen(tf.fd, "w+");
719   if (fp == nullptr) {
720     printf("Unable to create %s\n", tf.path);
721     _exit(1);
722   }
723   tf.release();
724 
725   void* ptr = malloc(1000);
726   if (ptr == nullptr) {
727     printf("malloc failed\n");
728     _exit(1);
729   }
730   memset(ptr, 0, 1000);
731 
732   android_mallopt(M_WRITE_MALLOC_LEAK_INFO_TO_FILE, fp, sizeof(fp));
733 
734   fclose(fp);
735 
736   free(ptr);
737 }
738 
TEST_F(MallocDebugSystemTest,write_leak_info_no_header)739 TEST_F(MallocDebugSystemTest, write_leak_info_no_header) {
740   unexpected_log_strings_.push_back(" HAS INVALID TAG ");
741   unexpected_log_strings_.push_back("USED AFTER FREE ");
742   unexpected_log_strings_.push_back("UNKNOWN POINTER ");
743   Exec("MallocTests.DISABLED_write_leak_info", "verbose backtrace");
744 }
745 
TEST_F(MallocDebugSystemTest,write_leak_info_header)746 TEST_F(MallocDebugSystemTest, write_leak_info_header) {
747   unexpected_log_strings_.push_back(" HAS INVALID TAG ");
748   unexpected_log_strings_.push_back("USED AFTER FREE ");
749   unexpected_log_strings_.push_back("UNKNOWN POINTER ");
750   Exec("MallocTests.DISABLED_write_leak_info", "verbose backtrace guard");
751 }
752 
TEST(MallocTests,DISABLED_malloc_and_backtrace_deadlock)753 TEST(MallocTests, DISABLED_malloc_and_backtrace_deadlock) {
754   std::atomic_bool running(false);
755   pid_t tid;
756   std::thread thread([&tid, &running] {
757     tid = gettid();
758     running = true;
759     while (running) {
760       void* ptr = malloc(200);
761       if (ptr == nullptr) {
762         return;
763       }
764       free(ptr);
765     }
766   });
767 
768   while (!running) {
769   }
770 
771   static constexpr size_t kNumUnwinds = 1000;
772   unwindstack::AndroidLocalUnwinder unwinder;
773   for (size_t i = 0; i < kNumUnwinds; i++) {
774     // Only verify that there is at least one frame in the unwind.
775     // This is not a test of the unwinder and clang for arm seems to
776     // produces an increasing number of code that does not have unwind
777     // information.
778     unwindstack::AndroidUnwinderData data;
779     ASSERT_TRUE(unwinder.Unwind(data)) << "Failed on unwind " << i;
780   }
781   running = false;
782   thread.join();
783 }
784 
TEST_F(MallocDebugSystemTest,malloc_and_backtrace_deadlock)785 TEST_F(MallocDebugSystemTest, malloc_and_backtrace_deadlock) {
786   // Make sure that malloc debug is enabled and that no timeouts occur during
787   // unwinds.
788   unexpected_log_strings_.push_back("Timed out waiting for ");
789   Exec("MallocTests.DISABLED_malloc_and_backtrace_deadlock", "verbose verify_pointers", 0);
790 }
791