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