diff --git a/lldb/test/Shell/Subprocess/Inputs/fork.cpp b/lldb/test/Shell/Subprocess/Inputs/fork.cpp --- a/lldb/test/Shell/Subprocess/Inputs/fork.cpp +++ b/lldb/test/Shell/Subprocess/Inputs/fork.cpp @@ -5,6 +5,7 @@ #include #endif #include +#include #include #include @@ -15,28 +16,87 @@ printf("function run in parent\n"); } -int child_func(void *unused) { +int parent_done[2]; +char parent_done_str[16]; + +void wait_for_parent() { + char buf[2]; + // wait for the parent to finish its part + int ret = read(parent_done[0], buf, sizeof(buf)); + assert(ret == 2); + ret = close(parent_done[0]); + assert(ret == 0); +} + +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 +#if defined(TEST_FORK) + if (TEST_FORK != vfork) +#endif + wait_for_parent(); + + int ret = close(parent_done[1]); + 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, 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]) { + parent_done[0] = atoi(argv[1]); + assert(parent_done[0] != 0); + +#if defined(TEST_FORK) + // for vfork(), we need to synchronize after exec + if (TEST_FORK == vfork) + wait_for_parent(); +#endif + + fprintf(stderr, "function run in exec'd child\n"); + return 0; + } + + ret = pipe(parent_done); + assert(ret == 0); + + ret = snprintf(parent_done_str, sizeof(parent_done_str), + "%d", parent_done[0]); + 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); + parent_func(); + + // resume the child + ret = write(parent_done[1], "go", 2); + assert(ret == 2); + ret = close(parent_done[1]); + assert(ret == 0); + int status, wait_flags = 0; #if defined(TEST_CLONE) wait_flags = __WALL; @@ -44,7 +104,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; } diff --git a/lldb/test/Shell/Subprocess/clone-follow-child-softbp.test b/lldb/test/Shell/Subprocess/clone-follow-child-softbp.test --- a/lldb/test/Shell/Subprocess/clone-follow-child-softbp.test +++ b/lldb/test/Shell/Subprocess/clone-follow-child-softbp.test @@ -4,10 +4,12 @@ # 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 diff --git a/lldb/test/Shell/Subprocess/clone-follow-child-wp.test b/lldb/test/Shell/Subprocess/clone-follow-child-wp.test --- a/lldb/test/Shell/Subprocess/clone-follow-child-wp.test +++ b/lldb/test/Shell/Subprocess/clone-follow-child-wp.test @@ -4,12 +4,14 @@ # 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 diff --git a/lldb/test/Shell/Subprocess/clone-follow-child.test b/lldb/test/Shell/Subprocess/clone-follow-child.test --- a/lldb/test/Shell/Subprocess/clone-follow-child.test +++ b/lldb/test/Shell/Subprocess/clone-follow-child.test @@ -4,7 +4,8 @@ # 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 diff --git a/lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test b/lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test --- a/lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test +++ b/lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test @@ -10,4 +10,4 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child diff --git a/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test b/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test --- a/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test +++ b/lldb/test/Shell/Subprocess/clone-follow-parent-wp.test @@ -11,4 +11,4 @@ # CHECK: stop reason = watchpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child diff --git a/lldb/test/Shell/Subprocess/clone-follow-parent.test b/lldb/test/Shell/Subprocess/clone-follow-parent.test --- a/lldb/test/Shell/Subprocess/clone-follow-parent.test +++ b/lldb/test/Shell/Subprocess/clone-follow-parent.test @@ -9,4 +9,4 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child diff --git a/lldb/test/Shell/Subprocess/fork-follow-child-softbp.test b/lldb/test/Shell/Subprocess/fork-follow-child-softbp.test --- a/lldb/test/Shell/Subprocess/fork-follow-child-softbp.test +++ b/lldb/test/Shell/Subprocess/fork-follow-child-softbp.test @@ -4,10 +4,12 @@ # 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 diff --git a/lldb/test/Shell/Subprocess/fork-follow-child-wp.test b/lldb/test/Shell/Subprocess/fork-follow-child-wp.test --- a/lldb/test/Shell/Subprocess/fork-follow-child-wp.test +++ b/lldb/test/Shell/Subprocess/fork-follow-child-wp.test @@ -4,12 +4,14 @@ # 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 diff --git a/lldb/test/Shell/Subprocess/fork-follow-child.test b/lldb/test/Shell/Subprocess/fork-follow-child.test --- a/lldb/test/Shell/Subprocess/fork-follow-child.test +++ b/lldb/test/Shell/Subprocess/fork-follow-child.test @@ -4,7 +4,8 @@ # 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 diff --git a/lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test b/lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test --- a/lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test +++ b/lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test @@ -11,4 +11,4 @@ # CHECK-NEXT: parent_func continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child diff --git a/lldb/test/Shell/Subprocess/fork-follow-parent-wp.test b/lldb/test/Shell/Subprocess/fork-follow-parent-wp.test --- a/lldb/test/Shell/Subprocess/fork-follow-parent-wp.test +++ b/lldb/test/Shell/Subprocess/fork-follow-parent-wp.test @@ -10,4 +10,4 @@ # CHECK: stop reason = watchpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child diff --git a/lldb/test/Shell/Subprocess/fork-follow-parent.test b/lldb/test/Shell/Subprocess/fork-follow-parent.test --- a/lldb/test/Shell/Subprocess/fork-follow-parent.test +++ b/lldb/test/Shell/Subprocess/fork-follow-parent.test @@ -8,4 +8,4 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child diff --git a/lldb/test/Shell/Subprocess/vfork-follow-child-softbp.test b/lldb/test/Shell/Subprocess/vfork-follow-child-softbp.test --- a/lldb/test/Shell/Subprocess/vfork-follow-child-softbp.test +++ b/lldb/test/Shell/Subprocess/vfork-follow-child-softbp.test @@ -1,13 +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 child_func b parent_func process launch # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child diff --git a/lldb/test/Shell/Subprocess/vfork-follow-child-wp.test b/lldb/test/Shell/Subprocess/vfork-follow-child-wp.test --- a/lldb/test/Shell/Subprocess/vfork-follow-child-wp.test +++ b/lldb/test/Shell/Subprocess/vfork-follow-child-wp.test @@ -1,13 +1,13 @@ # 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 diff --git a/lldb/test/Shell/Subprocess/vfork-follow-child.test b/lldb/test/Shell/Subprocess/vfork-follow-child.test --- a/lldb/test/Shell/Subprocess/vfork-follow-child.test +++ b/lldb/test/Shell/Subprocess/vfork-follow-child.test @@ -1,12 +1,11 @@ # 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 diff --git a/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test b/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test --- a/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test +++ b/lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test @@ -10,4 +10,4 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child diff --git a/lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test b/lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test --- a/lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test +++ b/lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test @@ -11,4 +11,4 @@ # CHECK: stop reason = watchpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child diff --git a/lldb/test/Shell/Subprocess/vfork-follow-parent.test b/lldb/test/Shell/Subprocess/vfork-follow-parent.test --- a/lldb/test/Shell/Subprocess/vfork-follow-parent.test +++ b/lldb/test/Shell/Subprocess/vfork-follow-parent.test @@ -8,4 +8,4 @@ # CHECK: stop reason = breakpoint continue # CHECK: function run in parent -# CHECK: child exited: 0 +# CHECK: function run in exec'd child