114d67073SMichał Górnyimport random 214d67073SMichał Górny 3bbae0c1fSMichał Górnyfrom lldbsuite.test.decorators import * 4bbae0c1fSMichał Górnyfrom lldbsuite.test.lldbtest import * 5bbae0c1fSMichał Górny 67fc12da8SMichał Górnyfrom fork_testbase import GdbRemoteForkTestBase 7bbae0c1fSMichał Górny 8313d9c15SMichał Górny 97fc12da8SMichał Górnyclass TestGdbRemoteFork(GdbRemoteForkTestBase): 10ba14e4d6SMuhammad Omair Javaid def setUp(self): 11ba14e4d6SMuhammad Omair Javaid GdbRemoteForkTestBase.setUp(self) 12*2238dcc3SJonas Devlieghere if self.getPlatform() == "linux" and self.getArchitecture() in [ 13*2238dcc3SJonas Devlieghere "arm", 14*2238dcc3SJonas Devlieghere "aarch64", 15*2238dcc3SJonas Devlieghere ]: 16ba14e4d6SMuhammad Omair Javaid self.skipTest("Unsupported for Arm/AArch64 Linux") 17ba14e4d6SMuhammad Omair Javaid 18c1829e0eSMichał Górny @add_test_categories(["fork"]) 19c1829e0eSMichał Górny def test_fork_multithreaded(self): 20c1829e0eSMichał Górny _, _, child_pid, _ = self.start_fork_test(["thread:new"] * 2 + ["fork"]) 21c1829e0eSMichał Górny 22c1829e0eSMichał Górny # detach the forked child 23*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 24*2238dcc3SJonas Devlieghere [ 25c1829e0eSMichał Górny "read packet: $D;{}#00".format(child_pid), 26c1829e0eSMichał Górny "send packet: $OK#00", 27c1829e0eSMichał Górny "read packet: $k#00", 28*2238dcc3SJonas Devlieghere ], 29*2238dcc3SJonas Devlieghere True, 30*2238dcc3SJonas Devlieghere ) 31c1829e0eSMichał Górny self.expect_gdbremote_sequence() 32c1829e0eSMichał Górny 33bbae0c1fSMichał Górny @add_test_categories(["fork"]) 34bbae0c1fSMichał Górny def test_fork(self): 35313d9c15SMichał Górny parent_pid, _ = self.fork_and_detach_test("fork") 36bbae0c1fSMichał Górny 37bbae0c1fSMichał Górny # resume the parent 38*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 39*2238dcc3SJonas Devlieghere [ 40bbae0c1fSMichał Górny "read packet: $c#00", 41313d9c15SMichał Górny "send packet: $W00;process:{}#00".format(parent_pid), 42*2238dcc3SJonas Devlieghere ], 43*2238dcc3SJonas Devlieghere True, 44*2238dcc3SJonas Devlieghere ) 45bbae0c1fSMichał Górny self.expect_gdbremote_sequence() 46bbae0c1fSMichał Górny 47bbae0c1fSMichał Górny @add_test_categories(["fork"]) 48bbae0c1fSMichał Górny def test_vfork(self): 49313d9c15SMichał Górny parent_pid, parent_tid = self.fork_and_detach_test("vfork") 50bbae0c1fSMichał Górny 51bbae0c1fSMichał Górny # resume the parent 52*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 53*2238dcc3SJonas Devlieghere [ 54bbae0c1fSMichał Górny "read packet: $c#00", 55*2238dcc3SJonas Devlieghere { 56*2238dcc3SJonas Devlieghere "direction": "send", 57*2238dcc3SJonas Devlieghere "regex": r"[$]T[0-9a-fA-F]{{2}}thread:p{}[.]{}.*vforkdone.*".format( 58*2238dcc3SJonas Devlieghere parent_pid, parent_tid 59*2238dcc3SJonas Devlieghere ), 60313d9c15SMichał Górny }, 61bbae0c1fSMichał Górny "read packet: $c#00", 62313d9c15SMichał Górny "send packet: $W00;process:{}#00".format(parent_pid), 63*2238dcc3SJonas Devlieghere ], 64*2238dcc3SJonas Devlieghere True, 65*2238dcc3SJonas Devlieghere ) 66bbae0c1fSMichał Górny self.expect_gdbremote_sequence() 67b7c14033SMichał Górny 68b415f8e3SMichał Górny @add_test_categories(["fork"]) 69b7c14033SMichał Górny def test_fork_follow(self): 70b7c14033SMichał Górny self.fork_and_follow_test("fork") 71b7c14033SMichał Górny 72b7c14033SMichał Górny @add_test_categories(["fork"]) 73b7c14033SMichał Górny def test_vfork_follow(self): 74b7c14033SMichał Górny self.fork_and_follow_test("vfork") 75b7c14033SMichał Górny 76b7c14033SMichał Górny @add_test_categories(["fork"]) 77b7c14033SMichał Górny def test_select_wrong_pid(self): 78b7c14033SMichał Górny self.build() 79b7c14033SMichał Górny self.prep_debug_monitor_and_inferior() 80b7c14033SMichał Górny self.add_qSupported_packets(["multiprocess+"]) 81b7c14033SMichał Górny ret = self.expect_gdbremote_sequence() 82b7c14033SMichał Górny self.assertIn("multiprocess+", ret["qSupported_response"]) 83b7c14033SMichał Górny self.reset_test_sequence() 84b7c14033SMichał Górny 85b7c14033SMichał Górny # get process pid 86*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 87*2238dcc3SJonas Devlieghere [ 88b7c14033SMichał Górny "read packet: $qC#00", 89*2238dcc3SJonas Devlieghere { 90*2238dcc3SJonas Devlieghere "direction": "send", 91*2238dcc3SJonas Devlieghere "regex": "[$]QCp([0-9a-f]+).([0-9a-f]+)#.*", 92*2238dcc3SJonas Devlieghere "capture": {1: "pid", 2: "tid"}, 93*2238dcc3SJonas Devlieghere }, 94*2238dcc3SJonas Devlieghere ], 95*2238dcc3SJonas Devlieghere True, 96*2238dcc3SJonas Devlieghere ) 97b7c14033SMichał Górny ret = self.expect_gdbremote_sequence() 98b7c14033SMichał Górny pid, tid = (int(ret[x], 16) for x in ("pid", "tid")) 99b7c14033SMichał Górny self.reset_test_sequence() 100b7c14033SMichał Górny 101*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 102*2238dcc3SJonas Devlieghere [ 103b7c14033SMichał Górny # try switching to correct pid 104b7c14033SMichał Górny "read packet: $Hgp{:x}.{:x}#00".format(pid, tid), 105313d9c15SMichał Górny "send packet: $OK#00", 106b7c14033SMichał Górny "read packet: $Hcp{:x}.{:x}#00".format(pid, tid), 107313d9c15SMichał Górny "send packet: $OK#00", 108b7c14033SMichał Górny # try switching to invalid tid 109b7c14033SMichał Górny "read packet: $Hgp{:x}.{:x}#00".format(pid, tid + 1), 110313d9c15SMichał Górny "send packet: $E15#00", 111b7c14033SMichał Górny "read packet: $Hcp{:x}.{:x}#00".format(pid, tid + 1), 112313d9c15SMichał Górny "send packet: $E15#00", 113b7c14033SMichał Górny # try switching to invalid pid 114b7c14033SMichał Górny "read packet: $Hgp{:x}.{:x}#00".format(pid + 1, tid), 115313d9c15SMichał Górny "send packet: $Eff#00", 116b7c14033SMichał Górny "read packet: $Hcp{:x}.{:x}#00".format(pid + 1, tid), 117313d9c15SMichał Górny "send packet: $Eff#00", 118*2238dcc3SJonas Devlieghere ], 119*2238dcc3SJonas Devlieghere True, 120*2238dcc3SJonas Devlieghere ) 121313d9c15SMichał Górny self.expect_gdbremote_sequence() 122b7c14033SMichał Górny 1234d2503cdSMichał Górny @add_test_categories(["fork"]) 124b7c14033SMichał Górny def test_detach_current(self): 125b7c14033SMichał Górny self.build() 126b7c14033SMichał Górny self.prep_debug_monitor_and_inferior() 127b7c14033SMichał Górny self.add_qSupported_packets(["multiprocess+"]) 128b7c14033SMichał Górny ret = self.expect_gdbremote_sequence() 129b7c14033SMichał Górny self.assertIn("multiprocess+", ret["qSupported_response"]) 130b7c14033SMichał Górny self.reset_test_sequence() 131b7c14033SMichał Górny 132b7c14033SMichał Górny # get process pid 133*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 134*2238dcc3SJonas Devlieghere [ 135630da0e3SMichał Górny "read packet: $qC#00", 136*2238dcc3SJonas Devlieghere { 137*2238dcc3SJonas Devlieghere "direction": "send", 138*2238dcc3SJonas Devlieghere "regex": "[$]QCp([0-9a-f]+).[0-9a-f]+#.*", 139*2238dcc3SJonas Devlieghere "capture": {1: "pid"}, 140*2238dcc3SJonas Devlieghere }, 141*2238dcc3SJonas Devlieghere ], 142*2238dcc3SJonas Devlieghere True, 143*2238dcc3SJonas Devlieghere ) 144b7c14033SMichał Górny ret = self.expect_gdbremote_sequence() 145313d9c15SMichał Górny pid = ret["pid"] 146b7c14033SMichał Górny self.reset_test_sequence() 147b7c14033SMichał Górny 148b7c14033SMichał Górny # detach the process 149*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 150*2238dcc3SJonas Devlieghere [ 151313d9c15SMichał Górny "read packet: $D;{}#00".format(pid), 152313d9c15SMichał Górny "send packet: $OK#00", 153b7c14033SMichał Górny "read packet: $qC#00", 154313d9c15SMichał Górny "send packet: $E44#00", 155*2238dcc3SJonas Devlieghere ], 156*2238dcc3SJonas Devlieghere True, 157*2238dcc3SJonas Devlieghere ) 158313d9c15SMichał Górny self.expect_gdbremote_sequence() 15913eb5b34SMichał Górny 160e8fe7e93SMichał Górny @add_test_categories(["fork"]) 161b415f8e3SMichał Górny def test_detach_all(self): 162b415f8e3SMichał Górny self.detach_all_test() 163b415f8e3SMichał Górny 164b415f8e3SMichał Górny @add_test_categories(["fork"]) 165e8fe7e93SMichał Górny def test_kill_all(self): 166c1829e0eSMichał Górny parent_pid, _, child_pid, _ = self.start_fork_test(["fork"]) 167e8fe7e93SMichał Górny 168e8fe7e93SMichał Górny exit_regex = "[$]X09;process:([0-9a-f]+)#.*" 169*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 170*2238dcc3SJonas Devlieghere [ 171e8fe7e93SMichał Górny # kill all processes 172e8fe7e93SMichał Górny "read packet: $k#00", 173*2238dcc3SJonas Devlieghere {"direction": "send", "regex": exit_regex, "capture": {1: "pid1"}}, 174*2238dcc3SJonas Devlieghere {"direction": "send", "regex": exit_regex, "capture": {1: "pid2"}}, 175*2238dcc3SJonas Devlieghere ], 176*2238dcc3SJonas Devlieghere True, 177*2238dcc3SJonas Devlieghere ) 178e8fe7e93SMichał Górny ret = self.expect_gdbremote_sequence() 179*2238dcc3SJonas Devlieghere self.assertEqual(set([ret["pid1"], ret["pid2"]]), set([parent_pid, child_pid])) 180c18784baSMichał Górny 181b415f8e3SMichał Górny @add_test_categories(["fork"]) 182c18784baSMichał Górny def test_vkill_child(self): 183c18784baSMichał Górny self.vkill_test(kill_child=True) 184c18784baSMichał Górny 185c18784baSMichał Górny @add_test_categories(["fork"]) 186c18784baSMichał Górny def test_vkill_parent(self): 187c18784baSMichał Górny self.vkill_test(kill_parent=True) 188c18784baSMichał Górny 189c18784baSMichał Górny @add_test_categories(["fork"]) 190c18784baSMichał Górny def test_vkill_both(self): 191c18784baSMichał Górny self.vkill_test(kill_parent=True, kill_child=True) 1923266b117SMichał Górny 1933266b117SMichał Górny @add_test_categories(["fork"]) 1943266b117SMichał Górny def test_c_parent(self): 1953266b117SMichał Górny self.resume_one_test(run_order=["parent", "parent"]) 1963266b117SMichał Górny 1973266b117SMichał Górny @add_test_categories(["fork"]) 1983266b117SMichał Górny def test_c_child(self): 1993266b117SMichał Górny self.resume_one_test(run_order=["child", "child"]) 2003266b117SMichał Górny 2013266b117SMichał Górny @add_test_categories(["fork"]) 2023266b117SMichał Górny def test_c_parent_then_child(self): 2033266b117SMichał Górny self.resume_one_test(run_order=["parent", "parent", "child", "child"]) 2043266b117SMichał Górny 2053266b117SMichał Górny @add_test_categories(["fork"]) 2063266b117SMichał Górny def test_c_child_then_parent(self): 2073266b117SMichał Górny self.resume_one_test(run_order=["child", "child", "parent", "parent"]) 2083266b117SMichał Górny 2093266b117SMichał Górny @add_test_categories(["fork"]) 2103266b117SMichał Górny def test_c_interspersed(self): 2113266b117SMichał Górny self.resume_one_test(run_order=["parent", "child", "parent", "child"]) 212a3422793SMichał Górny 213a3422793SMichał Górny @add_test_categories(["fork"]) 214a3422793SMichał Górny def test_vCont_parent(self): 215a3422793SMichał Górny self.resume_one_test(run_order=["parent", "parent"], use_vCont=True) 216a3422793SMichał Górny 217a3422793SMichał Górny @add_test_categories(["fork"]) 218a3422793SMichał Górny def test_vCont_child(self): 219a3422793SMichał Górny self.resume_one_test(run_order=["child", "child"], use_vCont=True) 220a3422793SMichał Górny 221a3422793SMichał Górny @add_test_categories(["fork"]) 222a3422793SMichał Górny def test_vCont_parent_then_child(self): 223*2238dcc3SJonas Devlieghere self.resume_one_test( 224*2238dcc3SJonas Devlieghere run_order=["parent", "parent", "child", "child"], use_vCont=True 225*2238dcc3SJonas Devlieghere ) 226a3422793SMichał Górny 227a3422793SMichał Górny @add_test_categories(["fork"]) 228a3422793SMichał Górny def test_vCont_child_then_parent(self): 229*2238dcc3SJonas Devlieghere self.resume_one_test( 230*2238dcc3SJonas Devlieghere run_order=["child", "child", "parent", "parent"], use_vCont=True 231*2238dcc3SJonas Devlieghere ) 232a3422793SMichał Górny 233a3422793SMichał Górny @add_test_categories(["fork"]) 234a3422793SMichał Górny def test_vCont_interspersed(self): 235*2238dcc3SJonas Devlieghere self.resume_one_test( 236*2238dcc3SJonas Devlieghere run_order=["parent", "child", "parent", "child"], use_vCont=True 237*2238dcc3SJonas Devlieghere ) 238a3422793SMichał Górny 239a3422793SMichał Górny @add_test_categories(["fork"]) 240a3422793SMichał Górny def test_vCont_two_processes(self): 241*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 242*2238dcc3SJonas Devlieghere ["fork", "stop"] 243*2238dcc3SJonas Devlieghere ) 244a3422793SMichał Górny 245*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 246*2238dcc3SJonas Devlieghere [ 247a3422793SMichał Górny # try to resume both processes 248a3422793SMichał Górny "read packet: $vCont;c:p{}.{};c:p{}.{}#00".format( 249*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid 250*2238dcc3SJonas Devlieghere ), 251a3422793SMichał Górny "send packet: $E03#00", 252*2238dcc3SJonas Devlieghere ], 253*2238dcc3SJonas Devlieghere True, 254*2238dcc3SJonas Devlieghere ) 255a3422793SMichał Górny self.expect_gdbremote_sequence() 256a3422793SMichał Górny 257a3422793SMichał Górny @add_test_categories(["fork"]) 258a3422793SMichał Górny def test_vCont_all_processes_explicit(self): 259251165b2SMichał Górny self.start_fork_test(["fork", "stop"]) 260a3422793SMichał Górny 261*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 262*2238dcc3SJonas Devlieghere [ 263a3422793SMichał Górny # try to resume all processes implicitly 264a3422793SMichał Górny "read packet: $vCont;c:p-1.-1#00", 265a3422793SMichał Górny "send packet: $E03#00", 266*2238dcc3SJonas Devlieghere ], 267*2238dcc3SJonas Devlieghere True, 268*2238dcc3SJonas Devlieghere ) 269a3422793SMichał Górny self.expect_gdbremote_sequence() 270a3422793SMichał Górny 271a3422793SMichał Górny @add_test_categories(["fork"]) 272a3422793SMichał Górny def test_vCont_all_processes_implicit(self): 273251165b2SMichał Górny self.start_fork_test(["fork", "stop"]) 274a3422793SMichał Górny 275*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 276*2238dcc3SJonas Devlieghere [ 277a3422793SMichał Górny # try to resume all processes implicitly 278a3422793SMichał Górny "read packet: $vCont;c#00", 279a3422793SMichał Górny "send packet: $E03#00", 280*2238dcc3SJonas Devlieghere ], 281*2238dcc3SJonas Devlieghere True, 282*2238dcc3SJonas Devlieghere ) 283a3422793SMichał Górny self.expect_gdbremote_sequence() 2840481d8efSMichał Górny 2850481d8efSMichał Górny @add_test_categories(["fork"]) 28675757c86SMichał Górny def test_threadinfo(self): 287*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 288*2238dcc3SJonas Devlieghere ["fork", "thread:new", "stop"] 289*2238dcc3SJonas Devlieghere ) 290c1829e0eSMichał Górny pidtids = [ 291c1829e0eSMichał Górny (parent_pid, parent_tid), 292c1829e0eSMichał Górny (child_pid, child_tid), 293c1829e0eSMichał Górny ] 29475757c86SMichał Górny 29575757c86SMichał Górny self.add_threadinfo_collection_packets() 29675757c86SMichał Górny ret = self.expect_gdbremote_sequence() 29775757c86SMichał Górny prev_pidtids = set(self.parse_threadinfo_packets(ret)) 298*2238dcc3SJonas Devlieghere self.assertEqual( 299*2238dcc3SJonas Devlieghere prev_pidtids, 300*2238dcc3SJonas Devlieghere frozenset((int(pid, 16), int(tid, 16)) for pid, tid in pidtids), 301*2238dcc3SJonas Devlieghere ) 30275757c86SMichał Górny self.reset_test_sequence() 30375757c86SMichał Górny 30475757c86SMichał Górny for pidtid in pidtids: 30575757c86SMichał Górny self.test_sequence.add_log_lines( 306*2238dcc3SJonas Devlieghere [ 307*2238dcc3SJonas Devlieghere "read packet: $Hcp{}.{}#00".format(*pidtid), 30875757c86SMichał Górny "send packet: $OK#00", 30975757c86SMichał Górny "read packet: $c#00", 310*2238dcc3SJonas Devlieghere { 311*2238dcc3SJonas Devlieghere "direction": "send", 312251165b2SMichał Górny "regex": self.stop_regex.format(*pidtid), 31375757c86SMichał Górny }, 314*2238dcc3SJonas Devlieghere ], 315*2238dcc3SJonas Devlieghere True, 316*2238dcc3SJonas Devlieghere ) 31775757c86SMichał Górny self.add_threadinfo_collection_packets() 31875757c86SMichał Górny ret = self.expect_gdbremote_sequence() 31975757c86SMichał Górny self.reset_test_sequence() 32075757c86SMichał Górny new_pidtids = set(self.parse_threadinfo_packets(ret)) 32175757c86SMichał Górny added_pidtid = new_pidtids - prev_pidtids 32275757c86SMichał Górny prev_pidtids = new_pidtids 32375757c86SMichał Górny 32475757c86SMichał Górny # verify that we've got exactly one new thread, and that 32575757c86SMichał Górny # the PID matches 32675757c86SMichał Górny self.assertEqual(len(added_pidtid), 1) 32775757c86SMichał Górny self.assertEqual(added_pidtid.pop()[0], int(pidtid[0], 16)) 32875757c86SMichał Górny 32975757c86SMichał Górny for pidtid in new_pidtids: 33075757c86SMichał Górny self.test_sequence.add_log_lines( 331*2238dcc3SJonas Devlieghere [ 332*2238dcc3SJonas Devlieghere "read packet: $Hgp{:x}.{:x}#00".format(*pidtid), 33375757c86SMichał Górny "send packet: $OK#00", 334*2238dcc3SJonas Devlieghere ], 335*2238dcc3SJonas Devlieghere True, 336*2238dcc3SJonas Devlieghere ) 33775757c86SMichał Górny self.expect_gdbremote_sequence() 33875757c86SMichał Górny 33975757c86SMichał Górny @add_test_categories(["fork"]) 3400481d8efSMichał Górny def test_memory_read_write(self): 3410481d8efSMichał Górny self.build() 3420481d8efSMichał Górny INITIAL_DATA = "Initial message" 3430481d8efSMichał Górny self.prep_debug_monitor_and_inferior( 344*2238dcc3SJonas Devlieghere inferior_args=[ 345*2238dcc3SJonas Devlieghere "set-message:{}".format(INITIAL_DATA), 3460481d8efSMichał Górny "get-data-address-hex:g_message", 3470481d8efSMichał Górny "fork", 3480481d8efSMichał Górny "print-message:", 349251165b2SMichał Górny "stop", 350*2238dcc3SJonas Devlieghere ] 351*2238dcc3SJonas Devlieghere ) 352*2238dcc3SJonas Devlieghere self.add_qSupported_packets(["multiprocess+", "fork-events+"]) 3530481d8efSMichał Górny ret = self.expect_gdbremote_sequence() 3540481d8efSMichał Górny self.assertIn("fork-events+", ret["qSupported_response"]) 3550481d8efSMichał Górny self.reset_test_sequence() 3560481d8efSMichał Górny 3570481d8efSMichał Górny # continue and expect fork 358*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 359*2238dcc3SJonas Devlieghere [ 3600481d8efSMichał Górny "read packet: $c#00", 361*2238dcc3SJonas Devlieghere { 362*2238dcc3SJonas Devlieghere "type": "output_match", 363*2238dcc3SJonas Devlieghere "regex": self.maybe_strict_output_regex( 364*2238dcc3SJonas Devlieghere r"data address: 0x([0-9a-fA-F]+)\r\n" 365*2238dcc3SJonas Devlieghere ), 366*2238dcc3SJonas Devlieghere "capture": {1: "addr"}, 367*2238dcc3SJonas Devlieghere }, 368*2238dcc3SJonas Devlieghere { 369*2238dcc3SJonas Devlieghere "direction": "send", 370*2238dcc3SJonas Devlieghere "regex": self.fork_regex.format("fork"), 371*2238dcc3SJonas Devlieghere "capture": self.fork_capture, 372*2238dcc3SJonas Devlieghere }, 373*2238dcc3SJonas Devlieghere ], 374*2238dcc3SJonas Devlieghere True, 375*2238dcc3SJonas Devlieghere ) 3760481d8efSMichał Górny ret = self.expect_gdbremote_sequence() 3770481d8efSMichał Górny pidtids = { 3780481d8efSMichał Górny "parent": (ret["parent_pid"], ret["parent_tid"]), 3790481d8efSMichał Górny "child": (ret["child_pid"], ret["child_tid"]), 3800481d8efSMichał Górny } 3810481d8efSMichał Górny addr = ret["addr"] 3820481d8efSMichał Górny self.reset_test_sequence() 3830481d8efSMichał Górny 3840481d8efSMichał Górny for name, pidtid in pidtids.items(): 3850481d8efSMichał Górny self.test_sequence.add_log_lines( 386*2238dcc3SJonas Devlieghere [ 387*2238dcc3SJonas Devlieghere "read packet: $Hgp{}.{}#00".format(*pidtid), 3880481d8efSMichał Górny "send packet: $OK#00", 3890481d8efSMichał Górny # read the current memory contents 390*2238dcc3SJonas Devlieghere "read packet: $m{},{:x}#00".format(addr, len(INITIAL_DATA) + 1), 391*2238dcc3SJonas Devlieghere { 392*2238dcc3SJonas Devlieghere "direction": "send", 3930481d8efSMichał Górny "regex": r"^[$](.+)#.*$", 394*2238dcc3SJonas Devlieghere "capture": {1: "data"}, 395*2238dcc3SJonas Devlieghere }, 3960481d8efSMichał Górny # write a new value 397*2238dcc3SJonas Devlieghere "read packet: $M{},{:x}:{}#00".format( 398*2238dcc3SJonas Devlieghere addr, len(name) + 1, seven.hexlify(name + "\0") 399*2238dcc3SJonas Devlieghere ), 4000481d8efSMichał Górny "send packet: $OK#00", 4010481d8efSMichał Górny # resume the process and wait for the trap 4020481d8efSMichał Górny "read packet: $Hcp{}.{}#00".format(*pidtid), 4030481d8efSMichał Górny "send packet: $OK#00", 4040481d8efSMichał Górny "read packet: $c#00", 405*2238dcc3SJonas Devlieghere { 406*2238dcc3SJonas Devlieghere "type": "output_match", 4070481d8efSMichał Górny "regex": self.maybe_strict_output_regex(r"message: (.*)\r\n"), 408*2238dcc3SJonas Devlieghere "capture": {1: "printed_message"}, 409*2238dcc3SJonas Devlieghere }, 410*2238dcc3SJonas Devlieghere { 411*2238dcc3SJonas Devlieghere "direction": "send", 412251165b2SMichał Górny "regex": self.stop_regex.format(*pidtid), 4130481d8efSMichał Górny }, 414*2238dcc3SJonas Devlieghere ], 415*2238dcc3SJonas Devlieghere True, 416*2238dcc3SJonas Devlieghere ) 4170481d8efSMichał Górny ret = self.expect_gdbremote_sequence() 4180481d8efSMichał Górny data = seven.unhexlify(ret["data"]) 4190481d8efSMichał Górny self.assertEqual(data, INITIAL_DATA + "\0") 420*2238dcc3SJonas Devlieghere self.assertEqual(ret["printed_message"], name) 4210481d8efSMichał Górny self.reset_test_sequence() 4220481d8efSMichał Górny 4230481d8efSMichał Górny # we do the second round separately to make sure that initial data 4240481d8efSMichał Górny # is correctly preserved while writing into the first process 4250481d8efSMichał Górny 4260481d8efSMichał Górny for name, pidtid in pidtids.items(): 4270481d8efSMichał Górny self.test_sequence.add_log_lines( 428*2238dcc3SJonas Devlieghere [ 429*2238dcc3SJonas Devlieghere "read packet: $Hgp{}.{}#00".format(*pidtid), 4300481d8efSMichał Górny "send packet: $OK#00", 4310481d8efSMichał Górny # read the current memory contents 432*2238dcc3SJonas Devlieghere "read packet: $m{},{:x}#00".format(addr, len(name) + 1), 433*2238dcc3SJonas Devlieghere { 434*2238dcc3SJonas Devlieghere "direction": "send", 4350481d8efSMichał Górny "regex": r"^[$](.+)#.*$", 436*2238dcc3SJonas Devlieghere "capture": {1: "data"}, 437*2238dcc3SJonas Devlieghere }, 438*2238dcc3SJonas Devlieghere ], 439*2238dcc3SJonas Devlieghere True, 440*2238dcc3SJonas Devlieghere ) 4410481d8efSMichał Górny ret = self.expect_gdbremote_sequence() 4420481d8efSMichał Górny self.assertIsNotNone(ret.get("data")) 4430481d8efSMichał Górny data = seven.unhexlify(ret.get("data")) 4440481d8efSMichał Górny self.assertEqual(data, name + "\0") 4450481d8efSMichał Górny self.reset_test_sequence() 44614d67073SMichał Górny 44714d67073SMichał Górny @add_test_categories(["fork"]) 44814d67073SMichał Górny def test_register_read_write(self): 449*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 450*2238dcc3SJonas Devlieghere ["fork", "thread:new", "stop"] 451*2238dcc3SJonas Devlieghere ) 45214d67073SMichał Górny pidtids = [ 453c1829e0eSMichał Górny (parent_pid, parent_tid), 454c1829e0eSMichał Górny (child_pid, child_tid), 45514d67073SMichał Górny ] 45614d67073SMichał Górny 45714d67073SMichał Górny for pidtid in pidtids: 45814d67073SMichał Górny self.test_sequence.add_log_lines( 459*2238dcc3SJonas Devlieghere [ 460*2238dcc3SJonas Devlieghere "read packet: $Hcp{}.{}#00".format(*pidtid), 46114d67073SMichał Górny "send packet: $OK#00", 46214d67073SMichał Górny "read packet: $c#00", 463*2238dcc3SJonas Devlieghere { 464*2238dcc3SJonas Devlieghere "direction": "send", 465251165b2SMichał Górny "regex": self.stop_regex.format(*pidtid), 46614d67073SMichał Górny }, 467*2238dcc3SJonas Devlieghere ], 468*2238dcc3SJonas Devlieghere True, 469*2238dcc3SJonas Devlieghere ) 47014d67073SMichał Górny 47114d67073SMichał Górny self.add_threadinfo_collection_packets() 47214d67073SMichał Górny ret = self.expect_gdbremote_sequence() 47314d67073SMichał Górny self.reset_test_sequence() 47414d67073SMichał Górny 47514d67073SMichał Górny pidtids = set(self.parse_threadinfo_packets(ret)) 47614d67073SMichał Górny self.assertEqual(len(pidtids), 4) 47714d67073SMichał Górny # first, save register values from all the threads 47814d67073SMichał Górny thread_regs = {} 47914d67073SMichał Górny for pidtid in pidtids: 48014d67073SMichał Górny for regno in range(256): 48114d67073SMichał Górny self.test_sequence.add_log_lines( 482*2238dcc3SJonas Devlieghere [ 483*2238dcc3SJonas Devlieghere "read packet: $Hgp{:x}.{:x}#00".format(*pidtid), 48414d67073SMichał Górny "send packet: $OK#00", 48514d67073SMichał Górny "read packet: $p{:x}#00".format(regno), 486*2238dcc3SJonas Devlieghere { 487*2238dcc3SJonas Devlieghere "direction": "send", 48814d67073SMichał Górny "regex": r"^[$](.+)#.*$", 489*2238dcc3SJonas Devlieghere "capture": {1: "data"}, 490*2238dcc3SJonas Devlieghere }, 491*2238dcc3SJonas Devlieghere ], 492*2238dcc3SJonas Devlieghere True, 493*2238dcc3SJonas Devlieghere ) 49414d67073SMichał Górny ret = self.expect_gdbremote_sequence() 49514d67073SMichał Górny data = ret.get("data") 49614d67073SMichał Górny self.assertIsNotNone(data) 49714d67073SMichał Górny # ignore registers shorter than 32 bits (this also catches 49814d67073SMichał Górny # "Exx" errors) 49914d67073SMichał Górny if len(data) >= 8: 50014d67073SMichał Górny break 50114d67073SMichał Górny else: 50214d67073SMichał Górny self.skipTest("no usable register found") 50314d67073SMichał Górny thread_regs[pidtid] = (regno, data) 50414d67073SMichał Górny 50514d67073SMichał Górny vals = set(x[1] for x in thread_regs.values()) 50614d67073SMichał Górny # NB: cheap hack to make the loop below easier 50714d67073SMichał Górny new_val = next(iter(vals)) 50814d67073SMichał Górny 50914d67073SMichał Górny # then, start altering them and verify that we don't unexpectedly 51014d67073SMichał Górny # change the value from another thread 51114d67073SMichał Górny for pidtid in pidtids: 51214d67073SMichał Górny old_val = thread_regs[pidtid] 51314d67073SMichał Górny regno = old_val[0] 51414d67073SMichał Górny old_val_length = len(old_val[1]) 51514d67073SMichał Górny # generate a unique new_val 51614d67073SMichał Górny while new_val in vals: 517*2238dcc3SJonas Devlieghere new_val = "{{:0{}x}}".format(old_val_length).format( 518*2238dcc3SJonas Devlieghere random.getrandbits(old_val_length * 4) 519*2238dcc3SJonas Devlieghere ) 52014d67073SMichał Górny vals.add(new_val) 52114d67073SMichał Górny 52214d67073SMichał Górny self.test_sequence.add_log_lines( 523*2238dcc3SJonas Devlieghere [ 524*2238dcc3SJonas Devlieghere "read packet: $Hgp{:x}.{:x}#00".format(*pidtid), 52514d67073SMichał Górny "send packet: $OK#00", 52614d67073SMichał Górny "read packet: $p{:x}#00".format(regno), 527*2238dcc3SJonas Devlieghere { 528*2238dcc3SJonas Devlieghere "direction": "send", 52914d67073SMichał Górny "regex": r"^[$](.+)#.*$", 530*2238dcc3SJonas Devlieghere "capture": {1: "data"}, 531*2238dcc3SJonas Devlieghere }, 53214d67073SMichał Górny "read packet: $P{:x}={}#00".format(regno, new_val), 53314d67073SMichał Górny "send packet: $OK#00", 534*2238dcc3SJonas Devlieghere ], 535*2238dcc3SJonas Devlieghere True, 536*2238dcc3SJonas Devlieghere ) 53714d67073SMichał Górny ret = self.expect_gdbremote_sequence() 53814d67073SMichał Górny data = ret.get("data") 53914d67073SMichał Górny self.assertIsNotNone(data) 54014d67073SMichał Górny self.assertEqual(data, old_val[1]) 54114d67073SMichał Górny thread_regs[pidtid] = (regno, new_val) 54214d67073SMichał Górny 54314d67073SMichał Górny # finally, verify that new values took effect 54414d67073SMichał Górny for pidtid in pidtids: 54514d67073SMichał Górny old_val = thread_regs[pidtid] 54614d67073SMichał Górny self.test_sequence.add_log_lines( 547*2238dcc3SJonas Devlieghere [ 548*2238dcc3SJonas Devlieghere "read packet: $Hgp{:x}.{:x}#00".format(*pidtid), 54914d67073SMichał Górny "send packet: $OK#00", 55014d67073SMichał Górny "read packet: $p{:x}#00".format(old_val[0]), 551*2238dcc3SJonas Devlieghere { 552*2238dcc3SJonas Devlieghere "direction": "send", 55314d67073SMichał Górny "regex": r"^[$](.+)#.*$", 554*2238dcc3SJonas Devlieghere "capture": {1: "data"}, 555*2238dcc3SJonas Devlieghere }, 556*2238dcc3SJonas Devlieghere ], 557*2238dcc3SJonas Devlieghere True, 558*2238dcc3SJonas Devlieghere ) 55914d67073SMichał Górny ret = self.expect_gdbremote_sequence() 56014d67073SMichał Górny data = ret.get("data") 56114d67073SMichał Górny self.assertIsNotNone(data) 56214d67073SMichał Górny self.assertEqual(data, old_val[1]) 563630da0e3SMichał Górny 564630da0e3SMichał Górny @add_test_categories(["fork"]) 565630da0e3SMichał Górny def test_qC(self): 566*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 567*2238dcc3SJonas Devlieghere ["fork", "thread:new", "stop"] 568*2238dcc3SJonas Devlieghere ) 569630da0e3SMichał Górny pidtids = [ 570c1829e0eSMichał Górny (parent_pid, parent_tid), 571c1829e0eSMichał Górny (child_pid, child_tid), 572630da0e3SMichał Górny ] 573630da0e3SMichał Górny 574630da0e3SMichał Górny for pidtid in pidtids: 575630da0e3SMichał Górny self.test_sequence.add_log_lines( 576*2238dcc3SJonas Devlieghere [ 577*2238dcc3SJonas Devlieghere "read packet: $Hcp{}.{}#00".format(*pidtid), 578630da0e3SMichał Górny "send packet: $OK#00", 579630da0e3SMichał Górny "read packet: $c#00", 580*2238dcc3SJonas Devlieghere { 581*2238dcc3SJonas Devlieghere "direction": "send", 582251165b2SMichał Górny "regex": self.stop_regex.format(*pidtid), 583630da0e3SMichał Górny }, 584*2238dcc3SJonas Devlieghere ], 585*2238dcc3SJonas Devlieghere True, 586*2238dcc3SJonas Devlieghere ) 587630da0e3SMichał Górny 588630da0e3SMichał Górny self.add_threadinfo_collection_packets() 589630da0e3SMichał Górny ret = self.expect_gdbremote_sequence() 590630da0e3SMichał Górny self.reset_test_sequence() 591630da0e3SMichał Górny 592630da0e3SMichał Górny pidtids = set(self.parse_threadinfo_packets(ret)) 593630da0e3SMichał Górny self.assertEqual(len(pidtids), 4) 594630da0e3SMichał Górny for pidtid in pidtids: 595630da0e3SMichał Górny self.test_sequence.add_log_lines( 596*2238dcc3SJonas Devlieghere [ 597*2238dcc3SJonas Devlieghere "read packet: $Hgp{:x}.{:x}#00".format(*pidtid), 598630da0e3SMichał Górny "send packet: $OK#00", 599630da0e3SMichał Górny "read packet: $qC#00", 600630da0e3SMichał Górny "send packet: $QCp{:x}.{:x}#00".format(*pidtid), 601*2238dcc3SJonas Devlieghere ], 602*2238dcc3SJonas Devlieghere True, 603*2238dcc3SJonas Devlieghere ) 604630da0e3SMichał Górny self.expect_gdbremote_sequence() 605e827e518SMichał Górny 606e827e518SMichał Górny @add_test_categories(["fork"]) 607e827e518SMichał Górny def test_T(self): 608*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 609*2238dcc3SJonas Devlieghere ["fork", "thread:new", "stop"] 610*2238dcc3SJonas Devlieghere ) 611e827e518SMichał Górny pidtids = [ 612c1829e0eSMichał Górny (parent_pid, parent_tid), 613c1829e0eSMichał Górny (child_pid, child_tid), 614e827e518SMichał Górny ] 615e827e518SMichał Górny 616e827e518SMichał Górny for pidtid in pidtids: 617e827e518SMichał Górny self.test_sequence.add_log_lines( 618*2238dcc3SJonas Devlieghere [ 619*2238dcc3SJonas Devlieghere "read packet: $Hcp{}.{}#00".format(*pidtid), 620e827e518SMichał Górny "send packet: $OK#00", 621e827e518SMichał Górny "read packet: $c#00", 622*2238dcc3SJonas Devlieghere { 623*2238dcc3SJonas Devlieghere "direction": "send", 624251165b2SMichał Górny "regex": self.stop_regex.format(*pidtid), 625e827e518SMichał Górny }, 626*2238dcc3SJonas Devlieghere ], 627*2238dcc3SJonas Devlieghere True, 628*2238dcc3SJonas Devlieghere ) 629e827e518SMichał Górny 630e827e518SMichał Górny self.add_threadinfo_collection_packets() 631e827e518SMichał Górny ret = self.expect_gdbremote_sequence() 632e827e518SMichał Górny self.reset_test_sequence() 633e827e518SMichał Górny 634e827e518SMichał Górny pidtids = set(self.parse_threadinfo_packets(ret)) 635e827e518SMichał Górny self.assertEqual(len(pidtids), 4) 636e827e518SMichał Górny max_pid = max(pid for pid, tid in pidtids) 637e827e518SMichał Górny max_tid = max(tid for pid, tid in pidtids) 638e827e518SMichał Górny bad_pidtids = ( 639e827e518SMichał Górny (max_pid, max_tid + 1, "E02"), 640e827e518SMichał Górny (max_pid + 1, max_tid, "E01"), 641e827e518SMichał Górny (max_pid + 1, max_tid + 1, "E01"), 642e827e518SMichał Górny ) 643e827e518SMichał Górny 644e827e518SMichał Górny for pidtid in pidtids: 645e827e518SMichał Górny self.test_sequence.add_log_lines( 646e827e518SMichał Górny [ 647e827e518SMichał Górny # test explicit PID+TID 648e827e518SMichał Górny "read packet: $Tp{:x}.{:x}#00".format(*pidtid), 649e827e518SMichał Górny "send packet: $OK#00", 650e827e518SMichał Górny # test implicit PID via Hg 651e827e518SMichał Górny "read packet: $Hgp{:x}.{:x}#00".format(*pidtid), 652e827e518SMichał Górny "send packet: $OK#00", 653e827e518SMichał Górny "read packet: $T{:x}#00".format(max_tid + 1), 654e827e518SMichał Górny "send packet: $E02#00", 655e827e518SMichał Górny "read packet: $T{:x}#00".format(pidtid[1]), 656e827e518SMichał Górny "send packet: $OK#00", 657*2238dcc3SJonas Devlieghere ], 658*2238dcc3SJonas Devlieghere True, 659*2238dcc3SJonas Devlieghere ) 660e827e518SMichał Górny for pid, tid, expected in bad_pidtids: 661e827e518SMichał Górny self.test_sequence.add_log_lines( 662*2238dcc3SJonas Devlieghere [ 663*2238dcc3SJonas Devlieghere "read packet: $Tp{:x}.{:x}#00".format(pid, tid), 664e827e518SMichał Górny "send packet: ${}#00".format(expected), 665*2238dcc3SJonas Devlieghere ], 666*2238dcc3SJonas Devlieghere True, 667*2238dcc3SJonas Devlieghere ) 668e827e518SMichał Górny self.expect_gdbremote_sequence() 669