[Lldb-commits] [lldb] 7fc12da - [lldb] [test] Split TestGdbRemoteFork in two

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Tue Jun 28 21:57:50 PDT 2022


Author: Michał Górny
Date: 2022-06-29T06:57:38+02:00
New Revision: 7fc12da898e05e68ec59fbe852c4402378938efa

URL: https://github.com/llvm/llvm-project/commit/7fc12da898e05e68ec59fbe852c4402378938efa
DIFF: https://github.com/llvm/llvm-project/commit/7fc12da898e05e68ec59fbe852c4402378938efa.diff

LOG: [lldb] [test] Split TestGdbRemoteFork in two

Split the test that's gotten very long in two, in hope that it will
resolve the arm/aarch64 buildbot failures.  Even if it does not, it
could help pinpointing where the problem lies.

Sponsored by: The FreeBSD Foundation

Added: 
    lldb/packages/Python/lldbsuite/test/tools/lldb-server/fork_testbase.py
    lldb/test/API/tools/lldb-server/TestGdbRemoteForkNonStop.py

Modified: 
    lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py

Removed: 
    


################################################################################
diff  --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/fork_testbase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/fork_testbase.py
new file mode 100644
index 000000000000..42833a15318f
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/fork_testbase.py
@@ -0,0 +1,204 @@
+import gdbremote_testcase
+
+
+class GdbRemoteForkTestBase(gdbremote_testcase.GdbRemoteTestCaseBase):
+    fork_regex = ("[$]T05thread:p([0-9a-f]+)[.]([0-9a-f]+);.*"
+                  "{}:p([0-9a-f]+)[.]([0-9a-f]+).*")
+    fork_regex_nonstop = ("%Stop:T05thread:p([0-9a-f]+)[.]([0-9a-f]+);.*"
+                          "{}:p([0-9a-f]+)[.]([0-9a-f]+).*")
+    fork_capture = {1: "parent_pid", 2: "parent_tid",
+                    3: "child_pid", 4: "child_tid"}
+
+    def start_fork_test(self, args, variant="fork", nonstop=False):
+        self.build()
+        self.prep_debug_monitor_and_inferior(inferior_args=args)
+        self.add_qSupported_packets(["multiprocess+",
+                                     "{}-events+".format(variant)])
+        ret = self.expect_gdbremote_sequence()
+        self.assertIn("{}-events+".format(variant), ret["qSupported_response"])
+        self.reset_test_sequence()
+
+        # continue and expect fork
+        if nonstop:
+            self.test_sequence.add_log_lines([
+                "read packet: $QNonStop:1#00",
+                "send packet: $OK#00",
+                "read packet: $c#00",
+                "send packet: $OK#00",
+                {"direction": "send",
+                 "regex": self.fork_regex_nonstop.format(variant),
+                 "capture": self.fork_capture},
+                "read packet: $vStopped#00",
+                "send packet: $OK#00",
+            ], True)
+        else:
+            self.test_sequence.add_log_lines([
+                "read packet: $c#00",
+                {"direction": "send", "regex": self.fork_regex.format(variant),
+                 "capture": self.fork_capture},
+            ], True)
+        ret = self.expect_gdbremote_sequence()
+        self.reset_test_sequence()
+
+        return tuple(ret[x] for x in ("parent_pid", "parent_tid",
+                                      "child_pid", "child_tid"))
+
+    def fork_and_detach_test(self, variant, nonstop=False):
+        parent_pid, parent_tid, child_pid, child_tid = (
+            self.start_fork_test([variant], variant, nonstop=nonstop))
+
+        # detach the forked child
+        self.test_sequence.add_log_lines([
+            "read packet: $D;{}#00".format(child_pid),
+            "send packet: $OK#00",
+            # verify that the current process is correct
+            "read packet: $qC#00",
+            "send packet: $QCp{}.{}#00".format(parent_pid, parent_tid),
+            # verify that the correct processes are detached/available
+            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
+            "send packet: $Eff#00",
+            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
+            "send packet: $OK#00",
+        ], True)
+        self.expect_gdbremote_sequence()
+        self.reset_test_sequence()
+        return parent_pid, parent_tid
+
+    def fork_and_follow_test(self, variant, nonstop=False):
+        parent_pid, parent_tid, child_pid, child_tid = (
+            self.start_fork_test([variant], variant, nonstop=nonstop))
+
+        # switch to the forked child
+        self.test_sequence.add_log_lines([
+            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
+            "send packet: $OK#00",
+            "read packet: $Hcp{}.{}#00".format(child_pid, child_tid),
+            "send packet: $OK#00",
+            # detach the parent
+            "read packet: $D;{}#00".format(parent_pid),
+            "send packet: $OK#00",
+            # verify that the correct processes are detached/available
+            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
+            "send packet: $Eff#00",
+            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
+            "send packet: $OK#00",
+            # then resume the child
+            "read packet: $c#00",
+        ], True)
+
+        if nonstop:
+            self.test_sequence.add_log_lines([
+                "send packet: $OK#00",
+                "send packet: %Stop:W00;process:{}#00".format(child_pid),
+                "read packet: $vStopped#00",
+                "send packet: $OK#00",
+            ], True)
+        else:
+            self.test_sequence.add_log_lines([
+                "send packet: $W00;process:{}#00".format(child_pid),
+            ], True)
+        self.expect_gdbremote_sequence()
+
+    def detach_all_test(self, nonstop=False):
+        parent_pid, parent_tid, child_pid, child_tid = (
+            self.start_fork_test(["fork"], nonstop=nonstop))
+
+        self.test_sequence.add_log_lines([
+            # double-check our PIDs
+            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
+            "send packet: $OK#00",
+            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
+            "send packet: $OK#00",
+            # detach all processes
+            "read packet: $D#00",
+            "send packet: $OK#00",
+            # verify that both PIDs are invalid now
+            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
+            "send packet: $Eff#00",
+            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
+            "send packet: $Eff#00",
+        ], True)
+        self.expect_gdbremote_sequence()
+
+    def vkill_test(self, kill_parent=False, kill_child=False, nonstop=False):
+        assert kill_parent or kill_child
+        parent_pid, parent_tid, child_pid, child_tid = (
+            self.start_fork_test(["fork"], nonstop=nonstop))
+
+        if kill_parent:
+            self.test_sequence.add_log_lines([
+                # kill the process
+                "read packet: $vKill;{}#00".format(parent_pid),
+                "send packet: $OK#00",
+            ], True)
+        if kill_child:
+            self.test_sequence.add_log_lines([
+                # kill the process
+                "read packet: $vKill;{}#00".format(child_pid),
+                "send packet: $OK#00",
+            ], True)
+        self.test_sequence.add_log_lines([
+            # check child PID/TID
+            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
+            "send packet: ${}#00".format("Eff" if kill_child else "OK"),
+            # check parent PID/TID
+            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
+            "send packet: ${}#00".format("Eff" if kill_parent else "OK"),
+        ], True)
+        self.expect_gdbremote_sequence()
+
+    def resume_one_test(self, run_order, use_vCont=False, nonstop=False):
+        parent_pid, parent_tid, child_pid, child_tid = (
+            self.start_fork_test(["fork", "trap"], nonstop=nonstop))
+
+        parent_expect = [
+            "T05thread:p{}.{};.*".format(parent_pid, parent_tid),
+            "W00;process:{}#.*".format(parent_pid),
+        ]
+        child_expect = [
+            "T05thread:p{}.{};.*".format(child_pid, child_tid),
+            "W00;process:{}#.*".format(child_pid),
+        ]
+
+        for x in run_order:
+            if x == "parent":
+                pidtid = (parent_pid, parent_tid)
+                expect = parent_expect.pop(0)
+            elif x == "child":
+                pidtid = (child_pid, child_tid)
+                expect = child_expect.pop(0)
+            else:
+                assert False, "unexpected x={}".format(x)
+
+            if use_vCont:
+                self.test_sequence.add_log_lines([
+                    # continue the selected process
+                    "read packet: $vCont;c:p{}.{}#00".format(*pidtid),
+                ], True)
+            else:
+                self.test_sequence.add_log_lines([
+                    # continue the selected process
+                    "read packet: $Hcp{}.{}#00".format(*pidtid),
+                    "send packet: $OK#00",
+                    "read packet: $c#00",
+                ], True)
+            if nonstop:
+                self.test_sequence.add_log_lines([
+                    "send packet: $OK#00",
+                    {"direction": "send", "regex": "%Stop:" + expect},
+                    "read packet: $vStopped#00",
+                    "send packet: $OK#00",
+                ], True)
+            else:
+                self.test_sequence.add_log_lines([
+                    {"direction": "send", "regex": "[$]" + expect},
+                ], True)
+            # if at least one process remained, check both PIDs
+            if parent_expect or child_expect:
+                self.test_sequence.add_log_lines([
+                    "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
+                    "send packet: ${}#00".format("OK" if parent_expect else "Eff"),
+                    "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
+                    "send packet: ${}#00".format("OK" if child_expect else "Eff"),
+                ], True)
+        self.expect_gdbremote_sequence()

