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