diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h --- a/compiler-rt/lib/scudo/standalone/secondary.h +++ b/compiler-rt/lib/scudo/standalone/secondary.h @@ -119,7 +119,7 @@ const uptr RoundedSize = roundUpTo(Size + LargeBlock::getHeaderSize(), PageSize); - if (MaxFreeListSize && AlignmentHint < PageSize) { + if (!SCUDO_FUCHSIA && MaxFreeListSize && AlignmentHint < PageSize) { ScopedLock L(Mutex); for (auto &H : FreeBlocks) { const uptr FreeBlockSize = H.BlockEnd - reinterpret_cast(&H); @@ -205,14 +205,16 @@ template void MapAllocator::deallocate(void *Ptr) { LargeBlock::Header *H = LargeBlock::getHeader(Ptr); + const uptr Block = reinterpret_cast(H); { ScopedLock L(Mutex); InUseBlocks.remove(H); - const uptr CommitSize = H->BlockEnd - reinterpret_cast(H); + const uptr CommitSize = H->BlockEnd - Block; FreedBytes += CommitSize; NumberOfFrees++; Stats.sub(StatAllocated, CommitSize); - if (MaxFreeListSize && FreeBlocks.size() < MaxFreeListSize) { + if (!SCUDO_FUCHSIA && MaxFreeListSize && + FreeBlocks.size() < MaxFreeListSize) { bool Inserted = false; for (auto &F : FreeBlocks) { const uptr FreeBlockSize = F.BlockEnd - reinterpret_cast(&F); @@ -225,11 +227,10 @@ if (!Inserted) FreeBlocks.push_back(H); const uptr RoundedAllocationStart = - roundUpTo(reinterpret_cast(H) + LargeBlock::getHeaderSize(), - getPageSizeCached()); + roundUpTo(Block + LargeBlock::getHeaderSize(), getPageSizeCached()); MapPlatformData Data = H->Data; // TODO(kostyak): use release_to_os_interval_ms - releasePagesToOS(H->MapBase, RoundedAllocationStart - H->MapBase, + releasePagesToOS(Block, RoundedAllocationStart - Block, H->BlockEnd - RoundedAllocationStart, &Data); return; } diff --git a/compiler-rt/lib/scudo/standalone/tests/atomic_test.cpp b/compiler-rt/lib/scudo/standalone/tests/atomic_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/atomic_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/atomic_test.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "scudo/standalone/atomic_helpers.h" -#include "gtest/gtest.h" +#include "tests/scudo_unit_test.h" + +#include "atomic_helpers.h" namespace scudo { diff --git a/compiler-rt/lib/scudo/standalone/tests/bytemap_test.cpp b/compiler-rt/lib/scudo/standalone/tests/bytemap_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/bytemap_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/bytemap_test.cpp @@ -6,10 +6,11 @@ // //===----------------------------------------------------------------------===// -#include "bytemap.h" +#include "tests/scudo_unit_test.h" -#include "gtest/gtest.h" +#include "bytemap.h" +#include #include template void testMap(T &Map, scudo::uptr Size) { diff --git a/compiler-rt/lib/scudo/standalone/tests/checksum_test.cpp b/compiler-rt/lib/scudo/standalone/tests/checksum_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/checksum_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/checksum_test.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "checksum.h" +#include "tests/scudo_unit_test.h" -#include "gtest/gtest.h" +#include "checksum.h" #include diff --git a/compiler-rt/lib/scudo/standalone/tests/chunk_test.cpp b/compiler-rt/lib/scudo/standalone/tests/chunk_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/chunk_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/chunk_test.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "chunk.h" +#include "tests/scudo_unit_test.h" -#include "gtest/gtest.h" +#include "chunk.h" #include diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp @@ -6,14 +6,15 @@ // //===----------------------------------------------------------------------===// +#include "tests/scudo_unit_test.h" + #include "allocator_config.h" #include "combined.h" -#include "gtest/gtest.h" - #include #include #include +#include static std::mutex Mutex; static std::condition_variable Cv; @@ -21,17 +22,6 @@ static constexpr scudo::Chunk::Origin Origin = scudo::Chunk::Origin::Malloc; -// This allows us to turn on the Quarantine for specific tests. The Quarantine -// parameters are on the low end, to avoid having to loop excessively in some -// tests. -static bool UseQuarantine = false; -extern "C" const char *__scudo_default_options() { - if (!UseQuarantine) - return ""; - return "quarantine_size_kb=256:thread_local_quarantine_size_kb=128:" - "quarantine_max_chunk_size=1024"; -} - template static void testAllocator() { using AllocatorT = scudo::Allocator; auto Deleter = [](AllocatorT *A) { @@ -168,15 +158,17 @@ } TEST(ScudoCombinedTest, BasicCombined) { + UseQuarantine = false; +#if !SCUDO_FUCHSIA testAllocator(); +#endif #if SCUDO_WORDSIZE == 64U testAllocator(); #endif // The following configs should work on all platforms. + testAllocator(); UseQuarantine = true; testAllocator(); - UseQuarantine = false; - testAllocator(); } template static void stressAllocator(AllocatorT *A) { @@ -223,20 +215,22 @@ } TEST(ScudoCombinedTest, ThreadedCombined) { + UseQuarantine = false; +#if !SCUDO_FUCHSIA testAllocatorThreaded(); +#endif #if SCUDO_WORDSIZE == 64U testAllocatorThreaded(); #endif + testAllocatorThreaded(); UseQuarantine = true; testAllocatorThreaded(); - UseQuarantine = false; - testAllocatorThreaded(); } struct DeathConfig { // Tiny allocator, its Primary only serves chunks of 1024 bytes. using DeathSizeClassMap = scudo::SizeClassMap<1U, 10U, 10U, 10U, 1U, 10U>; - typedef scudo::SizeClassAllocator32 Primary; + typedef scudo::SizeClassAllocator64 Primary; typedef scudo::MapAllocator<0U> Secondary; template using TSDRegistryT = scudo::TSDRegistrySharedT; }; @@ -258,8 +252,8 @@ // Invalid sized deallocation. EXPECT_DEATH(Allocator->deallocate(P, Origin, Size + 8U), ""); - // Misaligned pointer. - void *MisalignedP = + // Misaligned pointer. Potentially unused if EXPECT_DEATH isn't available. + UNUSED void *MisalignedP = reinterpret_cast(reinterpret_cast(P) | 1U); EXPECT_DEATH(Allocator->deallocate(MisalignedP, Origin, Size), ""); EXPECT_DEATH(Allocator->reallocate(MisalignedP, Size * 2U), ""); diff --git a/compiler-rt/lib/scudo/standalone/tests/flags_test.cpp b/compiler-rt/lib/scudo/standalone/tests/flags_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/flags_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/flags_test.cpp @@ -6,11 +6,11 @@ // //===----------------------------------------------------------------------===// +#include "tests/scudo_unit_test.h" + #include "flags.h" #include "flags_parser.h" -#include "gtest/gtest.h" - #include static const char FlagName[] = "flag_name"; diff --git a/compiler-rt/lib/scudo/standalone/tests/list_test.cpp b/compiler-rt/lib/scudo/standalone/tests/list_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/list_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/list_test.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "scudo/standalone/list.h" -#include "gtest/gtest.h" +#include "tests/scudo_unit_test.h" + +#include "list.h" struct ListItem { ListItem *Next; diff --git a/compiler-rt/lib/scudo/standalone/tests/map_test.cpp b/compiler-rt/lib/scudo/standalone/tests/map_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/map_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/map_test.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "common.h" +#include "tests/scudo_unit_test.h" -#include "gtest/gtest.h" +#include "common.h" #include #include @@ -31,11 +31,10 @@ TEST(ScudoMapTest, MapUnmap) { const scudo::uptr Size = 4 * scudo::getPageSizeCached(); - scudo::MapPlatformData Data = {}; - void *P = scudo::map(nullptr, Size, MappingName, 0, &Data); + void *P = scudo::map(nullptr, Size, MappingName, 0, nullptr); EXPECT_NE(P, nullptr); memset(P, 0xaa, Size); - scudo::unmap(P, Size, 0, &Data); + scudo::unmap(P, Size, 0, nullptr); EXPECT_DEATH(memset(P, 0xbb, Size), ""); } diff --git a/compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp b/compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/mutex_test.cpp @@ -6,10 +6,11 @@ // //===----------------------------------------------------------------------===// -#include "mutex.h" +#include "tests/scudo_unit_test.h" -#include "gtest/gtest.h" +#include "mutex.h" +#include #include class TestData { diff --git a/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp b/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp @@ -6,15 +6,16 @@ // //===----------------------------------------------------------------------===// +#include "tests/scudo_unit_test.h" + #include "primary32.h" #include "primary64.h" #include "size_class_map.h" -#include "gtest/gtest.h" - #include #include #include +#include // Note that with small enough regions, the SizeClassAllocator64 also works on // 32-bit architectures. It's not something we want to encourage, but we still @@ -53,7 +54,9 @@ TEST(ScudoPrimaryTest, BasicPrimary) { using SizeClassMap = scudo::DefaultSizeClassMap; +#if !SCUDO_FUCHSIA testPrimary>(); +#endif testPrimary>(); } @@ -78,7 +81,7 @@ AllocationFailed = true; break; } - for (scudo::uptr J = 0; J < B->getCount(); J++) + for (scudo::u32 J = 0; J < B->getCount(); J++) memset(B->get(J), 'B', Size); Batches.push_back(B); } @@ -136,7 +139,9 @@ TEST(ScudoPrimaryTest, PrimaryIterate) { using SizeClassMap = scudo::DefaultSizeClassMap; +#if !SCUDO_FUCHSIA testIteratePrimary>(); +#endif testIteratePrimary>(); } @@ -193,7 +198,9 @@ TEST(ScudoPrimaryTest, PrimaryThreaded) { using SizeClassMap = scudo::SvelteSizeClassMap; +#if !SCUDO_FUCHSIA testPrimaryThreaded>(); +#endif testPrimaryThreaded>(); } @@ -221,6 +228,8 @@ TEST(ScudoPrimaryTest, ReleaseToOS) { using SizeClassMap = scudo::DefaultSizeClassMap; +#if !SCUDO_FUCHSIA testReleaseToOS>(); +#endif testReleaseToOS>(); } diff --git a/compiler-rt/lib/scudo/standalone/tests/quarantine_test.cpp b/compiler-rt/lib/scudo/standalone/tests/quarantine_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/quarantine_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/quarantine_test.cpp @@ -6,10 +6,11 @@ // //===----------------------------------------------------------------------===// -#include "quarantine.h" +#include "tests/scudo_unit_test.h" -#include "gtest/gtest.h" +#include "quarantine.h" +#include #include static void *FakePtr = reinterpret_cast(0xFA83FA83); diff --git a/compiler-rt/lib/scudo/standalone/tests/release_test.cpp b/compiler-rt/lib/scudo/standalone/tests/release_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/release_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/release_test.cpp @@ -6,16 +6,17 @@ // //===----------------------------------------------------------------------===// +#include "tests/scudo_unit_test.h" + #include "list.h" #include "release.h" #include "size_class_map.h" -#include "gtest/gtest.h" - #include #include #include +#include TEST(ScudoReleaseTest, PackedCounterArray) { for (scudo::uptr I = 0; I < SCUDO_WORDSIZE; I++) { diff --git a/compiler-rt/lib/scudo/standalone/tests/report_test.cpp b/compiler-rt/lib/scudo/standalone/tests/report_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/report_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/report_test.cpp @@ -6,11 +6,13 @@ // //===----------------------------------------------------------------------===// -#include "scudo/standalone/report.h" -#include "gtest/gtest.h" +#include "tests/scudo_unit_test.h" + +#include "report.h" TEST(ScudoReportTest, Generic) { - void *P = reinterpret_cast(0x42424242U); + // Potentially unused if EXPECT_DEATH isn't defined. + UNUSED void *P = reinterpret_cast(0x42424242U); EXPECT_DEATH(scudo::reportError("TEST123"), "Scudo ERROR.*TEST123"); EXPECT_DEATH(scudo::reportInvalidFlag("ABC", "DEF"), "Scudo ERROR.*ABC.*DEF"); EXPECT_DEATH(scudo::reportHeaderCorruption(P), "Scudo ERROR.*42424242"); diff --git a/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test.h b/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test.h new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test.h @@ -0,0 +1,21 @@ +#include "platform.h" + +#if SCUDO_FUCHSIA +#include +#else +#include "gtest/gtest.h" +#endif + +// If EXPECT_DEATH isn't defined, make it a no-op. +#ifndef EXPECT_DEATH +#define EXPECT_DEATH(X, Y) \ + do { \ + } while (0) +#endif + +// If EXPECT_STREQ isn't defined, define our own simple one. +#ifndef EXPECT_STREQ +#define EXPECT_STREQ(X, Y) EXPECT_EQ(strcmp(X, Y), 0) +#endif + +extern bool UseQuarantine; diff --git a/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test_main.cpp b/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test_main.cpp --- a/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test_main.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test_main.cpp @@ -6,9 +6,25 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" +#include "tests/scudo_unit_test.h" + +// This allows us to turn on/off a Quarantine for specific tests. The Quarantine +// parameters are on the low end, to avoid having to loop excessively in some +// tests. +bool UseQuarantine = true; +extern "C" __attribute__((visibility("default"))) const char * +__scudo_default_options() { + if (!UseQuarantine) + return "dealloc_type_mismatch=true"; + return "quarantine_size_kb=256:thread_local_quarantine_size_kb=128:" + "quarantine_max_chunk_size=512:dealloc_type_mismatch=true"; +} int main(int argc, char **argv) { +#if !SCUDO_FUCHSIA testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); +#else + return RUN_ALL_TESTS(argc, argv); +#endif } diff --git a/compiler-rt/lib/scudo/standalone/tests/secondary_test.cpp b/compiler-rt/lib/scudo/standalone/tests/secondary_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/secondary_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/secondary_test.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "secondary.h" +#include "tests/scudo_unit_test.h" -#include "gtest/gtest.h" +#include "secondary.h" #include @@ -16,6 +16,7 @@ #include #include #include +#include template static void testSecondaryBasic(void) { scudo::GlobalStats S; diff --git a/compiler-rt/lib/scudo/standalone/tests/size_class_map_test.cpp b/compiler-rt/lib/scudo/standalone/tests/size_class_map_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/size_class_map_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/size_class_map_test.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "scudo/standalone/size_class_map.h" -#include "gtest/gtest.h" +#include "tests/scudo_unit_test.h" + +#include "size_class_map.h" template void testSizeClassMap() { typedef SizeClassMap SCMap; diff --git a/compiler-rt/lib/scudo/standalone/tests/stats_test.cpp b/compiler-rt/lib/scudo/standalone/tests/stats_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/stats_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/stats_test.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "scudo/standalone/stats.h" -#include "gtest/gtest.h" +#include "tests/scudo_unit_test.h" + +#include "stats.h" TEST(ScudoStatsTest, LocalStats) { scudo::LocalStats LStats; diff --git a/compiler-rt/lib/scudo/standalone/tests/strings_test.cpp b/compiler-rt/lib/scudo/standalone/tests/strings_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/strings_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/strings_test.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "scudo/standalone/string_utils.h" -#include "gtest/gtest.h" +#include "tests/scudo_unit_test.h" + +#include "string_utils.h" #include diff --git a/compiler-rt/lib/scudo/standalone/tests/tsd_test.cpp b/compiler-rt/lib/scudo/standalone/tests/tsd_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/tsd_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/tsd_test.cpp @@ -6,11 +6,11 @@ // //===----------------------------------------------------------------------===// +#include "tests/scudo_unit_test.h" + #include "tsd_exclusive.h" #include "tsd_shared.h" -#include "gtest/gtest.h" - #include #include #include @@ -108,7 +108,9 @@ TEST(ScudoTSDTest, TSDRegistryBasic) { testRegistry>(); testRegistry>(); +#if !SCUDO_FUCHSIA testRegistry>(); +#endif } static std::mutex Mutex; @@ -164,5 +166,7 @@ TEST(ScudoTSDTest, TSDRegistryThreaded) { testRegistryThreaded>(); testRegistryThreaded>(); +#if !SCUDO_FUCHSIA testRegistryThreaded>(); +#endif } diff --git a/compiler-rt/lib/scudo/standalone/tests/vector_test.cpp b/compiler-rt/lib/scudo/standalone/tests/vector_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/vector_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/vector_test.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "vector.h" +#include "tests/scudo_unit_test.h" -#include "gtest/gtest.h" +#include "vector.h" TEST(ScudoVectorTest, Basic) { scudo::Vector V; 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 @@ -6,10 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "platform.h" - -#include "gtest/gtest.h" +#include "tests/scudo_unit_test.h" +#include #include #include #include @@ -32,11 +31,6 @@ // We have to use a small quarantine to make sure that our double-free tests // trigger. Otherwise EXPECT_DEATH ends up reallocating the chunk that was just // freed (this depends on the size obviously) and the following free succeeds. -extern "C" __attribute__((visibility("default"))) const char * -__scudo_default_options() { - return "quarantine_size_kb=256:thread_local_quarantine_size_kb=128:" - "quarantine_max_chunk_size=512"; -} static const size_t Size = 100U; @@ -200,6 +194,7 @@ #define M_PURGE -101 #endif +#if !SCUDO_FUCHSIA TEST(ScudoWrappersCTest, MallOpt) { errno = 0; EXPECT_EQ(mallopt(-1000, 1), 0); @@ -213,8 +208,10 @@ EXPECT_EQ(mallopt(M_DECAY_TIME, 1), 1); EXPECT_EQ(mallopt(M_DECAY_TIME, 0), 1); } +#endif TEST(ScudoWrappersCTest, OtherAlloc) { +#if !SCUDO_FUCHSIA const size_t PageSize = sysconf(_SC_PAGESIZE); void *P = pvalloc(Size); @@ -229,10 +226,12 @@ EXPECT_NE(P, nullptr); EXPECT_EQ(reinterpret_cast(P) & (PageSize - 1), 0U); free(P); +#endif EXPECT_EQ(valloc(SIZE_MAX), nullptr); } +#if !SCUDO_FUCHSIA TEST(ScudoWrappersCTest, MallInfo) { const size_t BypassQuarantineSize = 1024U; @@ -248,6 +247,7 @@ MI = mallinfo(); EXPECT_GE(static_cast(MI.fordblks), Free + BypassQuarantineSize); } +#endif static uintptr_t BoundaryP; static size_t Count; @@ -282,6 +282,7 @@ free(P); } +#if !SCUDO_FUCHSIA TEST(ScudoWrappersCTest, MallocInfo) { char Buffer[64]; FILE *F = fmemopen(Buffer, sizeof(Buffer), "w+"); @@ -292,3 +293,4 @@ fclose(F); EXPECT_EQ(strncmp(Buffer, " #include #include +#include void operator delete(void *, size_t) noexcept; void operator delete[](void *, size_t) noexcept; @@ -18,12 +19,6 @@ // 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. -extern "C" __attribute__((visibility("default"))) const char * -__scudo_default_options() { - return "quarantine_size_kb=256:thread_local_quarantine_size_kb=128:" - "quarantine_max_chunk_size=512:dealloc_type_mismatch=true"; -} - template static void testCxxNew() { T *P = new T; EXPECT_NE(P, nullptr);