xref: /llvm-project/compiler-rt/test/rtsan/fork_exec.cpp (revision af4ae12780099d3df0b89bccc80fd69b240f345e)
1 // RUN: %clangxx -fsanitize=realtime -DIS_NONBLOCKING=1 %s -o %t
2 // RUN: %env_rtsan_opts="halt_on_error=true" not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HALT
3 // RUN: %env_rtsan_opts="halt_on_error=false" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOHALT
4 
5 // RUN: %clangxx -fsanitize=realtime -DIS_NONBLOCKING=0 %s -o %t
6 // RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-OK
7 // RUN: %env_rtsan_opts="halt_on_error=false" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-OK
8 
9 // UNSUPPORTED: ios
10 
11 // Intent: Ensure fork/exec dies when realtime and survives otherwise
12 //         This behavior is difficult to test in a gtest, because the process is
13 //         wiped away with exec.
14 
15 #include <stdio.h>
16 #include <sys/types.h>
17 #include <sys/wait.h>
18 #include <unistd.h>
19 
20 #if IS_NONBLOCKING
21 #  define MAYBE_NONBLOCKING [[clang::nonblocking]]
22 #else
23 #  define MAYBE_NONBLOCKING
24 #endif
25 
26 int main() MAYBE_NONBLOCKING {
27   const pid_t pid = fork();
28 
29   if (pid == 0) {
30     char *args[] = {"/bin/ls", nullptr};
31     execve(args[0], args, nullptr);
32     perror("execve failed");
33     return 1;
34   } else if (pid > 0) {
35     int status;
36     waitpid(pid, &status, 0);
37     usleep(1);
38   } else {
39     perror("fork failed");
40     return 1;
41   }
42 
43   printf("fork/exec succeeded\n");
44   return 0;
45 }
46 
47 // CHECK-NOHALT: Intercepted call to {{.*}} `fork` {{.*}}
48 // CHECK-NOHALT: Intercepted call to {{.*}} `execve` {{.*}}
49 
50 // usleep checks that rtsan is still enabled in the parent process
51 // See note in our interceptors file for why we don't look for `wait`
52 // CHECK-NOHALT: Intercepted call to {{.*}} `usleep` {{.*}}
53 
54 // CHECK-NOHALT: fork/exec succeeded
55 
56 // CHECK-HALT: ==ERROR: RealtimeSanitizer: unsafe-library-call
57 // CHECK-HALT-NEXT: Intercepted call to {{.*}} `fork` {{.*}}
58 
59 // CHECK-OK: fork/exec succeeded
60