[compiler-rt] 6d8fe3d - [sanitizer] Pre-commit disabled test for fork (#75257)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 12 20:00:07 PST 2023
Author: Vitaly Buka
Date: 2023-12-12T20:00:04-08:00
New Revision: 6d8fe3dc9a4f6225c4c84de578469efc50d7684d
URL: https://github.com/llvm/llvm-project/commit/6d8fe3dc9a4f6225c4c84de578469efc50d7684d
DIFF: https://github.com/llvm/llvm-project/commit/6d8fe3dc9a4f6225c4c84de578469efc50d7684d.diff
LOG: [sanitizer] Pre-commit disabled test for fork (#75257)
Added:
compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
Modified:
compiler-rt/test/sanitizer_common/sanitizer_specific.h
Removed:
################################################################################
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
new file mode 100644
index 00000000000000..667f81d2985335
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
@@ -0,0 +1,90 @@
+// RUN: %clangxx -O0 %s -o %t && %env_tool_opts=die_after_fork=0 %run %t
+
+// UNSUPPORTED: asan, hwasan, lsan, msan, tsan, ubsan
+
+// Forking in multithread environment is unsupported. However we already have
+// some workarounds, and will add more, so this is the test.
+// The test try to check two things:
+// 1. Internal mutexes used by `inparent` thread do not deadlock `inchild`
+// thread.
+// 2. Stack poisoned by `inparent` is not poisoned in `inchild` thread.
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "sanitizer_common/sanitizer_specific.h"
+
+static const size_t kBufferSize = 1 << 20;
+
+pthread_barrier_t bar;
+
+// Without appropriate workarounds this code can cause the forked process to
+// start with locked internal mutexes.
+void ShouldNotDeadlock() {
+ // Don't bother with leaks, we try to trigger allocator or lsan deadlock.
+ __lsan::ScopedDisabler disable;
+ char *volatile p = new char[10];
+ __lsan_do_recoverable_leak_check();
+ delete[] p;
+}
+
+// Prevent stack buffer cleanup by instrumentation.
+#define NOSAN __attribute__((no_sanitize("address", "hwaddress", "memory")))
+
+NOSAN static void *inparent(void *arg) {
+ fprintf(stderr, "inparent %d\n", gettid());
+
+ char t[kBufferSize];
+ make_mem_bad(t, sizeof(t));
+
+ pthread_barrier_wait(&bar);
+
+ for (;;)
+ ShouldNotDeadlock();
+
+ return 0;
+}
+
+NOSAN static void *inchild(void *arg) {
+ char t[kBufferSize];
+ check_mem_is_good(t, sizeof(t));
+ ShouldNotDeadlock();
+ return 0;
+}
+
+int main(void) {
+ pid_t pid;
+
+ pthread_barrier_init(&bar, nullptr, 2);
+ pthread_t thread_id;
+ while (pthread_create(&thread_id, 0, &inparent, 0) != 0) {
+ }
+ pthread_barrier_wait(&bar);
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ perror("fork");
+ return -1;
+ case 0:
+ while (pthread_create(&thread_id, 0, &inchild, 0) != 0) {
+ }
+ break;
+ default: {
+ fprintf(stderr, "fork %d\n", pid);
+ int status;
+ while (waitpid(-1, &status, __WALL) != pid) {
+ }
+ assert(WIFEXITED(status) && WEXITSTATUS(status) == 0);
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/compiler-rt/test/sanitizer_common/sanitizer_specific.h b/compiler-rt/test/sanitizer_common/sanitizer_specific.h
index 1a802020cfd668..898899f00e3701 100644
--- a/compiler-rt/test/sanitizer_common/sanitizer_specific.h
+++ b/compiler-rt/test/sanitizer_common/sanitizer_specific.h
@@ -1,6 +1,12 @@
#ifndef __SANITIZER_COMMON_SANITIZER_SPECIFIC_H__
#define __SANITIZER_COMMON_SANITIZER_SPECIFIC_H__
+#include <sanitizer/lsan_interface.h>
+
+__attribute__((weak)) int __lsan_do_recoverable_leak_check() { return 0; }
+__attribute__((weak)) void __lsan_disable(void) {}
+__attribute__((weak)) void __lsan_enable(void) {}
+
#ifndef __has_feature
# define __has_feature(x) 0
#endif
@@ -10,6 +16,8 @@
static void check_mem_is_good(void *p, size_t s) {
__msan_check_mem_is_initialized(p, s);
}
+static void make_mem_good(void *p, size_t s) { __msan_unpoison(p, s); }
+static void make_mem_bad(void *p, size_t s) { __msan_poison(p, s); }
#elif __has_feature(address_sanitizer)
# include <sanitizer/asan_interface.h>
# include <stdlib.h>
@@ -17,8 +25,16 @@ static void check_mem_is_good(void *p, size_t s) {
if (__asan_region_is_poisoned(p, s))
abort();
}
+static void make_mem_good(void *p, size_t s) {
+ __asan_unpoison_memory_region(p, s);
+}
+static void make_mem_bad(void *p, size_t s) {
+ __asan_poison_memory_region(p, s);
+}
#else
static void check_mem_is_good(void *p, size_t s) {}
+static void make_mem_good(void *p, size_t s) {}
+static void make_mem_bad(void *p, size_t s) {}
#endif
-#endif // __SANITIZER_COMMON_SANITIZER_SPECIFIC_H__
\ No newline at end of file
+#endif // __SANITIZER_COMMON_SANITIZER_SPECIFIC_H__
More information about the llvm-commits
mailing list