mgorny created this revision.
mgorny added reviewers: labath, emaste, krytarowski.
mgorny requested review of this revision.

Add synchronization routines to ensure that Subprocess tests output
in a predictable order, and all test strings are output before the tests
terminate.


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,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-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-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-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-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/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/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-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-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-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-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/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/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-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-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-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-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/Inputs/fork.cpp
===================================================================
--- lldb/test/Shell/Subprocess/Inputs/fork.cpp
+++ lldb/test/Shell/Subprocess/Inputs/fork.cpp
@@ -5,38 +5,108 @@
 #include <sched.h>
 #endif
 #include <stdint.h>
+#include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 
 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<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
+  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;
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to