1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <sys/time.h>
18 
19 #include <chrono>
20 #include <functional>
21 
22 #include <gtest/gtest.h>
23 #include <ScopedDisableMalloc.h>
24 
25 using namespace std::chrono_literals;
26 
27 class DisableMallocTest : public ::testing::Test {
28  protected:
alarm(std::chrono::microseconds us)29   void alarm(std::chrono::microseconds us) {
30     std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(us);
31     itimerval t = itimerval();
32     t.it_value.tv_sec = s.count();
33     t.it_value.tv_usec = (us - s).count();
34     setitimer(ITIMER_REAL, &t, NULL);
35   }
36 };
37 
TEST_F(DisableMallocTest,reenable)38 TEST_F(DisableMallocTest, reenable) {
39   ASSERT_EXIT({
40     alarm(100ms);
41     void *ptr1 = malloc(128);
42     ASSERT_NE(ptr1, nullptr);
43     free(ptr1);
44     {
45       ScopedDisableMalloc disable_malloc;
46     }
47     void *ptr2 = malloc(128);
48     ASSERT_NE(ptr2, nullptr);
49     free(ptr2);
50     _exit(1);
51   }, ::testing::ExitedWithCode(1), "");
52 }
53 
TEST_F(DisableMallocTest,deadlock_allocate)54 TEST_F(DisableMallocTest, deadlock_allocate) {
55   ASSERT_DEATH({
56     void *ptr = malloc(128);
57     ASSERT_NE(ptr, nullptr);
58     free(ptr);
59     {
60       alarm(100ms);
61       ScopedDisableMalloc disable_malloc;
62       void* ptr = malloc(128);
63       ASSERT_NE(ptr, nullptr);
64       free(ptr);
65     }
66   }, "");
67 }
68 
TEST_F(DisableMallocTest,deadlock_new)69 TEST_F(DisableMallocTest, deadlock_new) {
70   ASSERT_DEATH({
71     char* ptr = new(char);
72     ASSERT_NE(ptr, nullptr);
73     delete(ptr);
74     {
75       alarm(100ms);
76       ScopedDisableMalloc disable_malloc;
77       char* ptr = new(char);
78       ASSERT_NE(ptr, nullptr);
79       delete(ptr);
80     }
81   }, "");
82 }
83 
TEST_F(DisableMallocTest,deadlock_delete)84 TEST_F(DisableMallocTest, deadlock_delete) {
85   ASSERT_DEATH({
86     char* ptr = new(char);
87     ASSERT_NE(ptr, nullptr);
88     {
89       alarm(250ms);
90       ScopedDisableMalloc disable_malloc;
91       delete(ptr);
92     }
93   }, "");
94 }
95 
TEST_F(DisableMallocTest,deadlock_free)96 TEST_F(DisableMallocTest, deadlock_free) {
97   ASSERT_DEATH({
98     void *ptr = malloc(128);
99     ASSERT_NE(ptr, nullptr);
100     {
101       alarm(100ms);
102       ScopedDisableMalloc disable_malloc;
103       free(ptr);
104     }
105   }, "");
106 }
107 
TEST_F(DisableMallocTest,deadlock_fork)108 TEST_F(DisableMallocTest, deadlock_fork) {
109   ASSERT_DEATH({
110     {
111       alarm(100ms);
112       ScopedDisableMalloc disable_malloc;
113       fork();
114     }
115   }, "");
116 }
117