diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -402,7 +402,10 @@ Str.output(); } - void releaseToOS() { Primary.releaseToOS(); } + void releaseToOS() { + initThreadMaybe(); + Primary.releaseToOS(); + } // Iterate over all chunks and call a callback for all busy chunks located // within the provided memory range. Said callback must not use this allocator 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 @@ -279,3 +279,18 @@ EXPECT_DEATH(Allocator->reallocate(P, Size * 2U), ""); EXPECT_DEATH(Allocator->getUsableSize(P), ""); } + +// Ensure that releaseToOS can be called prior to any other allocator +// operation without issue. +TEST(ScudoCombinedTest, ReleaseToOS) { + using AllocatorT = scudo::Allocator; + auto Deleter = [](AllocatorT *A) { + A->unmapTestOnly(); + delete A; + }; + std::unique_ptr Allocator(new AllocatorT, + Deleter); + Allocator->reset(); + + Allocator->releaseToOS(); +}