Skip to content

Commit 5ace7ab

Browse files
author
git apple-llvm automerger
committed
Merge commit 'd0eef2217109' from llvm.org/main into next
2 parents 9a7c5fc + d0eef22 commit 5ace7ab

File tree

2 files changed

+55
-34
lines changed

2 files changed

+55
-34
lines changed

compiler-rt/lib/scudo/standalone/combined.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class Allocator {
101101
Chunk::UnpackedHeader Header = {};
102102
Header.ClassId = QuarantineClassId & Chunk::ClassIdMask;
103103
Header.SizeOrUnusedBytes = sizeof(QuarantineBatch);
104-
Header.State = Chunk::State::Allocated;
104+
Header.State = Chunk::State::Quarantined;
105105
Chunk::storeHeader(Allocator.Cookie, Ptr, &Header);
106106

107107
// Reset tag to 0 as this chunk may have been previously used for a tagged
@@ -120,7 +120,7 @@ class Allocator {
120120
Chunk::UnpackedHeader Header;
121121
Chunk::loadHeader(Allocator.Cookie, Ptr, &Header);
122122

123-
if (UNLIKELY(Header.State != Chunk::State::Allocated))
123+
if (UNLIKELY(Header.State != Chunk::State::Quarantined))
124124
reportInvalidChunkState(AllocatorAction::Deallocating, Ptr);
125125
DCHECK_EQ(Header.ClassId, QuarantineClassId);
126126
DCHECK_EQ(Header.Offset, 0);

compiler-rt/lib/scudo/standalone/tests/combined_test.cpp

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <set>
2525
#include <stdlib.h>
2626
#include <thread>
27+
#include <unordered_map>
2728
#include <vector>
2829

2930
static constexpr scudo::Chunk::Origin Origin = scudo::Chunk::Origin::Malloc;
@@ -150,14 +151,8 @@ void TestAllocator<Config>::operator delete(void *ptr) {
150151
}
151152

152153
template <class TypeParam> struct ScudoCombinedTest : public Test {
153-
ScudoCombinedTest() {
154-
UseQuarantine = std::is_same<TypeParam, scudo::AndroidConfig>::value;
155-
Allocator = std::make_unique<AllocatorT>();
156-
}
157-
~ScudoCombinedTest() {
158-
Allocator->releaseToOS(scudo::ReleaseToOS::Force);
159-
UseQuarantine = true;
160-
}
154+
ScudoCombinedTest() { Allocator = std::make_unique<AllocatorT>(); }
155+
~ScudoCombinedTest() { Allocator->releaseToOS(scudo::ReleaseToOS::Force); }
161156

162157
void RunTest();
163158

@@ -525,30 +520,25 @@ SCUDO_TYPED_TEST(ScudoCombinedTest, IterateOverChunks) {
525520
auto *Allocator = this->Allocator.get();
526521
// Allocates a bunch of chunks, then iterate over all the chunks, ensuring
527522
// they are the ones we allocated. This requires the allocator to not have any
528-
// other allocated chunk at this point (eg: won't work with the Quarantine).
529-
// FIXME: Make it work with UseQuarantine and tagging enabled. Internals of
530-
// iterateOverChunks reads header by tagged and non-tagger pointers so one of
531-
// them will fail.
532-
if (!UseQuarantine) {
533-
std::vector<void *> V;
534-
for (scudo::uptr I = 0; I < 64U; I++)
535-
V.push_back(Allocator->allocate(
536-
static_cast<scudo::uptr>(std::rand()) %
537-
(TypeParam::Primary::SizeClassMap::MaxSize / 2U),
538-
Origin));
539-
Allocator->disable();
540-
Allocator->iterateOverChunks(
541-
0U, static_cast<scudo::uptr>(SCUDO_MMAP_RANGE_SIZE - 1),
542-
[](uintptr_t Base, UNUSED size_t Size, void *Arg) {
543-
std::vector<void *> *V = reinterpret_cast<std::vector<void *> *>(Arg);
544-
void *P = reinterpret_cast<void *>(Base);
545-
EXPECT_NE(std::find(V->begin(), V->end(), P), V->end());
546-
},
547-
reinterpret_cast<void *>(&V));
548-
Allocator->enable();
549-
for (auto P : V)
550-
Allocator->deallocate(P, Origin);
551-
}
523+
// other allocated chunk at this point.
524+
std::vector<void *> V;
525+
for (scudo::uptr I = 0; I < 64U; I++)
526+
V.push_back(Allocator->allocate(
527+
static_cast<scudo::uptr>(std::rand()) %
528+
(TypeParam::Primary::SizeClassMap::MaxSize / 2U),
529+
Origin));
530+
Allocator->disable();
531+
Allocator->iterateOverChunks(
532+
0U, static_cast<scudo::uptr>(SCUDO_MMAP_RANGE_SIZE - 1),
533+
[](uintptr_t Base, UNUSED size_t Size, void *Arg) {
534+
std::vector<void *> *V = reinterpret_cast<std::vector<void *> *>(Arg);
535+
void *P = reinterpret_cast<void *>(Base);
536+
EXPECT_NE(std::find(V->begin(), V->end(), P), V->end());
537+
},
538+
reinterpret_cast<void *>(&V));
539+
Allocator->enable();
540+
for (auto P : V)
541+
Allocator->deallocate(P, Origin);
552542
}
553543

554544
SCUDO_TYPED_TEST(ScudoCombinedDeathTest, UseAfterFree) {
@@ -1161,3 +1151,34 @@ TEST(ScudoCombinedTest, QuarantineDisabled) {
11611151
// No quarantine stats should not be present.
11621152
EXPECT_EQ(Stats.find("Stats: Quarantine"), std::string::npos);
11631153
}
1154+
1155+
// Verify that no special quarantine blocks appear in iterateOverChunks.
1156+
TEST(ScudoCombinedTest, QuarantineIterateOverChunks) {
1157+
using AllocatorT = scudo::Allocator<TestQuarantineConfig>;
1158+
auto Allocator = std::unique_ptr<AllocatorT>(new AllocatorT());
1159+
1160+
// Do a bunch of allocations and deallocations. At the end there should
1161+
// be no special quarantine blocks in our callbacks, and no blocks at all.
1162+
std::vector<scudo::uptr> Sizes = {128, 128, 256, 256};
1163+
for (auto const Size : Sizes) {
1164+
void *Ptr = Allocator->allocate(Size, Origin);
1165+
EXPECT_NE(Ptr, nullptr);
1166+
Allocator->deallocate(Ptr, Origin);
1167+
}
1168+
std::unordered_map<uintptr_t, size_t> Pointers;
1169+
Allocator->disable();
1170+
Allocator->iterateOverChunks(
1171+
0, static_cast<scudo::uptr>(SCUDO_MMAP_RANGE_SIZE - 1),
1172+
[](uintptr_t Base, size_t Size, void *Arg) {
1173+
std::unordered_map<uintptr_t, size_t> *Pointers =
1174+
reinterpret_cast<std::unordered_map<uintptr_t, size_t> *>(Arg);
1175+
(*Pointers)[Base] = Size;
1176+
},
1177+
reinterpret_cast<void *>(&Pointers));
1178+
Allocator->enable();
1179+
1180+
for (const auto [Base, Size] : Pointers) {
1181+
EXPECT_TRUE(false) << "Unexpected pointer found in iterateOverChunks "
1182+
<< std::hex << Base << " Size " << std::dec << Size;
1183+
}
1184+
}

0 commit comments

Comments
 (0)