Index: lldb/test/Shell/Subprocess/Inputs/fork.cpp =================================================================== --- lldb/test/Shell/Subprocess/Inputs/fork.cpp +++ lldb/test/Shell/Subprocess/Inputs/fork.cpp @@ -5,38 +5,108 @@ #include #endif #include +#include #include #include int g_val = 0; +void indicate(int pipefd[2]) { + int ret; + ret = write(pipefd[1], "go", 2); + assert(ret == 2); + ret = close(pipefd[1]); + assert(ret == 0); +} + +void wait_for(int pipefd[2]) { + char buf[2]; + int ret; + ret = read(pipefd[0], buf, sizeof(buf)); + assert(ret == 2); + ret = close(pipefd[0]); + assert(ret == 0); +} + void parent_func() { g_val = 1; printf("function run in parent\n"); } -int child_func(void *unused) { +int parent_done[2]; +int child_done[2]; +char parent_done_str[16]; +char child_done_str[16]; + +int child_func(void *argv0_ptr) { + const char *argv0 = static_cast(argv0_ptr); + + // NB: when using vfork(), the parent may be suspended while running + // this function, so do not rely on any synchronization until we exec + int ret = close(parent_done[1]); + assert(ret == 0); + ret = close(child_done[0]); + assert(ret == 0); + // 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; + execl(argv0, argv0, parent_done_str, child_done_str, NULL); + assert(0 && "this should not be reached"); + return 1; } -int main() { +int main(int argc, char* argv[]) { alignas(uintmax_t) char stack[4096]; + int ret; + + if (argv[1]) { + assert(argv[2]); + parent_done[0] = atoi(argv[1]); + assert(parent_done[0] != 0); + child_done[1] = atoi(argv[2]); + assert(child_done[1] != 0); + + wait_for(parent_done); + fprintf(stderr, "function run in exec'd child\n"); + indicate(child_done); + return 0; + } + + ret = pipe(parent_done); + assert(ret == 0); + ret = pipe(child_done); + assert(ret == 0); + + ret = snprintf(parent_done_str, sizeof(parent_done_str), + "%d", parent_done[0]); + assert(ret != -1); + ret = snprintf(child_done_str, sizeof(child_done_str), + "%d", child_done[1]); + assert(ret != -1); #if defined(TEST_CLONE) - pid_t pid = clone(child_func, &stack[sizeof(stack)], 0, NULL); + pid_t pid = clone(child_func, &stack[sizeof(stack)], 0, argv[0]); #elif defined(TEST_FORK) pid_t pid = TEST_FORK(); + // NB: this must be equivalent to the clone() call above if (pid == 0) - _exit(child_func(NULL)); + _exit(child_func(argv[0])); #endif assert(pid != -1); + ret = close(parent_done[0]); + assert(ret == 0); + ret = close(child_done[1]); + assert(ret == 0); + parent_func(); + + indicate(parent_done); + wait_for(child_done); + int status, wait_flags = 0; #if defined(TEST_CLONE) wait_flags = __WALL; @@ -44,7 +114,7 @@ pid_t waited = waitpid(pid, &status, wait_flags); assert(waited == pid); assert(WIFEXITED(status)); - printf("child exited: %d\n", WEXITSTATUS(status)); + assert(WEXITSTATUS(status) == 0); return 0; } Index: lldb/test/Shell/Subprocess/clone-follow-child-softbp.test =================================================================== --- lldb/test/Shell/Subprocess/clone-follow-child-softbp.test +++ lldb/test/Shell/Subprocess/clone-follow-child-softbp.test @@ -4,10 +4,13 @@ # RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_CLONE -o %t # RUN: %lldb -b -s %s %t | FileCheck %s settings set target.process.follow-fork-mode child +settings set target.process.stop-on-exec false b child_func b parent_func process launch +# CHECK: function run in parent # CHECK: stop reason = breakpoint # CHECK-NEXT: child_func continue -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/clone-follow-child-wp.test =================================================================== --- lldb/test/Shell/Subprocess/clone-follow-child-wp.test +++ lldb/test/Shell/Subprocess/clone-follow-child-wp.test @@ -4,12 +4,15 @@ # RUN: %clangxx_host -g %p/Inputs/fork.cpp -DTEST_CLONE -o %t # RUN: %lldb -b -s %s %t | FileCheck %s settings set target.process.follow-fork-mode child +settings set target.process.stop-on-exec false process launch -s watchpoint set variable -w write g_val # CHECK: Watchpoint created: continue +# CHECK: function run in parent # CHECK: stop reason = watchpoint continue # CHECK: stop reason = watchpoint continue -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/clone-follow-child.test =================================================================== --- lldb/test/Shell/Subprocess/clone-follow-child.test +++ lldb/test/Shell/Subprocess/clone-follow-child.test @@ -4,7 +4,9 @@ # RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_CLONE -o %t # RUN: %lldb -b -s %s %t | FileCheck %s settings set target.process.follow-fork-mode child +settings set target.process.stop-on-exec false b parent_func process launch # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test =================================================================== --- lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test +++ lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test @@ -10,4 +10,5 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/clone-follow-parent-wp.test =================================================================== --- lldb/test/Shell/Subprocess/clone-follow-parent-wp.test +++ lldb/test/Shell/Subprocess/clone-follow-parent-wp.test @@ -11,4 +11,5 @@ # CHECK: stop reason = watchpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/clone-follow-parent.test =================================================================== --- lldb/test/Shell/Subprocess/clone-follow-parent.test +++ lldb/test/Shell/Subprocess/clone-follow-parent.test @@ -9,4 +9,5 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/fork-follow-child-softbp.test =================================================================== --- lldb/test/Shell/Subprocess/fork-follow-child-softbp.test +++ lldb/test/Shell/Subprocess/fork-follow-child-softbp.test @@ -4,10 +4,13 @@ # RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_FORK=fork -o %t # RUN: %lldb -b -s %s %t | FileCheck %s settings set target.process.follow-fork-mode child +settings set target.process.stop-on-exec false b child_func b parent_func process launch +# CHECK: function run in parent # CHECK: stop reason = breakpoint # CHECK-NEXT: child_func continue -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/fork-follow-child-wp.test =================================================================== --- lldb/test/Shell/Subprocess/fork-follow-child-wp.test +++ lldb/test/Shell/Subprocess/fork-follow-child-wp.test @@ -4,12 +4,15 @@ # RUN: %clangxx_host -g %p/Inputs/fork.cpp -DTEST_FORK=fork -o %t # RUN: %lldb -b -s %s %t | FileCheck %s settings set target.process.follow-fork-mode child +settings set target.process.stop-on-exec false process launch -s watchpoint set variable -w write g_val # CHECK: Watchpoint created: continue +# CHECK: function run in parent # CHECK: stop reason = watchpoint continue # CHECK: stop reason = watchpoint continue -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/fork-follow-child.test =================================================================== --- lldb/test/Shell/Subprocess/fork-follow-child.test +++ lldb/test/Shell/Subprocess/fork-follow-child.test @@ -4,7 +4,9 @@ # RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_FORK=fork -o %t # RUN: %lldb -b -s %s %t | FileCheck %s settings set target.process.follow-fork-mode child +settings set target.process.stop-on-exec false b parent_func process launch # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test =================================================================== --- lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test +++ lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test @@ -11,4 +11,5 @@ # CHECK-NEXT: parent_func continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/fork-follow-parent-wp.test =================================================================== --- lldb/test/Shell/Subprocess/fork-follow-parent-wp.test +++ lldb/test/Shell/Subprocess/fork-follow-parent-wp.test @@ -10,4 +10,5 @@ # CHECK: stop reason = watchpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/fork-follow-parent.test =================================================================== --- lldb/test/Shell/Subprocess/fork-follow-parent.test +++ lldb/test/Shell/Subprocess/fork-follow-parent.test @@ -8,4 +8,5 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/vfork-follow-child-softbp.test =================================================================== --- lldb/test/Shell/Subprocess/vfork-follow-child-softbp.test +++ lldb/test/Shell/Subprocess/vfork-follow-child-softbp.test @@ -1,13 +1,13 @@ # REQUIRES: native # UNSUPPORTED: system-darwin # UNSUPPORTED: system-windows -# This test is very flaky on aarch64. -# UNSUPPORTED: system-linux && target-aarch64 # RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_FORK=vfork -o %t # RUN: %lldb -b -s %s %t | FileCheck %s settings set target.process.follow-fork-mode child +settings set target.process.stop-on-exec false b child_func b parent_func process launch # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/vfork-follow-child-wp.test =================================================================== --- lldb/test/Shell/Subprocess/vfork-follow-child-wp.test +++ lldb/test/Shell/Subprocess/vfork-follow-child-wp.test @@ -1,13 +1,14 @@ # REQUIRES: native && dbregs-set # UNSUPPORTED: system-darwin # UNSUPPORTED: system-windows -# This test is very flaky on aarch64. -# UNSUPPORTED: system-linux && target-aarch64 # RUN: %clangxx_host -g %p/Inputs/fork.cpp -DTEST_FORK=vfork -o %t # RUN: %lldb -b -s %s %t | FileCheck %s settings set target.process.follow-fork-mode child +settings set target.process.stop-on-exec false process launch -s watchpoint set variable -w write g_val # CHECK: Watchpoint created: continue -# CHECK: child exited: 0 +# CHECK: function run in parent +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/vfork-follow-child.test =================================================================== --- lldb/test/Shell/Subprocess/vfork-follow-child.test +++ lldb/test/Shell/Subprocess/vfork-follow-child.test @@ -1,12 +1,12 @@ # REQUIRES: native # UNSUPPORTED: system-darwin # UNSUPPORTED: system-windows -# This test is very flaky on aarch64. -# UNSUPPORTED: system-linux && target-aarch64 # RUN: %clangxx_host %p/Inputs/fork.cpp -DTEST_FORK=vfork -o %t # RUN: %lldb -b -s %s %t | FileCheck %s settings set target.process.follow-fork-mode child +settings set target.process.stop-on-exec false b parent_func process launch # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test =================================================================== --- lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test +++ lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test @@ -10,4 +10,5 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test =================================================================== --- lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test +++ lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test @@ -11,4 +11,5 @@ # CHECK: stop reason = watchpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/test/Shell/Subprocess/vfork-follow-parent.test =================================================================== --- lldb/test/Shell/Subprocess/vfork-follow-parent.test +++ lldb/test/Shell/Subprocess/vfork-follow-parent.test @@ -8,4 +8,5 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child +# CHECK: Process {{[0-9]+}} exited with status = 0