diff  --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py b/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
index c58f0fc381eb..81be3c67399e 100644
--- a/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
@@ -1,53 +1,12 @@
 import random
 
-import gdbremote_testcase
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
 
-class TestGdbRemoteFork(gdbremote_testcase.GdbRemoteTestCaseBase):
+from fork_testbase import GdbRemoteForkTestBase
 
-    fork_regex = ("[$]T05thread:p([0-9a-f]+)[.]([0-9a-f]+);.*"
-                  "{}:p([0-9a-f]+)[.]([0-9a-f]+).*")
-    fork_regex_nonstop = ("%Stop:T05thread:p([0-9a-f]+)[.]([0-9a-f]+);.*"
-                          "{}:p([0-9a-f]+)[.]([0-9a-f]+).*")
-    fork_capture = {1: "parent_pid", 2: "parent_tid",
-                    3: "child_pid", 4: "child_tid"}
-
-    def start_fork_test(self, args, variant="fork", nonstop=False):
-        self.build()
-        self.prep_debug_monitor_and_inferior(inferior_args=args)
-        self.add_qSupported_packets(["multiprocess+",
-                                     "{}-events+".format(variant)])
-        ret = self.expect_gdbremote_sequence()
-        self.assertIn("{}-events+".format(variant), ret["qSupported_response"])
-        self.reset_test_sequence()
-
-        # continue and expect fork
-        if nonstop:
-            self.test_sequence.add_log_lines([
-                "read packet: $QNonStop:1#00",
-                "send packet: $OK#00",
-                "read packet: $c#00",
-                "send packet: $OK#00",
-                {"direction": "send",
-                 "regex": self.fork_regex_nonstop.format(variant),
-                 "capture": self.fork_capture},
-                "read packet: $vStopped#00",
-                "send packet: $OK#00",
-            ], True)
-        else:
-            self.test_sequence.add_log_lines([
-                "read packet: $c#00",
-                {"direction": "send", "regex": self.fork_regex.format(variant),
-                 "capture": self.fork_capture},
-            ], True)
-        ret = self.expect_gdbremote_sequence()
-        self.reset_test_sequence()
-
-        return tuple(ret[x] for x in ("parent_pid", "parent_tid",
-                                      "child_pid", "child_tid"))
 
