Skip to content

Commit 81b1d3d

Browse files
committed
[sanitizers][Windows] Implement __sanitizer_purge_allocator for Win64
Windows' memory unmapping has to be explicit, there is no madvise. Similarly, re-mapping memory has to be explicit as well. This patch implements a basic method for remapping memory which was previously returned to the OS on Windows. Patch by Matthew G. McGovern and Jordyn Puryear
1 parent 0b1914e commit 81b1d3d

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,17 @@ class SizeClassAllocator64 {
144144
CompactPtrT *free_array = GetFreeArray(region_beg);
145145

146146
BlockingMutexLock l(&region->mutex);
147+
#if SANITIZER_WINDOWS
148+
/* On Windows unmapping of memory during __sanitizer_purge_allocator is
149+
explicit and immediate, so unmapped regions must be explicitly mapped back
150+
in when they are accessed again. */
151+
if (region->rtoi.last_released_bytes > 0) {
152+
MmapFixedOrDie(region_beg, region->mapped_user,
153+
"SizeClassAllocator: region data");
154+
region->rtoi.n_freed_at_last_release = 0;
155+
region->rtoi.last_released_bytes = 0;
156+
}
157+
#endif
147158
if (UNLIKELY(region->num_freed_chunks < n_chunks)) {
148159
if (UNLIKELY(!PopulateFreeArray(stat, class_id, region,
149160
n_chunks - region->num_freed_chunks)))

compiler-rt/lib/sanitizer_common/sanitizer_win.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,12 @@ bool MprotectNoAccess(uptr addr, uptr size) {
334334
}
335335

336336
void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
337-
// This is almost useless on 32-bits.
338-
// FIXME: add madvise-analog when we move to 64-bits.
337+
uptr beg_aligned = RoundDownTo(beg, GetPageSizeCached()),
338+
end_aligned = RoundDownTo(end, GetPageSizeCached());
339+
CHECK(beg < end); // make sure the region is sane
340+
if (beg_aligned == end_aligned) // make sure we're freeing at least 1 page;
341+
return;
342+
UnmapOrDie((void *)beg, end_aligned - beg_aligned);
339343
}
340344

341345
void SetShadowRegionHugePageMode(uptr addr, uptr size) {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <Windows.h>
2+
#include <stdio.h>
3+
#include <sanitizer/allocator_interface.h>
4+
#include <psapi.h>
5+
6+
// RUN: %clang_cl_asan -Od %s -Fe%t
7+
// RUN: %t
8+
// REQUIRES: asan-64-bits
9+
10+
size_t GetRSS() {
11+
PROCESS_MEMORY_COUNTERS counters;
12+
if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
13+
return 0;
14+
return counters.WorkingSetSize;
15+
}
16+
17+
int main(){
18+
for (int i = 0; i < 1000; i++) {
19+
void* a = malloc(1000);
20+
free(a);
21+
}
22+
size_t rss_pre = GetRSS();
23+
__sanitizer_purge_allocator();
24+
size_t rss_post = GetRSS();
25+
26+
if (rss_pre <= rss_post){
27+
return -1;
28+
}
29+
30+
return 0;
31+
}

0 commit comments

Comments
 (0)