mgorny updated this revision to Diff 371571.
mgorny added a comment.

Force sync earlier for `fork()` and `clone()` (since we don't have to wait for 
exec there). Avoid depending on ordering between child output and LLDB exit.

Stress-testing it now.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109495/new/

https://reviews.llvm.org/D109495

Files:
  lldb/test/Shell/Subprocess/Inputs/fork.cpp
  lldb/test/Shell/Subprocess/clone-follow-child-softbp.test
  lldb/test/Shell/Subprocess/clone-follow-child-wp.test
  lldb/test/Shell/Subprocess/clone-follow-child.test
  lldb/test/Shell/Subprocess/clone-follow-parent-softbp.test
  lldb/test/Shell/Subprocess/clone-follow-parent-wp.test
  lldb/test/Shell/Subprocess/clone-follow-parent.test
  lldb/test/Shell/Subprocess/fork-follow-child-softbp.test
  lldb/test/Shell/Subprocess/fork-follow-child-wp.test
  lldb/test/Shell/Subprocess/fork-follow-child.test
  lldb/test/Shell/Subprocess/fork-follow-parent-softbp.test
  lldb/test/Shell/Subprocess/fork-follow-parent-wp.test
  lldb/test/Shell/Subprocess/fork-follow-parent.test
  lldb/test/Shell/Subprocess/vfork-follow-child-softbp.test
  lldb/test/Shell/Subprocess/vfork-follow-child-wp.test
  lldb/test/Shell/Subprocess/vfork-follow-child.test
  lldb/test/Shell/Subprocess/vfork-follow-parent-softbp.test
  lldb/test/Shell/Subprocess/vfork-follow-parent-wp.test
  lldb/test/Shell/Subprocess/vfork-follow-parent.test

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,4 @@
 # CHECK: stop reason = breakpoint
 continue
 # CHECK: function run in parent
-# CHECK: child exited: 0
+# CHECK: function run in exec'd child
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,4 @@
 # CHECK: stop reason = watchpoint
 continue
 # CHECK: function run in parent
-# CHECK: child exited: 0
+# CHECK: function run in exec'd child
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,4 @@
 # CHECK: stop reason = breakpoint
 continue
 # CHECK: function run in parent
-# CHECK: child exited: 0
+# CHECK: function run in exec'd child
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,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
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,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
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,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
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,4 @@
 # CHECK: stop reason = breakpoint
 continue
 # CHECK: function run in parent
-# CHECK: child exited: 0
+# CHECK: function run in exec'd child
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,4 @@
 # CHECK: stop reason = watchpoint
 continue
 # CHECK: function run in parent
-# CHECK: child exited: 0
+# CHECK: function run in exec'd child
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,4 @@
 # CHECK-NEXT: parent_func
 continue
 # CHECK: function run in parent
-# CHECK: child exited: 0
+# CHECK: function run in exec'd child
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,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
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,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
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,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
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,4 @@
 # CHECK: stop reason = breakpoint
 continue
 # CHECK: function run in parent
-# CHECK: child exited: 0
+# CHECK: function run in exec'd child
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,4 @@
 # CHECK: stop reason = watchpoint
 continue
 # CHECK: function run in parent
-# CHECK: child exited: 0
+# CHECK: function run in exec'd child
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,4 @@
 # CHECK: stop reason = breakpoint
 continue
 # CHECK: function run in parent
-# CHECK: child exited: 0
+# CHECK: function run in exec'd child
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,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
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,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
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,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
Index: lldb/test/Shell/Subprocess/Inputs/fork.cpp
===================================================================
--- lldb/test/Shell/Subprocess/Inputs/fork.cpp
+++ lldb/test/Shell/Subprocess/Inputs/fork.cpp
@@ -5,6 +5,7 @@
 #include <sched.h>
 #endif
 #include <stdint.h>
+#include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 
@@ -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<char*>(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;
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to