+class TestGdbRemoteFork(GdbRemoteForkTestBase):
     @add_test_categories(["fork"])
     def test_fork_multithreaded(self):
         _, _, child_pid, _ = self.start_fork_test(["thread:new"]*2 + ["fork"])
@@ -60,27 +19,6 @@ def test_fork_multithreaded(self):
         ], True)
         self.expect_gdbremote_sequence()
 
-    def fork_and_detach_test(self, variant, nonstop=False):
-        parent_pid, parent_tid, child_pid, child_tid = (
-            self.start_fork_test([variant], variant, nonstop=nonstop))
-
-        # detach the forked child
-        self.test_sequence.add_log_lines([
-            "read packet: $D;{}#00".format(child_pid),
-            "send packet: $OK#00",
-            # verify that the current process is correct
-            "read packet: $qC#00",
-            "send packet: $QCp{}.{}#00".format(parent_pid, parent_tid),
-            # verify that the correct processes are detached/available
-            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
-            "send packet: $Eff#00",
-            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
-            "send packet: $OK#00",
-        ], True)
-        self.expect_gdbremote_sequence()
-        self.reset_test_sequence()
-        return parent_pid, parent_tid
-
     @add_test_categories(["fork"])
     def test_fork(self):
         parent_pid, _ = self.fork_and_detach_test("fork")
@@ -92,20 +30,6 @@ def test_fork(self):
         ], True)
         self.expect_gdbremote_sequence()
 
