[Lldb-commits] [lldb] 14d6707 - [lldb] [llgs] Add a test for multiprocess register read/write

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 24 08:20:43 PDT 2022


Author: Michał Górny
Date: 2022-06-24T17:20:24+02:00
New Revision: 14d67073359a86f1d2ae9e140f0b29aa4e63a3af

URL: https://github.com/llvm/llvm-project/commit/14d67073359a86f1d2ae9e140f0b29aa4e63a3af
DIFF: https://github.com/llvm/llvm-project/commit/14d67073359a86f1d2ae9e140f0b29aa4e63a3af.diff

LOG: [lldb] [llgs] Add a test for multiprocess register read/write

Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.llvm.org/D128153

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py b/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
index 31f8a1336b58f..78e7d24f0db93 100644
--- a/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
@@ -1,3 +1,5 @@
+import random
+
 import gdbremote_testcase
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
@@ -700,3 +702,118 @@ def test_memory_read_write(self):
             data = seven.unhexlify(ret.get("data"))
             self.assertEqual(data, name + "\0")
             self.reset_test_sequence()
+
+    @add_test_categories(["fork"])
+    def test_register_read_write(self):
+        self.build()
+        self.prep_debug_monitor_and_inferior(
+            inferior_args=["fork",
+                           "thread:new",
+                           "trap",
+                           ])
+        self.add_qSupported_packets(["multiprocess+",
+                                     "fork-events+"])
+        ret = self.expect_gdbremote_sequence()
+        self.assertIn("fork-events+", ret["qSupported_response"])
+        self.reset_test_sequence()
+
+        # continue and expect fork
+        self.test_sequence.add_log_lines([
+            "read packet: $c#00",
+            {"direction": "send", "regex": self.fork_regex.format("fork"),
+             "capture": self.fork_capture},
+        ], True)
+        self.add_threadinfo_collection_packets()
+        ret = self.expect_gdbremote_sequence()
+        pidtids = [
+            (ret["parent_pid"], ret["parent_tid"]),
+            (ret["child_pid"], ret["child_tid"]),
+        ]
+        self.reset_test_sequence()
+
+        for pidtid in pidtids:
+            self.test_sequence.add_log_lines(
+                ["read packet: $Hcp{}.{}#00".format(*pidtid),
+                 "send packet: $OK#00",
+                 "read packet: $c#00",
+                 {"direction": "send",
+                  "regex": "^[$]T05thread:p{}.{}.*".format(*pidtid),
+                  },
+                 ], True)
+
+        self.add_threadinfo_collection_packets()
+        ret = self.expect_gdbremote_sequence()
+        self.reset_test_sequence()
+
+        pidtids = set(self.parse_threadinfo_packets(ret))
+        self.assertEqual(len(pidtids), 4)
+        # first, save register values from all the threads
+        thread_regs = {}
+        for pidtid in pidtids:
+            for regno in range(256):
+                self.test_sequence.add_log_lines(
+                    ["read packet: $Hgp{:x}.{:x}#00".format(*pidtid),
+                     "send packet: $OK#00",
+                     "read packet: $p{:x}#00".format(regno),
+                     {"direction": "send",
+                      "regex": r"^[$](.+)#.*$",
+                      "capture": {1: "data"}},
+                     ], True)
+                ret = self.expect_gdbremote_sequence()
+                data = ret.get("data")
+                self.assertIsNotNone(data)
+                # ignore registers shorter than 32 bits (this also catches
+                # "Exx" errors)
+                if len(data) >= 8:
+                    break
+            else:
+                self.skipTest("no usable register found")
+            thread_regs[pidtid] = (regno, data)
+
+        vals = set(x[1] for x in thread_regs.values())
+        # NB: cheap hack to make the loop below easier
+        new_val = next(iter(vals))
+
+        # then, start altering them and verify that we don't unexpectedly
+        # change the value from another thread
+        for pidtid in pidtids:
+            old_val = thread_regs[pidtid]
+            regno = old_val[0]
+            old_val_length = len(old_val[1])
+            # generate a unique new_val
+            while new_val in vals:
+                new_val = ('{{:0{}x}}'.format(old_val_length)
+                           .format(random.getrandbits(old_val_length*4)))
+            vals.add(new_val)
+
+            self.test_sequence.add_log_lines(
+                ["read packet: $Hgp{:x}.{:x}#00".format(*pidtid),
+                 "send packet: $OK#00",
+                 "read packet: $p{:x}#00".format(regno),
+                 {"direction": "send",
+                  "regex": r"^[$](.+)#.*$",
+                  "capture": {1: "data"}},
+                 "read packet: $P{:x}={}#00".format(regno, new_val),
+                 "send packet: $OK#00",
+                 ], True)
+            ret = self.expect_gdbremote_sequence()
+            data = ret.get("data")
+            self.assertIsNotNone(data)
+            self.assertEqual(data, old_val[1])
+            thread_regs[pidtid] = (regno, new_val)
+
+        # finally, verify that new values took effect
+        for pidtid in pidtids:
+            old_val = thread_regs[pidtid]
+            self.test_sequence.add_log_lines(
+                ["read packet: $Hgp{:x}.{:x}#00".format(*pidtid),
+                 "send packet: $OK#00",
+                 "read packet: $p{:x}#00".format(old_val[0]),
+                 {"direction": "send",
+                  "regex": r"^[$](.+)#.*$",
+                  "capture": {1: "data"}},
+                 ], True)
+            ret = self.expect_gdbremote_sequence()
+            data = ret.get("data")
+            self.assertIsNotNone(data)
+            self.assertEqual(data, old_val[1])


        


More information about the lldb-commits mailing list