• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <android-base/test_utils.h>
23 
24 #include <ScopedDisableMalloc.h>
25 #include <gtest/gtest.h>
26 
27 using namespace std::chrono_literals;
28 
29 namespace android {
30 
31 class DisableMallocTest : public ::testing::Test {
32  protected:
alarm(std::chrono::microseconds us)33   void alarm(std::chrono::microseconds us) {
34     std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(us);
35     itimerval t = itimerval();
36     t.it_value.tv_sec = s.count();
37     t.it_value.tv_usec = (us - s).count();
38     setitimer(ITIMER_REAL, &t, NULL);
39   }
40 
SetUp()41   void SetUp() override {
42     // HWASan does not support malloc_disable.
43     SKIP_WITH_HWASAN;
44   }
45 };
46 
TEST_F(DisableMallocTest,reenable)47 TEST_F(DisableMallocTest, reenable) {
48   ASSERT_EXIT(
49       {
50         alarm(100ms);
51         void* ptr1 = malloc(128);
52         ASSERT_NE(ptr1, nullptr);
53         free(ptr1);
54         { ScopedDisableMalloc disable_malloc; }
55         void* ptr2 = malloc(128);
56         ASSERT_NE(ptr2, nullptr);
57         free(ptr2);
58         _exit(1);
59       },
60       ::testing::ExitedWithCode(1), "");
61 }
62 
TEST_F(DisableMallocTest,deadlock_allocate)63 TEST_F(DisableMallocTest, deadlock_allocate) {
64   ASSERT_DEATH(
65       {
66         void* ptr = malloc(128);
67         ASSERT_NE(ptr, nullptr);
68         free(ptr);
69         {
70           alarm(100ms);
71           ScopedDisableMalloc disable_malloc;
72           void* ptr = malloc(128);
73           ASSERT_NE(ptr, nullptr);
74           free(ptr);
75         }
76       },
77       "");
78 }
79 
TEST_F(DisableMallocTest,deadlock_new)80 TEST_F(DisableMallocTest, deadlock_new) {
81   ASSERT_DEATH(
82       {
83         // C++ allows `new Foo` to be replaced with a stack allocation or merged
84         // with future `new Foo` expressions, provided certain conditions are
85         // met [expr.new/10]. None of this applies to `operator new(size_t)`.
86         void* ptr = ::operator new(1);
87         ASSERT_NE(ptr, nullptr);
88         ::operator delete(ptr);
89         {
90           alarm(100ms);
91           ScopedDisableMalloc disable_malloc;
92           void* ptr = ::operator new(1);
93           ASSERT_NE(ptr, nullptr);
94           ::operator delete(ptr);
95         }
96       },
97       "");
98 }
99 
TEST_F(DisableMallocTest,deadlock_delete)100 TEST_F(DisableMallocTest, deadlock_delete) {
101   ASSERT_DEATH(
102       {
103         void* ptr = ::operator new(1);
104         ASSERT_NE(ptr, nullptr);
105         {
106           alarm(250ms);
107           ScopedDisableMalloc disable_malloc;
108           ::operator delete(ptr);
109         }
110       },
111       "");
112 }
113 
TEST_F(DisableMallocTest,deadlock_free)114 TEST_F(DisableMallocTest, deadlock_free) {
115   ASSERT_DEATH(
116       {
117         void* ptr = malloc(128);
118         ASSERT_NE(ptr, nullptr);
119         {
120           alarm(100ms);
121           ScopedDisableMalloc disable_malloc;
122           free(ptr);
123         }
124       },
125       "");
126 }
127 
TEST_F(DisableMallocTest,deadlock_fork)128 TEST_F(DisableMallocTest, deadlock_fork) {
129   ASSERT_DEATH({
130     {
131       alarm(100ms);
132       ScopedDisableMalloc disable_malloc;
133       fork();
134 }
135 }, "");
136 }
137 
138 }  // namespace android
139