[Lldb-commits] [compiler-rt] [mlir] [llvm] [lldb] [sanitizer] Pre-commit disabled test for fork (PR #75257)

Vitaly Buka via lldb-commits lldb-commits at lists.llvm.org
Tue Dec 12 17:16:06 PST 2023


https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/75257

>From db7b2abf12add7fcbac65c7f7fad5f60be58de2f Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 12 Dec 2023 16:08:56 -0800
Subject: [PATCH 1/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 .../TestCases/Posix/fork_threaded.cpp         | 86 +++++++++++++++++++
 .../sanitizer_common/sanitizer_specific.h     | 16 ++++
 2 files changed, 102 insertions(+)
 create mode 100644 compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp

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..d5c60bbb7c9430
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
@@ -0,0 +1,86 @@
+// RUN: %clangxx -O0 %s -o %t && %env_tool_opts=die_after_fork=0 %run %t
+
+// UNSUPPORTED: *
+
+// Forking in multithread environment is unsupported. However we already have
+// some workarounds, and will add more, so this is the test.
+
+#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;
+
+static void *background(void *arg) { return nullptr; }
+
+pthread_barrier_t bar;
+
+void CanDeadLock() {
+  // 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 (;;)
+    CanDeadLock();
+
+  return 0;
+}
+
+NOSAN static void *inchild(void *arg) {
+  char t[kBufferSize];
+  check_mem_is_good(t, sizeof(t));
+  CanDeadLock();
+  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;
+}
\ No newline at end of file
diff --git a/compiler-rt/test/sanitizer_common/sanitizer_specific.h b/compiler-rt/test/sanitizer_common/sanitizer_specific.h
index 1a802020cfd668..963d91cb305f60 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

>From 3ceddfbc5d928a8297e41923cfb3ac63d0af2a03 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 12 Dec 2023 16:11:58 -0800
Subject: [PATCH 2/4] newline

Created using spr 1.3.4
---
 .../test/sanitizer_common/TestCases/Posix/fork_threaded.cpp     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
index d5c60bbb7c9430..2264c558166388 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
@@ -83,4 +83,4 @@ int main(void) {
   }
 
   return 0;
-}
\ No newline at end of file
+}

>From 406f51b5873a5454400aab64abde7149b2e60cb6 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 12 Dec 2023 17:09:11 -0800
Subject: [PATCH 3/4] newline

Created using spr 1.3.4
---
 compiler-rt/test/sanitizer_common/sanitizer_specific.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler-rt/test/sanitizer_common/sanitizer_specific.h b/compiler-rt/test/sanitizer_common/sanitizer_specific.h
index 963d91cb305f60..898899f00e3701 100644
--- a/compiler-rt/test/sanitizer_common/sanitizer_specific.h
+++ b/compiler-rt/test/sanitizer_common/sanitizer_specific.h
@@ -37,4 +37,4 @@ 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__

>From e85f20de900826d7fc5367820e3e1b2e5093aeef Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 12 Dec 2023 17:15:55 -0800
Subject: [PATCH 4/4] commend

Created using spr 1.3.4
---
 .../sanitizer_common/TestCases/Posix/fork_threaded.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
index 052638438680f7..1e3a8ebf91d3d2 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
@@ -4,6 +4,10 @@
 
 // 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>
@@ -22,7 +26,7 @@ pthread_barrier_t bar;
 
 // Without appropriate workarounds this code can cause the forked process to
 // start with locked internal mutexes.
-void CanDeadLock() {
+void ShouldNotDeadlock() {
   // Don't bother with leaks, we try to trigger allocator or lsan deadlock.
   __lsan::ScopedDisabler disable;
   char *volatile p = new char[10];
@@ -42,7 +46,7 @@ NOSAN static void *inparent(void *arg) {
   pthread_barrier_wait(&bar);
 
   for (;;)
-    CanDeadLock();
+    ShouldNotDeadlock();
 
   return 0;
 }
@@ -50,7 +54,7 @@ NOSAN static void *inparent(void *arg) {
 NOSAN static void *inchild(void *arg) {
   char t[kBufferSize];
   check_mem_is_good(t, sizeof(t));
-  CanDeadLock();
+  ShouldNotDeadlock();
   return 0;
 }
 



More information about the lldb-commits mailing list