[compiler-rt] 81b1d3d - [sanitizers][Windows] Implement __sanitizer_purge_allocator for Win64
Matthew G McGovern via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 12 09:51:37 PST 2021
Author: Matthew G McGovern
Date: 2021-02-12T09:49:04-08:00
New Revision: 81b1d3da094c54ffd75e05c8d4683792edf17f4c
URL: https://github.com/llvm/llvm-project/commit/81b1d3da094c54ffd75e05c8d4683792edf17f4c
DIFF: https://github.com/llvm/llvm-project/commit/81b1d3da094c54ffd75e05c8d4683792edf17f4c.diff
LOG: [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
Added:
compiler-rt/test/asan/TestCases/Windows/sanitizer_purge.cpp
Modified:
compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h
compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h
index 0a18b0c58ef7..21b0366d83ca 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h
@@ -144,6 +144,17 @@ class SizeClassAllocator64 {
CompactPtrT *free_array = GetFreeArray(region_beg);
BlockingMutexLock l(®ion->mutex);
+#if SANITIZER_WINDOWS
+ /* On Windows unmapping of memory during __sanitizer_purge_allocator is
+ explicit and immediate, so unmapped regions must be explicitly mapped back
+ in when they are accessed again. */
+ if (region->rtoi.last_released_bytes > 0) {
+ MmapFixedOrDie(region_beg, region->mapped_user,
+ "SizeClassAllocator: region data");
+ region->rtoi.n_freed_at_last_release = 0;
+ region->rtoi.last_released_bytes = 0;
+ }
+#endif
if (UNLIKELY(region->num_freed_chunks < n_chunks)) {
if (UNLIKELY(!PopulateFreeArray(stat, class_id, region,
n_chunks - region->num_freed_chunks)))
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
index 1b591f1bdcbb..99ecfd040c6a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
@@ -334,8 +334,12 @@ bool MprotectNoAccess(uptr addr, uptr size) {
}
void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
- // This is almost useless on 32-bits.
- // FIXME: add madvise-analog when we move to 64-bits.
+ uptr beg_aligned = RoundDownTo(beg, GetPageSizeCached()),
+ end_aligned = RoundDownTo(end, GetPageSizeCached());
+ CHECK(beg < end); // make sure the region is sane
+ if (beg_aligned == end_aligned) // make sure we're freeing at least 1 page;
+ return;
+ UnmapOrDie((void *)beg, end_aligned - beg_aligned);
}
void SetShadowRegionHugePageMode(uptr addr, uptr size) {
diff --git a/compiler-rt/test/asan/TestCases/Windows/sanitizer_purge.cpp b/compiler-rt/test/asan/TestCases/Windows/sanitizer_purge.cpp
new file mode 100644
index 000000000000..e3c7bfeaa5d4
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/Windows/sanitizer_purge.cpp
@@ -0,0 +1,31 @@
+#include <Windows.h>
+#include <stdio.h>
+#include <sanitizer/allocator_interface.h>
+#include <psapi.h>
+
+// RUN: %clang_cl_asan -Od %s -Fe%t
+// RUN: %t
+// REQUIRES: asan-64-bits
+
+size_t GetRSS() {
+ PROCESS_MEMORY_COUNTERS counters;
+ if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
+ return 0;
+ return counters.WorkingSetSize;
+}
+
+int main(){
+ for (int i = 0; i < 1000; i++) {
+ void* a = malloc(1000);
+ free(a);
+ }
+ size_t rss_pre = GetRSS();
+ __sanitizer_purge_allocator();
+ size_t rss_post = GetRSS();
+
+ if (rss_pre <= rss_post){
+ return -1;
+ }
+
+ return 0;
+}
\ No newline at end of file
More information about the llvm-commits
mailing list