-    @add_test_categories(["fork"])
-    def test_fork_nonstop(self):
-        parent_pid, _ = self.fork_and_detach_test("fork", nonstop=True)
-
-        # resume the parent
-        self.test_sequence.add_log_lines([
-            "read packet: $c#00",
-            "send packet: $OK#00",
-            "send packet: %Stop:W00;process:{}#00".format(parent_pid),
-            "read packet: $vStopped#00",
-            "send packet: $OK#00",
-        ], True)
-        self.expect_gdbremote_sequence()
-
     @add_test_categories(["fork"])
     def test_vfork(self):
         parent_pid, parent_tid = self.fork_and_detach_test("vfork")
@@ -122,80 +46,14 @@ def test_vfork(self):
         ], True)
         self.expect_gdbremote_sequence()
 
-    @add_test_categories(["fork"])
-    def test_vfork_nonstop(self):
-        parent_pid, parent_tid = self.fork_and_detach_test("vfork",
-                                                           nonstop=True)
-
-        # resume the parent
-        self.test_sequence.add_log_lines([
-            "read packet: $c#00",
-            "send packet: $OK#00",
-            {"direction": "send",
-             "regex": r"%Stop:T05thread:p{}[.]{}.*vforkdone.*".format(
-                 parent_pid, parent_tid),
-             },
-            "read packet: $vStopped#00",
-            "send packet: $OK#00",
-            "read packet: $c#00",
-            "send packet: $OK#00",
-            "send packet: %Stop:W00;process:{}#00".format(parent_pid),
-            "read packet: $vStopped#00",
-            "send packet: $OK#00",
-        ], True)
-        self.expect_gdbremote_sequence()
-
-    def fork_and_follow_test(self, variant, nonstop=False):
-        parent_pid, parent_tid, child_pid, child_tid = (
-            self.start_fork_test([variant], variant, nonstop=nonstop))
-
-        # switch to the forked child
-        self.test_sequence.add_log_lines([
-            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
-            "send packet: $OK#00",
-            "read packet: $Hcp{}.{}#00".format(child_pid, child_tid),
-            "send packet: $OK#00",
-            # detach the parent
-            "read packet: $D;{}#00".format(parent_pid),
-            "send packet: $OK#00",
-            # verify that the correct processes are detached/available
-            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
-            "send packet: $Eff#00",
-            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
-            "send packet: $OK#00",
-            # then resume the child
-            "read packet: $c#00",
-        ], True)
-
-        if nonstop:
-            self.test_sequence.add_log_lines([
-                "send packet: $OK#00",
-                "send packet: %Stop:W00;process:{}#00".format(child_pid),
-                "read packet: $vStopped#00",
-                "send packet: $OK#00",
-            ], True)
-        else:
-            self.test_sequence.add_log_lines([
-                "send packet: $W00;process:{}#00".format(child_pid),
-            ], True)
-        self.expect_gdbremote_sequence()
-
     @add_test_categories(["fork"])
     def test_fork_follow(self):
         self.fork_and_follow_test("fork")
 
-    @add_test_categories(["fork"])
-    def test_fork_follow_nonstop(self):
-        self.fork_and_follow_test("fork", nonstop=True)
-
     @add_test_categories(["fork"])
     def test_vfork_follow(self):
         self.fork_and_follow_test("vfork")
 
-    @add_test_categories(["fork"])
-    def test_vfork_follow_nonstop(self):
-        self.fork_and_follow_test("vfork", nonstop=True)
-
     @add_test_categories(["fork"])
     def test_select_wrong_pid(self):
         self.build()
@@ -262,35 +120,10 @@ def test_detach_current(self):
         ], True)
         self.expect_gdbremote_sequence()
 
-    def detach_all_test(self, nonstop=False):
-        parent_pid, parent_tid, child_pid, child_tid = (
-            self.start_fork_test(["fork"], nonstop=nonstop))
-
-        self.test_sequence.add_log_lines([
-            # double-check our PIDs
-            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
-            "send packet: $OK#00",
-            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
-            "send packet: $OK#00",
-            # detach all processes
-            "read packet: $D#00",
-            "send packet: $OK#00",
-            # verify that both PIDs are invalid now
-            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
-            "send packet: $Eff#00",
-            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
-            "send packet: $Eff#00",
-        ], True)
-        self.expect_gdbremote_sequence()
-
     @add_test_categories(["fork"])
     def test_detach_all(self):
         self.detach_all_test()
 
