diff --git a/compiler-rt/lib/scudo/standalone/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/CMakeLists.txt --- a/compiler-rt/lib/scudo/standalone/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/CMakeLists.txt @@ -25,7 +25,7 @@ append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SCUDO_CFLAGS) if(COMPILER_RT_DEBUG) - list(APPEND SCUDO_CFLAGS -O0 -DSCUDO_DEBUG=1) + list(APPEND SCUDO_CFLAGS -O0 -DSCUDO_DEBUG=1 -DSCUDO_ENABLE_HOOKS=1) else() list(APPEND SCUDO_CFLAGS -O3) endif() diff --git a/compiler-rt/lib/scudo/standalone/platform.h b/compiler-rt/lib/scudo/standalone/platform.h --- a/compiler-rt/lib/scudo/standalone/platform.h +++ b/compiler-rt/lib/scudo/standalone/platform.h @@ -73,6 +73,14 @@ #endif #endif +#ifndef SCUDO_ENABLE_HOOKS +#if SCUDO_FUCHSIA +#define SCUDO_ENABLE_HOOKS 1 +#else +#define SCUDO_ENABLE_HOOKS 0 +#endif +#endif + #ifndef SCUDO_MIN_ALIGNMENT_LOG // We force malloc-type functions to be aligned to std::max_align_t, but there // is no reason why the minimum alignment for all other functions can't be 8 diff --git a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt --- a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt @@ -19,7 +19,10 @@ -Wno-mismatched-new-delete) if(COMPILER_RT_DEBUG) - list(APPEND SCUDO_UNITTEST_CFLAGS -DSCUDO_DEBUG=1) + list(APPEND SCUDO_UNITTEST_CFLAGS -DSCUDO_DEBUG=1 -DSCUDO_ENABLE_HOOKS=1) + if (NOT FUCHSIA) + list(APPEND SCUDO_UNITTEST_CFLAGS -DSCUDO_ENABLE_HOOKS_TESTS=1) + endif() endif() if(ANDROID) diff --git a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp @@ -37,6 +37,23 @@ #define HAVE_VALLOC 1 #endif +extern "C" { +void malloc_enable(void); +void malloc_disable(void); +int malloc_iterate(uintptr_t base, size_t size, + void (*callback)(uintptr_t base, size_t size, void *arg), + void *arg); +void *valloc(size_t size); +void *pvalloc(size_t size); + +#ifndef SCUDO_ENABLE_HOOKS_TESTS +#define SCUDO_ENABLE_HOOKS_TESTS 0 +#endif + +#if (SCUDO_ENABLE_HOOKS_TESTS == 1) && (SCUDO_ENABLE_HOOKS == 0) +#error "Hooks tests should have hooks enabled as well!" +#endif + struct AllocContext { void *Ptr; size_t Size; @@ -47,15 +64,7 @@ static AllocContext AC; static DeallocContext DC; -extern "C" { -void malloc_enable(void); -void malloc_disable(void); -int malloc_iterate(uintptr_t base, size_t size, - void (*callback)(uintptr_t base, size_t size, void *arg), - void *arg); -void *valloc(size_t size); -void *pvalloc(size_t size); - +#if (SCUDO_ENABLE_HOOKS_TESTS == 1) __attribute__((visibility("default"))) void __scudo_allocate_hook(void *Ptr, size_t Size) { AC.Ptr = Ptr; @@ -64,8 +73,35 @@ __attribute__((visibility("default"))) void __scudo_deallocate_hook(void *Ptr) { DC.Ptr = Ptr; } +#endif // (SCUDO_ENABLE_HOOKS_TESTS == 1) } +class ScudoWrappersCTest : public Test { +protected: + void SetUp() override { + if (SCUDO_ENABLE_HOOKS && !SCUDO_ENABLE_HOOKS_TESTS) + printf("Hooks are enabled but hooks tests are disabled.\n"); + } + + void invalidateAllocHookPtrAs(UNUSED void *Ptr) { + if (SCUDO_ENABLE_HOOKS_TESTS) + AC.Ptr = Ptr; + } + void verifyAllocHookPtr(UNUSED void *Ptr) { + if (SCUDO_ENABLE_HOOKS_TESTS) + EXPECT_EQ(Ptr, AC.Ptr); + } + void verifyAllocHookSize(UNUSED size_t Size) { + if (SCUDO_ENABLE_HOOKS_TESTS) + EXPECT_EQ(Size, AC.Size); + } + void verifyDeallocHookPtr(UNUSED void *Ptr) { + if (SCUDO_ENABLE_HOOKS_TESTS) + EXPECT_EQ(Ptr, DC.Ptr); + } +}; +using ScudoWrappersCDeathTest = ScudoWrappersCTest; + // Note that every C allocation function in the test binary will be fulfilled // by Scudo (this includes the gtest APIs, etc.), which is a test by itself. // But this might also lead to unexpected side-effects, since the allocation and @@ -78,13 +114,13 @@ static const size_t Size = 100U; -TEST(ScudoWrappersCDeathTest, Malloc) { +TEST_F(ScudoWrappersCDeathTest, Malloc) { void *P = malloc(Size); EXPECT_NE(P, nullptr); EXPECT_LE(Size, malloc_usable_size(P)); EXPECT_EQ(reinterpret_cast(P) % FIRST_32_SECOND_64(8U, 16U), 0U); - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(Size, AC.Size); + verifyAllocHookPtr(P); + verifyAllocHookSize(Size); // An update to this warning in Clang now triggers in this line, but it's ok // because the check is expecting a bad pointer and should fail. @@ -99,7 +135,7 @@ #endif free(P); - EXPECT_EQ(P, DC.Ptr); + verifyDeallocHookPtr(P); EXPECT_DEATH(free(P), ""); P = malloc(0U); @@ -111,16 +147,16 @@ EXPECT_EQ(errno, ENOMEM); } -TEST(ScudoWrappersCTest, Calloc) { +TEST_F(ScudoWrappersCTest, Calloc) { void *P = calloc(1U, Size); EXPECT_NE(P, nullptr); EXPECT_LE(Size, malloc_usable_size(P)); - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(Size, AC.Size); + verifyAllocHookPtr(P); + verifyAllocHookSize(Size); for (size_t I = 0; I < Size; I++) EXPECT_EQ((reinterpret_cast(P))[I], 0U); free(P); - EXPECT_EQ(P, DC.Ptr); + verifyDeallocHookPtr(P); P = calloc(1U, 0U); EXPECT_NE(P, nullptr); @@ -141,7 +177,7 @@ EXPECT_EQ(errno, ENOMEM); } -TEST(ScudoWrappersCTest, SmallAlign) { +TEST_F(ScudoWrappersCTest, SmallAlign) { // Allocating pointers by the powers of 2 from 1 to 0x10000 // Using powers of 2 due to memalign using powers of 2 and test more sizes constexpr size_t MaxSize = 0x10000; @@ -162,7 +198,7 @@ free(ptr); } -TEST(ScudoWrappersCTest, Memalign) { +TEST_F(ScudoWrappersCTest, Memalign) { void *P; for (size_t I = FIRST_32_SECOND_64(2U, 3U); I <= 18U; I++) { const size_t Alignment = 1U << I; @@ -171,20 +207,20 @@ EXPECT_NE(P, nullptr); EXPECT_LE(Size, malloc_usable_size(P)); EXPECT_EQ(reinterpret_cast(P) % Alignment, 0U); - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(Size, AC.Size); + verifyAllocHookPtr(P); + verifyAllocHookSize(Size); free(P); - EXPECT_EQ(P, DC.Ptr); + verifyDeallocHookPtr(P); P = nullptr; EXPECT_EQ(posix_memalign(&P, Alignment, Size), 0); EXPECT_NE(P, nullptr); EXPECT_LE(Size, malloc_usable_size(P)); EXPECT_EQ(reinterpret_cast(P) % Alignment, 0U); - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(Size, AC.Size); + verifyAllocHookPtr(P); + verifyAllocHookSize(Size); free(P); - EXPECT_EQ(P, DC.Ptr); + verifyDeallocHookPtr(P); } EXPECT_EQ(memalign(4096U, SIZE_MAX), nullptr); @@ -196,24 +232,24 @@ for (size_t Alignment = 0U; Alignment <= 128U; Alignment++) { P = memalign(Alignment, 1024U); EXPECT_NE(P, nullptr); - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(Size, AC.Size); + verifyAllocHookPtr(P); + verifyAllocHookSize(Size); free(P); - EXPECT_EQ(P, DC.Ptr); + verifyDeallocHookPtr(P); } } } -TEST(ScudoWrappersCTest, AlignedAlloc) { +TEST_F(ScudoWrappersCTest, AlignedAlloc) { const size_t Alignment = 4096U; void *P = aligned_alloc(Alignment, Alignment * 4U); EXPECT_NE(P, nullptr); EXPECT_LE(Alignment * 4U, malloc_usable_size(P)); EXPECT_EQ(reinterpret_cast(P) % Alignment, 0U); - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(Alignment * 4U, AC.Size); + verifyAllocHookPtr(P); + verifyAllocHookSize(Alignment * 4U); free(P); - EXPECT_EQ(P, DC.Ptr); + verifyDeallocHookPtr(P); errno = 0; P = aligned_alloc(Alignment, Size); @@ -221,27 +257,27 @@ EXPECT_EQ(errno, EINVAL); } -TEST(ScudoWrappersCDeathTest, Realloc) { +TEST_F(ScudoWrappersCDeathTest, Realloc) { // realloc(nullptr, N) is malloc(N) void *P = realloc(nullptr, Size); EXPECT_NE(P, nullptr); - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(Size, AC.Size); + verifyAllocHookPtr(P); + verifyAllocHookSize(Size); free(P); - EXPECT_EQ(P, DC.Ptr); + verifyDeallocHookPtr(P); P = malloc(Size); EXPECT_NE(P, nullptr); // realloc(P, 0U) is free(P) and returns nullptr EXPECT_EQ(realloc(P, 0U), nullptr); - EXPECT_EQ(P, DC.Ptr); + verifyDeallocHookPtr(P); P = malloc(Size); EXPECT_NE(P, nullptr); EXPECT_LE(Size, malloc_usable_size(P)); memset(P, 0x42, Size); - AC.Ptr = reinterpret_cast(0xdeadbeef); + invalidateAllocHookPtrAs(reinterpret_cast(0xdeadbeef)); void *OldP = P; P = realloc(P, Size * 2U); EXPECT_NE(P, nullptr); @@ -249,14 +285,14 @@ for (size_t I = 0; I < Size; I++) EXPECT_EQ(0x42, (reinterpret_cast(P))[I]); if (OldP == P) { - EXPECT_EQ(AC.Ptr, reinterpret_cast(0xdeadbeef)); + verifyAllocHookPtr(reinterpret_cast(0xdeadbeef)); } else { - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(Size * 2U, AC.Size); - EXPECT_EQ(OldP, DC.Ptr); + verifyAllocHookPtr(P); + verifyAllocHookSize(Size * 2U); + verifyDeallocHookPtr(OldP); } - AC.Ptr = reinterpret_cast(0xdeadbeef); + invalidateAllocHookPtrAs(reinterpret_cast(0xdeadbeef)); OldP = P; P = realloc(P, Size / 2U); EXPECT_NE(P, nullptr); @@ -264,10 +300,10 @@ for (size_t I = 0; I < Size / 2U; I++) EXPECT_EQ(0x42, (reinterpret_cast(P))[I]); if (OldP == P) { - EXPECT_EQ(AC.Ptr, reinterpret_cast(0xdeadbeef)); + verifyAllocHookPtr(reinterpret_cast(0xdeadbeef)); } else { - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(Size / 2U, AC.Size); + verifyAllocHookPtr(P); + verifyAllocHookSize(Size / 2U); } free(P); @@ -302,7 +338,7 @@ } #if !SCUDO_FUCHSIA -TEST(ScudoWrappersCTest, MallOpt) { +TEST_F(ScudoWrappersCTest, MallOpt) { errno = 0; EXPECT_EQ(mallopt(-1000, 1), 0); // mallopt doesn't set errno. @@ -323,7 +359,7 @@ } #endif -TEST(ScudoWrappersCTest, OtherAlloc) { +TEST_F(ScudoWrappersCTest, OtherAlloc) { #if HAVE_PVALLOC const size_t PageSize = static_cast(sysconf(_SC_PAGESIZE)); @@ -331,11 +367,11 @@ EXPECT_NE(P, nullptr); EXPECT_EQ(reinterpret_cast(P) & (PageSize - 1), 0U); EXPECT_LE(PageSize, malloc_usable_size(P)); - EXPECT_EQ(P, AC.Ptr); + verifyAllocHookPtr(P); // Size will be rounded up to PageSize. - EXPECT_EQ(PageSize, AC.Size); + verifyAllocHookSize(PageSize); free(P); - EXPECT_EQ(P, DC.Ptr); + verifyDeallocHookPtr(P); EXPECT_EQ(pvalloc(SIZE_MAX), nullptr); @@ -351,7 +387,7 @@ } #if !SCUDO_FUCHSIA -TEST(ScudoWrappersCTest, MallInfo) { +TEST_F(ScudoWrappersCTest, MallInfo) { // mallinfo is deprecated. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" @@ -372,7 +408,7 @@ #endif #if __GLIBC_PREREQ(2, 33) -TEST(ScudoWrappersCTest, MallInfo2) { +TEST_F(ScudoWrappersCTest, MallInfo2) { const size_t BypassQuarantineSize = 1024U; struct mallinfo2 MI = mallinfo2(); size_t Allocated = MI.uordblks; @@ -404,7 +440,7 @@ // To achieve this, we allocate a chunk for which the backing block will be // aligned on a page, then run the malloc_iterate on both the pages that the // block is a boundary for. It must only be seen once by the callback function. -TEST(ScudoWrappersCTest, MallocIterateBoundary) { +TEST_F(ScudoWrappersCTest, MallocIterateBoundary) { const size_t PageSize = static_cast(sysconf(_SC_PAGESIZE)); #if SCUDO_ANDROID // Android uses a 16 byte alignment for both 32 bit and 64 bit. @@ -456,7 +492,7 @@ // Fuchsia doesn't have alarm, fork or malloc_info. #if !SCUDO_FUCHSIA -TEST(ScudoWrappersCDeathTest, MallocDisableDeadlock) { +TEST_F(ScudoWrappersCDeathTest, MallocDisableDeadlock) { // We expect heap operations within a disable/enable scope to deadlock. EXPECT_DEATH( { @@ -471,7 +507,7 @@ ""); } -TEST(ScudoWrappersCTest, MallocInfo) { +TEST_F(ScudoWrappersCTest, MallocInfo) { // Use volatile so that the allocations don't get optimized away. void *volatile P1 = malloc(1234); void *volatile P2 = malloc(4321); @@ -491,7 +527,7 @@ free(P2); } -TEST(ScudoWrappersCDeathTest, Fork) { +TEST_F(ScudoWrappersCDeathTest, Fork) { void *P; pid_t Pid = fork(); EXPECT_GE(Pid, 0) << strerror(errno); @@ -543,7 +579,7 @@ return nullptr; } -TEST(ScudoWrappersCTest, DisableForkEnable) { +TEST_F(ScudoWrappersCTest, DisableForkEnable) { pthread_t ThreadId; Ready = false; EXPECT_EQ(pthread_create(&ThreadId, nullptr, &enableMalloc, nullptr), 0); diff --git a/compiler-rt/lib/scudo/standalone/tests/wrappers_cpp_test.cpp b/compiler-rt/lib/scudo/standalone/tests/wrappers_cpp_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/wrappers_cpp_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/wrappers_cpp_test.cpp @@ -24,6 +24,18 @@ #define SKIP_MISMATCH_TESTS 0 #endif +void operator delete(void *, size_t) noexcept; +void operator delete[](void *, size_t) noexcept; + +extern "C" { +#ifndef SCUDO_ENABLE_HOOKS_TESTS +#define SCUDO_ENABLE_HOOKS_TESTS 0 +#endif + +#if (SCUDO_ENABLE_HOOKS_TESTS == 1) && (SCUDO_ENABLE_HOOKS == 0) +#error "Hooks tests should have hooks enabled as well!" +#endif + struct AllocContext { void *Ptr; size_t Size; @@ -34,10 +46,7 @@ static AllocContext AC; static DeallocContext DC; -void operator delete(void *, size_t) noexcept; -void operator delete[](void *, size_t) noexcept; - -extern "C" { +#if (SCUDO_ENABLE_HOOKS_TESTS == 1) __attribute__((visibility("default"))) void __scudo_allocate_hook(void *Ptr, size_t Size) { AC.Ptr = Ptr; @@ -46,60 +55,81 @@ __attribute__((visibility("default"))) void __scudo_deallocate_hook(void *Ptr) { DC.Ptr = Ptr; } +#endif // (SCUDO_ENABLE_HOOKS_TESTS == 1) } -// Note that every Cxx allocation function in the test binary will be fulfilled -// by Scudo. See the comment in the C counterpart of this file. -template static void testCxxNew() { - T *P = new T; - EXPECT_NE(P, nullptr); - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(sizeof(T), AC.Size); - memset(P, 0x42, sizeof(T)); - EXPECT_DEATH(delete[] P, ""); - delete P; - EXPECT_EQ(P, DC.Ptr); - EXPECT_DEATH(delete P, ""); - - P = new T; - EXPECT_NE(P, nullptr); - memset(P, 0x42, sizeof(T)); - operator delete(P, sizeof(T)); - EXPECT_EQ(P, DC.Ptr); - - P = new (std::nothrow) T; - EXPECT_EQ(P, AC.Ptr); - EXPECT_EQ(sizeof(T), AC.Size); - EXPECT_NE(P, nullptr); - memset(P, 0x42, sizeof(T)); - delete P; - EXPECT_EQ(P, DC.Ptr); - - const size_t N = 16U; - T *A = new T[N]; - EXPECT_NE(A, nullptr); - EXPECT_EQ(A, AC.Ptr); - EXPECT_EQ(sizeof(T) * N, AC.Size); - memset(A, 0x42, sizeof(T) * N); - EXPECT_DEATH(delete A, ""); - delete[] A; - EXPECT_EQ(A, DC.Ptr); - EXPECT_DEATH(delete[] A, ""); - - A = new T[N]; - EXPECT_NE(A, nullptr); - memset(A, 0x42, sizeof(T) * N); - operator delete[](A, sizeof(T) * N); - EXPECT_EQ(A, DC.Ptr); - - A = new (std::nothrow) T[N]; - EXPECT_EQ(A, AC.Ptr); - EXPECT_EQ(sizeof(T) * N, AC.Size); - EXPECT_NE(A, nullptr); - memset(A, 0x42, sizeof(T) * N); - delete[] A; - EXPECT_EQ(A, DC.Ptr); -} +class ScudoWrappersCppTest : public Test { +protected: + void SetUp() override { + if (SCUDO_ENABLE_HOOKS && !SCUDO_ENABLE_HOOKS_TESTS) + printf("Hooks are enabled but hooks tests are disabled.\n"); + } + + void verifyAllocHookPtr(UNUSED void *Ptr) { + if (SCUDO_ENABLE_HOOKS_TESTS) + EXPECT_EQ(Ptr, AC.Ptr); + } + void verifyAllocHookSize(UNUSED size_t Size) { + if (SCUDO_ENABLE_HOOKS_TESTS) + EXPECT_EQ(Size, AC.Size); + } + void verifyDeallocHookPtr(UNUSED void *Ptr) { + if (SCUDO_ENABLE_HOOKS_TESTS) + EXPECT_EQ(Ptr, DC.Ptr); + } + + template void testCxxNew() { + T *P = new T; + EXPECT_NE(P, nullptr); + verifyAllocHookPtr(P); + verifyAllocHookSize(sizeof(T)); + memset(P, 0x42, sizeof(T)); + EXPECT_DEATH(delete[] P, ""); + delete P; + verifyDeallocHookPtr(P); + EXPECT_DEATH(delete P, ""); + + P = new T; + EXPECT_NE(P, nullptr); + memset(P, 0x42, sizeof(T)); + operator delete(P, sizeof(T)); + verifyDeallocHookPtr(P); + + P = new (std::nothrow) T; + verifyAllocHookPtr(P); + verifyAllocHookSize(sizeof(T)); + EXPECT_NE(P, nullptr); + memset(P, 0x42, sizeof(T)); + delete P; + verifyDeallocHookPtr(P); + + const size_t N = 16U; + T *A = new T[N]; + EXPECT_NE(A, nullptr); + verifyAllocHookPtr(A); + verifyAllocHookSize(sizeof(T) * N); + memset(A, 0x42, sizeof(T) * N); + EXPECT_DEATH(delete A, ""); + delete[] A; + verifyDeallocHookPtr(A); + EXPECT_DEATH(delete[] A, ""); + + A = new T[N]; + EXPECT_NE(A, nullptr); + memset(A, 0x42, sizeof(T) * N); + operator delete[](A, sizeof(T) * N); + verifyDeallocHookPtr(A); + + A = new (std::nothrow) T[N]; + verifyAllocHookPtr(A); + verifyAllocHookSize(sizeof(T) * N); + EXPECT_NE(A, nullptr); + memset(A, 0x42, sizeof(T) * N); + delete[] A; + verifyDeallocHookPtr(A); + } +}; +using ScudoWrappersCppDeathTest = ScudoWrappersCppTest; class Pixel { public: @@ -109,7 +139,10 @@ Color C = Color::Red; }; -TEST(ScudoWrappersCppDeathTest, New) { +// Note that every Cxx allocation function in the test binary will be fulfilled +// by Scudo. See the comment in the C counterpart of this file. + +TEST_F(ScudoWrappersCppDeathTest, New) { if (getenv("SKIP_TYPE_MISMATCH") || SKIP_MISMATCH_TESTS) { printf("Skipped type mismatch tests.\n"); return; @@ -150,7 +183,7 @@ } } -TEST(ScudoWrappersCppTest, ThreadedNew) { +TEST_F(ScudoWrappersCppTest, ThreadedNew) { // TODO: Investigate why libc sometimes crashes with tag missmatch in // __pthread_clockjoin_ex. std::unique_ptr NoTags; @@ -172,7 +205,7 @@ } #if !SCUDO_FUCHSIA -TEST(ScudoWrappersCppTest, AllocAfterFork) { +TEST_F(ScudoWrappersCppTest, AllocAfterFork) { // This test can fail flakily when ran as a part of large number of // other tests if the maxmimum number of mappings allowed is low. // We tried to reduce the number of iterations of the loops with diff --git a/compiler-rt/lib/scudo/standalone/wrappers_c.cpp b/compiler-rt/lib/scudo/standalone/wrappers_c.cpp --- a/compiler-rt/lib/scudo/standalone/wrappers_c.cpp +++ b/compiler-rt/lib/scudo/standalone/wrappers_c.cpp @@ -12,6 +12,8 @@ #if !SCUDO_ANDROID || !_BIONIC #include "allocator_config.h" +#include "internal_defs.h" +#include "platform.h" #include "scudo/interface.h" #include "wrappers_c.h" #include "wrappers_c_checks.h" diff --git a/compiler-rt/lib/scudo/standalone/wrappers_c.inc b/compiler-rt/lib/scudo/standalone/wrappers_c.inc --- a/compiler-rt/lib/scudo/standalone/wrappers_c.inc +++ b/compiler-rt/lib/scudo/standalone/wrappers_c.inc @@ -18,13 +18,14 @@ #endif static void reportAllocation(void *ptr, size_t size) { - if (__scudo_allocate_hook && ptr) - __scudo_allocate_hook(ptr, size); + if (SCUDO_ENABLE_HOOKS) + if (__scudo_allocate_hook && ptr) + __scudo_allocate_hook(ptr, size); } - static void reportDeallocation(void *ptr) { - if (__scudo_deallocate_hook) - __scudo_deallocate_hook(ptr); + if (SCUDO_ENABLE_HOOKS) + if (__scudo_deallocate_hook) + __scudo_deallocate_hook(ptr); } extern "C" { diff --git a/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp b/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp --- a/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp +++ b/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp @@ -12,6 +12,8 @@ #if SCUDO_ANDROID && _BIONIC #include "allocator_config.h" +#include "internal_defs.h" +#include "platform.h" #include "scudo/interface.h" #include "wrappers_c.h" #include "wrappers_c_checks.h" diff --git a/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp b/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp --- a/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp +++ b/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp @@ -12,6 +12,8 @@ #if !SCUDO_ANDROID || !_BIONIC #include "allocator_config.h" +#include "internal_defs.h" +#include "platform.h" #include "scudo/interface.h" #include "wrappers_c.h" @@ -23,13 +25,14 @@ } // namespace std static void reportAllocation(void *ptr, size_t size) { - if (__scudo_allocate_hook && ptr) - __scudo_allocate_hook(ptr, size); + if (SCUDO_ENABLE_HOOKS) + if (__scudo_allocate_hook && ptr) + __scudo_allocate_hook(ptr, size); } - static void reportDeallocation(void *ptr) { - if (__scudo_deallocate_hook) - __scudo_deallocate_hook(ptr); + if (SCUDO_ENABLE_HOOKS) + if (__scudo_deallocate_hook) + __scudo_deallocate_hook(ptr); } INTERFACE WEAK void *operator new(size_t size) {