Watch for fork(2)/vfork(2) (also fork/vfork-style clone(2) on Linux) notifications and explicitly detach the forked child process, and add initial tests for these cases. The code covers FreeBSD, Linux and NetBSD process plugins. There is no new user-visible functionality provided -- this change lays foundations over subsequent work on fork support. Differential Revision: https://reviews.llvm.org/D98822
51 lines
1.0 KiB
C++
51 lines
1.0 KiB
C++
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <assert.h>
|
|
#if defined(TEST_CLONE)
|
|
#include <sched.h>
|
|
#endif
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
int g_val = 0;
|
|
|
|
void parent_func() {
|
|
g_val = 1;
|
|
printf("function run in parent\n");
|
|
}
|
|
|
|
int child_func(void *unused) {
|
|
// we need to avoid memory modifications for vfork(), yet we want
|
|
// to be able to test watchpoints, so do the next best thing
|
|
// and restore the original value
|
|
g_val = 2;
|
|
g_val = 0;
|
|
return 0;
|
|
}
|
|
|
|
int main() {
|
|
alignas(uintmax_t) char stack[4096];
|
|
|
|
#if defined(TEST_CLONE)
|
|
pid_t pid = clone(child_func, &stack[sizeof(stack)], 0, NULL);
|
|
#elif defined(TEST_FORK)
|
|
pid_t pid = TEST_FORK();
|
|
if (pid == 0)
|
|
_exit(child_func(NULL));
|
|
#endif
|
|
assert(pid != -1);
|
|
|
|
parent_func();
|
|
int status, wait_flags = 0;
|
|
#if defined(TEST_CLONE)
|
|
wait_flags = __WALL;
|
|
#endif
|
|
pid_t waited = waitpid(pid, &status, wait_flags);
|
|
assert(waited == pid);
|
|
assert(WIFEXITED(status));
|
|
printf("child exited: %d\n", WEXITSTATUS(status));
|
|
|
|
return 0;
|
|
}
|