-    @add_test_categories(["fork"])
-    def test_detach_all_nonstop(self):
-        self.detach_all_test(nonstop=True)
-
     @add_test_categories(["fork"])
     def test_kill_all(self):
         parent_pid, _, child_pid, _ = self.start_fork_test(["fork"])
@@ -308,74 +141,6 @@ def test_kill_all(self):
         self.assertEqual(set([ret["pid1"], ret["pid2"]]),
                          set([parent_pid, child_pid]))
 
-    @add_test_categories(["fork"])
-    def test_kill_all_nonstop(self):
-        parent_pid, _, child_pid, _ = self.start_fork_test(["fork"],
-                                                           nonstop=True)
-
-        exit_regex = "X09;process:([0-9a-f]+)"
-        # Depending on a potential race, the second kill may make it into
-        # the async queue before we issue vStopped or after.  In the former
-        # case, we should expect the exit status in reply to vStopped.
-        # In the latter, we should expect an OK response (queue empty),
-        # followed by another async notification.
-        vstop_regex = "[$](OK|{})#.*".format(exit_regex)
-        self.test_sequence.add_log_lines([
-            # kill all processes
-            "read packet: $k#00",
-            "send packet: $OK#00",
-            {"direction": "send", "regex": "%Stop:{}#.*".format(exit_regex),
-             "capture": {1: "pid1"}},
-            "read packet: $vStopped#00",
-            {"direction": "send", "regex": vstop_regex,
-             "capture": {1: "vstop_reply", 2: "pid2"}},
-        ], True)
-        ret = self.expect_gdbremote_sequence()
-        pid1 = ret["pid1"]
-        if ret["vstop_reply"] == "OK":
-            self.reset_test_sequence()
-            self.test_sequence.add_log_lines([
-                {"direction": "send", "regex": "%Stop:{}#.*".format(exit_regex),
-                 "capture": {1: "pid2"}},
-            ], True)
-            ret = self.expect_gdbremote_sequence()
-        pid2 = ret["pid2"]
-        self.reset_test_sequence()
-        self.test_sequence.add_log_lines([
-            "read packet: $vStopped#00",
-            "send packet: $OK#00",
-        ], True)
-        self.expect_gdbremote_sequence()
-        self.assertEqual(set([ret["pid1"], ret["pid2"]]),
-                         set([parent_pid, child_pid]))
-
-    def vkill_test(self, kill_parent=False, kill_child=False, nonstop=False):
-        assert kill_parent or kill_child
-        parent_pid, parent_tid, child_pid, child_tid = (
-            self.start_fork_test(["fork"], nonstop=nonstop))
-
-        if kill_parent:
-            self.test_sequence.add_log_lines([
-                # kill the process
-                "read packet: $vKill;{}#00".format(parent_pid),
-                "send packet: $OK#00",
-            ], True)
-        if kill_child:
-            self.test_sequence.add_log_lines([
-                # kill the process
-                "read packet: $vKill;{}#00".format(child_pid),
-                "send packet: $OK#00",
-            ], True)
-        self.test_sequence.add_log_lines([
-            # check child PID/TID
-            "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
-            "send packet: ${}#00".format("Eff" if kill_child else "OK"),
-            # check parent PID/TID
-            "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
-            "send packet: ${}#00".format("Eff" if kill_parent else "OK"),
-        ], True)
-        self.expect_gdbremote_sequence()
-
     @add_test_categories(["fork"])
     def test_vkill_child(self):
         self.vkill_test(kill_child=True)
@@ -388,66 +153,6 @@ def test_vkill_parent(self):
     def test_vkill_both(self):
         self.vkill_test(kill_parent=True, kill_child=True)
 
