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