[NFC][sanitizer] Add OnMapSecondary callback
Now it implemented as OnMap everywhere, but in follow up patches we can optimize Asan handler.
This commit is contained in:
parent
04a7c672ab
commit
38dfcf96df
@ -248,6 +248,15 @@ void AsanMapUnmapCallback::OnMap(uptr p, uptr size) const {
|
||||
thread_stats.mmaps++;
|
||||
thread_stats.mmaped += size;
|
||||
}
|
||||
|
||||
void AsanMapUnmapCallback::OnMapSecondary(uptr p, uptr size) const {
|
||||
PoisonShadow(p, size, kAsanHeapLeftRedzoneMagic);
|
||||
// Statistics.
|
||||
AsanStats &thread_stats = GetCurrentThreadStats();
|
||||
thread_stats.mmaps++;
|
||||
thread_stats.mmaped += size;
|
||||
}
|
||||
|
||||
void AsanMapUnmapCallback::OnUnmap(uptr p, uptr size) const {
|
||||
PoisonShadow(p, size, 0);
|
||||
// We are about to unmap a chunk of user memory.
|
||||
|
||||
@ -114,6 +114,7 @@ class AsanChunkFifoList: public IntrusiveList<AsanChunk> {
|
||||
|
||||
struct AsanMapUnmapCallback {
|
||||
void OnMap(uptr p, uptr size) const;
|
||||
void OnMapSecondary(uptr p, uptr size) const;
|
||||
void OnUnmap(uptr p, uptr size) const;
|
||||
};
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ struct Metadata {
|
||||
|
||||
struct DFsanMapUnmapCallback {
|
||||
void OnMap(uptr p, uptr size) const { dfsan_set_label(0, (void *)p, size); }
|
||||
void OnMapSecondary(uptr p, uptr size) const { OnMap(p, size); }
|
||||
void OnUnmap(uptr p, uptr size) const { dfsan_set_label(0, (void *)p, size); }
|
||||
};
|
||||
|
||||
|
||||
@ -54,6 +54,7 @@ static_assert(sizeof(Metadata) == 16);
|
||||
|
||||
struct HwasanMapUnmapCallback {
|
||||
void OnMap(uptr p, uptr size) const { UpdateMemoryUsage(); }
|
||||
void OnMapSecondary(uptr p, uptr size) const { UpdateMemoryUsage(); }
|
||||
void OnUnmap(uptr p, uptr size) const {
|
||||
// We are about to unmap a chunk of user memory.
|
||||
// It can return as user-requested mmap() or another thread stack.
|
||||
|
||||
@ -39,6 +39,7 @@ void InitializeAllocator();
|
||||
|
||||
struct MemprofMapUnmapCallback {
|
||||
void OnMap(uptr p, uptr size) const;
|
||||
void OnMapSecondary(uptr p, uptr size) const { OnMap(p, size); }
|
||||
void OnUnmap(uptr p, uptr size) const;
|
||||
};
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ struct Metadata {
|
||||
|
||||
struct MsanMapUnmapCallback {
|
||||
void OnMap(uptr p, uptr size) const {}
|
||||
void OnMapSecondary(uptr p, uptr size) const {}
|
||||
void OnUnmap(uptr p, uptr size) const {
|
||||
__msan_unpoison((void *)p, size);
|
||||
|
||||
|
||||
@ -64,6 +64,7 @@ inline void RandomShuffle(T *a, u32 n, u32 *rand_state) {
|
||||
|
||||
struct NoOpMapUnmapCallback {
|
||||
void OnMap(uptr p, uptr size) const {}
|
||||
void OnMapSecondary(uptr p, uptr size) const {}
|
||||
void OnUnmap(uptr p, uptr size) const {}
|
||||
};
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ class LargeMmapAllocator {
|
||||
if (!map_beg)
|
||||
return nullptr;
|
||||
CHECK(IsAligned(map_beg, page_size_));
|
||||
MapUnmapCallback().OnMap(map_beg, map_size);
|
||||
MapUnmapCallback().OnMapSecondary(map_beg, map_size);
|
||||
uptr map_end = map_beg + map_size;
|
||||
uptr res = map_beg + page_size_;
|
||||
if (res & (alignment - 1)) // Align.
|
||||
|
||||
@ -476,11 +476,15 @@ TEST(SanitizerCommon, SizeClassAllocator32CompactGetBlockBegin) {
|
||||
#endif // SANITIZER_CAN_USE_ALLOCATOR64
|
||||
|
||||
struct TestMapUnmapCallback {
|
||||
static int map_count, unmap_count;
|
||||
static int map_count, map_secondary_count, unmap_count;
|
||||
void OnMap(uptr p, uptr size) const { map_count++; }
|
||||
void OnMapSecondary(uptr p, uptr size) const { map_secondary_count++; }
|
||||
void OnUnmap(uptr p, uptr size) const { unmap_count++; }
|
||||
|
||||
static void Reset() { map_count = map_secondary_count = unmap_count = 0; }
|
||||
};
|
||||
int TestMapUnmapCallback::map_count;
|
||||
int TestMapUnmapCallback::map_secondary_count;
|
||||
int TestMapUnmapCallback::unmap_count;
|
||||
|
||||
#if SANITIZER_CAN_USE_ALLOCATOR64
|
||||
@ -500,12 +504,12 @@ struct AP64WithCallback {
|
||||
};
|
||||
|
||||
TEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) {
|
||||
TestMapUnmapCallback::map_count = 0;
|
||||
TestMapUnmapCallback::unmap_count = 0;
|
||||
TestMapUnmapCallback::Reset();
|
||||
typedef SizeClassAllocator64<AP64WithCallback<>> Allocator64WithCallBack;
|
||||
Allocator64WithCallBack *a = new Allocator64WithCallBack;
|
||||
a->Init(kReleaseToOSIntervalNever);
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_count, 1); // Allocator state.
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 0);
|
||||
typename Allocator64WithCallBack::AllocatorCache cache;
|
||||
memset(&cache, 0, sizeof(cache));
|
||||
cache.Init(0);
|
||||
@ -516,6 +520,7 @@ TEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) {
|
||||
a->GetFromAllocator(&stats, 30, chunks, kNumChunks);
|
||||
// State + alloc + metadata + freearray.
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_count, 4);
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 0);
|
||||
a->TestOnlyUnmap();
|
||||
EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1); // The whole thing.
|
||||
delete a;
|
||||
@ -536,12 +541,12 @@ struct AP32WithCallback {
|
||||
};
|
||||
|
||||
TEST(SanitizerCommon, SizeClassAllocator32MapUnmapCallback) {
|
||||
TestMapUnmapCallback::map_count = 0;
|
||||
TestMapUnmapCallback::unmap_count = 0;
|
||||
TestMapUnmapCallback::Reset();
|
||||
typedef SizeClassAllocator32<AP32WithCallback<>> Allocator32WithCallBack;
|
||||
Allocator32WithCallBack *a = new Allocator32WithCallBack;
|
||||
a->Init(kReleaseToOSIntervalNever);
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_count, 0);
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 0);
|
||||
Allocator32WithCallBack::AllocatorCache cache;
|
||||
memset(&cache, 0, sizeof(cache));
|
||||
cache.Init(0);
|
||||
@ -549,23 +554,21 @@ TEST(SanitizerCommon, SizeClassAllocator32MapUnmapCallback) {
|
||||
stats.Init();
|
||||
a->AllocateBatch(&stats, &cache, 32);
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_count, 1);
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 0);
|
||||
a->TestOnlyUnmap();
|
||||
EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1);
|
||||
delete a;
|
||||
// fprintf(stderr, "Map: %d Unmap: %d\n",
|
||||
// TestMapUnmapCallback::map_count,
|
||||
// TestMapUnmapCallback::unmap_count);
|
||||
}
|
||||
|
||||
TEST(SanitizerCommon, LargeMmapAllocatorMapUnmapCallback) {
|
||||
TestMapUnmapCallback::map_count = 0;
|
||||
TestMapUnmapCallback::unmap_count = 0;
|
||||
TestMapUnmapCallback::Reset();
|
||||
LargeMmapAllocator<TestMapUnmapCallback> a;
|
||||
a.Init();
|
||||
AllocatorStats stats;
|
||||
stats.Init();
|
||||
void *x = a.Allocate(&stats, 1 << 20, 1);
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_count, 1);
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_count, 0);
|
||||
EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 1);
|
||||
a.Deallocate(&stats, x);
|
||||
EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1);
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ namespace __tsan {
|
||||
|
||||
struct MapUnmapCallback {
|
||||
void OnMap(uptr p, uptr size) const { }
|
||||
void OnMapSecondary(uptr p, uptr size) const {};
|
||||
void OnUnmap(uptr p, uptr size) const {
|
||||
// We are about to unmap a chunk of user memory.
|
||||
// Mark the corresponding shadow memory as not needed.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user