-    @add_test_categories(["fork"])
-    def test_vkill_both_nonstop(self):
-        self.vkill_test(kill_parent=True, kill_child=True, nonstop=True)
-
-    def resume_one_test(self, run_order, use_vCont=False, nonstop=False):
-        parent_pid, parent_tid, child_pid, child_tid = (
-            self.start_fork_test(["fork", "trap"], nonstop=nonstop))
-
-        parent_expect = [
-            "T05thread:p{}.{};.*".format(parent_pid, parent_tid),
-            "W00;process:{}#.*".format(parent_pid),
-        ]
-        child_expect = [
-            "T05thread:p{}.{};.*".format(child_pid, child_tid),
-            "W00;process:{}#.*".format(child_pid),
-        ]
-
-        for x in run_order:
-            if x == "parent":
-                pidtid = (parent_pid, parent_tid)
-                expect = parent_expect.pop(0)
-            elif x == "child":
-                pidtid = (child_pid, child_tid)
-                expect = child_expect.pop(0)
-            else:
-                assert False, "unexpected x={}".format(x)
-
-            if use_vCont:
-                self.test_sequence.add_log_lines([
-                    # continue the selected process
-                    "read packet: $vCont;c:p{}.{}#00".format(*pidtid),
-                ], True)
-            else:
-                self.test_sequence.add_log_lines([
-                    # continue the selected process
-                    "read packet: $Hcp{}.{}#00".format(*pidtid),
-                    "send packet: $OK#00",
-                    "read packet: $c#00",
-                ], True)
-            if nonstop:
-                self.test_sequence.add_log_lines([
-                    "send packet: $OK#00",
-                    {"direction": "send", "regex": "%Stop:" + expect},
-                    "read packet: $vStopped#00",
-                    "send packet: $OK#00",
-                ], True)
-            else:
-                self.test_sequence.add_log_lines([
-                    {"direction": "send", "regex": "[$]" + expect},
-                ], True)
-            # if at least one process remained, check both PIDs
-            if parent_expect or child_expect:
-                self.test_sequence.add_log_lines([
-                    "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
-                    "send packet: ${}#00".format("OK" if parent_expect else "Eff"),
-                    "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
-                    "send packet: ${}#00".format("OK" if child_expect else "Eff"),
-                ], True)
-        self.expect_gdbremote_sequence()
-
     @expectedFailureAll(archs=["arm"])  # TODO
     @expectedFailureAll(archs=["aarch64"],
                         bugnumber="https://github.com/llvm/llvm-project/issues/56268")
@@ -483,14 +188,6 @@ def test_c_child_then_parent(self):
     def test_c_interspersed(self):
         self.resume_one_test(run_order=["parent", "child", "parent", "child"])
 
-    @expectedFailureAll(archs=["arm"])  # TODO
-    @expectedFailureAll(archs=["aarch64"],
-                        bugnumber="https://github.com/llvm/llvm-project/issues/56268")
-    @add_test_categories(["fork"])
-    def test_c_interspersed_nonstop(self):
-        self.resume_one_test(run_order=["parent", "child", "parent", "child"],
-                             nonstop=True)
-
     @expectedFailureAll(archs=["arm"])  # TODO
     @expectedFailureAll(archs=["aarch64"],
                         bugnumber="https://github.com/llvm/llvm-project/issues/56268")
@@ -529,14 +226,6 @@ def test_vCont_interspersed(self):
         self.resume_one_test(run_order=["parent", "child", "parent", "child"],
                              use_vCont=True)
 
