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