[compiler-rt] 7ac72ce - [hwasan] Implement __sanitizer_purge_allocator
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 26 19:16:46 PDT 2023
Author: Vitaly Buka
Date: 2023-04-26T19:16:40-07:00
New Revision: 7ac72cea0ee9f676e79f16521c7e3f0d2ce3a678
URL: https://github.com/llvm/llvm-project/commit/7ac72cea0ee9f676e79f16521c7e3f0d2ce3a678
DIFF: https://github.com/llvm/llvm-project/commit/7ac72cea0ee9f676e79f16521c7e3f0d2ce3a678.diff
LOG: [hwasan] Implement __sanitizer_purge_allocator
Reviewed By: kstoimenov
Differential Revision: https://reviews.llvm.org/D149241
Added:
compiler-rt/test/sanitizer_common/TestCases/Linux/release_to_os_test.cpp
Modified:
compiler-rt/lib/hwasan/hwasan_allocator.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
index ae9ffe88384d..585d907a62a0 100644
--- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
@@ -683,3 +683,5 @@ const void *__sanitizer_get_allocated_begin(const void *p) {
}
uptr __sanitizer_get_allocated_size(const void *p) { return AllocationSize(p); }
+
+void __sanitizer_purge_allocator() { allocator.ForceReleaseToOS(); }
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/release_to_os_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/release_to_os_test.cpp
new file mode 100644
index 000000000000..83af7d3e611e
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/release_to_os_test.cpp
@@ -0,0 +1,90 @@
+// RUN: %clangxx %s -o %t
+// RUN: env %tool_options=allocator_release_to_os_interval_ms=-1 %run %t
+
+// Not needed, no allocator.
+// XFAIL: ubsan
+
+// FIXME: Implement
+// XFAIL: lsan, msan, tsan, hwasan-aliasing
+
+#include <algorithm>
+#include <assert.h>
+#include <fcntl.h>
+#include <random>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <sanitizer/allocator_interface.h>
+
+const size_t kPageSize = 4096;
+
+void sync_rss() {
+ char *page =
+ (char *)mmap((void *)&sync_rss, kPageSize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ // Linux kernel updates RSS counters after a set number of page faults.
+ for (int i = 0; i < 10000; ++i) {
+ page[0] = 42;
+ madvise(page, kPageSize, MADV_DONTNEED);
+ }
+ munmap(page, kPageSize);
+}
+
+size_t current_rss() {
+ sync_rss();
+ int statm_fd = open("/proc/self/statm", O_RDONLY);
+ assert(statm_fd >= 0);
+
+ char buf[100];
+ assert(read(statm_fd, &buf, sizeof(buf)) > 0);
+ size_t size, rss;
+ assert(sscanf(buf, "%zu %zu", &size, &rss) == 2);
+
+ close(statm_fd);
+ return rss;
+}
+
+void MallocReleaseStress() {
+ const size_t kNumChunks = 10000;
+ const size_t kAllocSize = 100;
+ const size_t kNumIter = 100;
+ uintptr_t *chunks[kNumChunks] = {0};
+ std::mt19937 r;
+
+ for (size_t iter = 0; iter < kNumIter; iter++) {
+ std::shuffle(chunks, chunks + kNumChunks, r);
+ size_t to_replace = rand() % kNumChunks;
+ for (size_t i = 0; i < kNumChunks; i++) {
+ if (chunks[i])
+ assert(chunks[i][0] == (uintptr_t)chunks[i]);
+ if (i < to_replace) {
+ delete[] chunks[i];
+ chunks[i] = new uintptr_t[kAllocSize];
+ chunks[i][0] = (uintptr_t)chunks[i];
+ }
+ }
+ }
+ fprintf(stderr, "before delete: %zu\n", current_rss());
+ for (auto p : chunks)
+ delete[] p;
+}
+
+int main(int argc, char **argv) {
+ // 32bit asan allocator is unsupported.
+ if (sizeof(void *) < 8 && __has_feature(address_sanitizer))
+ return 0;
+ auto a = current_rss();
+ MallocReleaseStress();
+ auto b = current_rss();
+ __sanitizer_purge_allocator();
+ auto c = current_rss();
+ fprintf(stderr, "a:%zu b:%zu c:%zu\n", a, b, c);
+ assert(a * 2 < b);
+ assert(c * 2 < b);
+}
More information about the llvm-commits
mailing list