-    @expectedFailureAll(archs=["arm"])  # TODO
-    @expectedFailureAll(archs=["aarch64"],
-                        bugnumber="https://github.com/llvm/llvm-project/issues/56268")
-    @add_test_categories(["fork"])
-    def test_vCont_interspersed_nonstop(self):
-        self.resume_one_test(run_order=["parent", "child", "parent", "child"],
-                             use_vCont=True, nonstop=True)
-
     @add_test_categories(["fork"])
     def test_vCont_two_processes(self):
         parent_pid, parent_tid, child_pid, child_tid = (

diff  --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteForkNonStop.py b/lldb/test/API/tools/lldb-server/TestGdbRemoteForkNonStop.py
new file mode 100644
index 000000000000..6b5010da9b19
--- /dev/null
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteForkNonStop.py
@@ -0,0 +1,116 @@
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+from fork_testbase import GdbRemoteForkTestBase
+
+
+class TestGdbRemoteForkNonStop(GdbRemoteForkTestBase):
+    @add_test_categories(["fork"])
+    def test_vfork_nonstop(self):
+        parent_pid, parent_tid = self.fork_and_detach_test("vfork",
+                                                           nonstop=True)
+
+        # resume the parent
+        self.test_sequence.add_log_lines([
+            "read packet: $c#00",
+            "send packet: $OK#00",
+            {"direction": "send",
+             "regex": r"%Stop:T05thread:p{}[.]{}.*vforkdone.*".format(
+                 parent_pid, parent_tid),
+             },
+            "read packet: $vStopped#00",
+            "send packet: $OK#00",
+            "read packet: $c#00",
+            "send packet: $OK#00",
+            "send packet: %Stop:W00;process:{}#00".format(parent_pid),
+            "read packet: $vStopped#00",
+            "send packet: $OK#00",
+        ], True)
+        self.expect_gdbremote_sequence()
+
+    @add_test_categories(["fork"])
+    def test_fork_nonstop(self):
+        parent_pid, _ = self.fork_and_detach_test("fork", nonstop=True)
+
+        # resume the parent
+        self.test_sequence.add_log_lines([
+            "read packet: $c#00",
+            "send packet: $OK#00",
+            "send packet: %Stop:W00;process:{}#00".format(parent_pid),
+            "read packet: $vStopped#00",
+            "send packet: $OK#00",
+        ], True)
+        self.expect_gdbremote_sequence()
+
+    @add_test_categories(["fork"])
+    def test_fork_follow_nonstop(self):
+        self.fork_and_follow_test("fork", nonstop=True)
+
+    @add_test_categories(["fork"])
+    def test_vfork_follow_nonstop(self):
+        self.fork_and_follow_test("vfork", nonstop=True)
+
+    @add_test_categories(["fork"])
+    def test_detach_all_nonstop(self):
+        self.detach_all_test(nonstop=True)
+
+    @add_test_categories(["fork"])
+    def test_kill_all_nonstop(self):
+        parent_pid, _, child_pid, _ = self.start_fork_test(["fork"],
+                                                           nonstop=True)
+
+        exit_regex = "X09;process:([0-9a-f]+)"
+        # Depending on a potential race, the second kill may make it into
+        # the async queue before we issue vStopped or after.  In the former
+        # case, we should expect the exit status in reply to vStopped.
+        # In the latter, we should expect an OK response (queue empty),
+        # followed by another async notification.
+        vstop_regex = "[$](OK|{})#.*".format(exit_regex)
+        self.test_sequence.add_log_lines([
+            # kill all processes
+            "read packet: $k#00",
+            "send packet: $OK#00",
+            {"direction": "send", "regex": "%Stop:{}#.*".format(exit_regex),
+             "capture": {1: "pid1"}},
+            "read packet: $vStopped#00",
+            {"direction": "send", "regex": vstop_regex,
+             "capture": {1: "vstop_reply", 2: "pid2"}},
+        ], True)
+        ret = self.expect_gdbremote_sequence()
+        pid1 = ret["pid1"]
+        if ret["vstop_reply"] == "OK":
+            self.reset_test_sequence()
+            self.test_sequence.add_log_lines([
+                {"direction": "send", "regex": "%Stop:{}#.*".format(exit_regex),
+                 "capture": {1: "pid2"}},
+            ], True)
+            ret = self.expect_gdbremote_sequence()
+        pid2 = ret["pid2"]
+        self.reset_test_sequence()
+        self.test_sequence.add_log_lines([
+            "read packet: $vStopped#00",
+            "send packet: $OK#00",
+        ], True)
+        self.expect_gdbremote_sequence()
+        self.assertEqual(set([ret["pid1"], ret["pid2"]]),
+                         set([parent_pid, child_pid]))
+
+    @add_test_categories(["fork"])
+    def test_vkill_both_nonstop(self):
+        self.vkill_test(kill_parent=True, kill_child=True, nonstop=True)
+
+    @expectedFailureAll(archs=["arm"])  # TODO
+    @expectedFailureAll(archs=["aarch64"],
+                        bugnumber="https://github.com/llvm/llvm-project/issues/56268")
+    @add_test_categories(["fork"])
+    def test_c_interspersed_nonstop(self):
+        self.resume_one_test(run_order=["parent", "child", "parent", "child"],
+                             nonstop=True)
+
+    @expectedFailureAll(archs=["arm"])  # TODO
+    @expectedFailureAll(archs=["aarch64"],
+                        bugnumber="https://github.com/llvm/llvm-project/issues/56268")
+    @add_test_categories(["fork"])
+    def test_vCont_interspersed_nonstop(self):
+        self.resume_one_test(run_order=["parent", "child", "parent", "child"],
+                             use_vCont=True, nonstop=True)


        


More information about the lldb-commits mailing list