17fc12da8SMichał Górnyimport gdbremote_testcase 27fc12da8SMichał Górny 37fc12da8SMichał Górny 47fc12da8SMichał Górnyclass GdbRemoteForkTestBase(gdbremote_testcase.GdbRemoteTestCaseBase): 5*2238dcc3SJonas Devlieghere fork_regex = ( 6*2238dcc3SJonas Devlieghere "[$]T[0-9a-fA-F]{{2}}thread:p([0-9a-f]+)[.]([0-9a-f]+);.*" 7*2238dcc3SJonas Devlieghere "{}:p([0-9a-f]+)[.]([0-9a-f]+).*" 8*2238dcc3SJonas Devlieghere ) 9*2238dcc3SJonas Devlieghere fork_regex_nonstop = ( 10*2238dcc3SJonas Devlieghere "%Stop:T[0-9a-fA-F]{{2}}" 114a95861dSMichał Górny "thread:p([0-9a-f]+)[.]([0-9a-f]+);.*" 12*2238dcc3SJonas Devlieghere "{}:p([0-9a-f]+)[.]([0-9a-f]+).*" 13*2238dcc3SJonas Devlieghere ) 14*2238dcc3SJonas Devlieghere fork_capture = {1: "parent_pid", 2: "parent_tid", 3: "child_pid", 4: "child_tid"} 15251165b2SMichał Górny stop_regex_base = "T[0-9a-fA-F]{{2}}thread:p{}.{};.*reason:signal.*" 16251165b2SMichał Górny stop_regex = "^[$]" + stop_regex_base 177fc12da8SMichał Górny 187fc12da8SMichał Górny def start_fork_test(self, args, variant="fork", nonstop=False): 197fc12da8SMichał Górny self.build() 207fc12da8SMichał Górny self.prep_debug_monitor_and_inferior(inferior_args=args) 21*2238dcc3SJonas Devlieghere self.add_qSupported_packets(["multiprocess+", "{}-events+".format(variant)]) 227fc12da8SMichał Górny ret = self.expect_gdbremote_sequence() 237fc12da8SMichał Górny self.assertIn("{}-events+".format(variant), ret["qSupported_response"]) 247fc12da8SMichał Górny self.reset_test_sequence() 257fc12da8SMichał Górny 267fc12da8SMichał Górny # continue and expect fork 277fc12da8SMichał Górny if nonstop: 28*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 29*2238dcc3SJonas Devlieghere [ 307fc12da8SMichał Górny "read packet: $QNonStop:1#00", 317fc12da8SMichał Górny "send packet: $OK#00", 327fc12da8SMichał Górny "read packet: $c#00", 337fc12da8SMichał Górny "send packet: $OK#00", 34*2238dcc3SJonas Devlieghere { 35*2238dcc3SJonas Devlieghere "direction": "send", 367fc12da8SMichał Górny "regex": self.fork_regex_nonstop.format(variant), 37*2238dcc3SJonas Devlieghere "capture": self.fork_capture, 38*2238dcc3SJonas Devlieghere }, 397fc12da8SMichał Górny "read packet: $vStopped#00", 407fc12da8SMichał Górny "send packet: $OK#00", 41*2238dcc3SJonas Devlieghere ], 42*2238dcc3SJonas Devlieghere True, 43*2238dcc3SJonas Devlieghere ) 447fc12da8SMichał Górny else: 45*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 46*2238dcc3SJonas Devlieghere [ 477fc12da8SMichał Górny "read packet: $c#00", 48*2238dcc3SJonas Devlieghere { 49*2238dcc3SJonas Devlieghere "direction": "send", 50*2238dcc3SJonas Devlieghere "regex": self.fork_regex.format(variant), 51*2238dcc3SJonas Devlieghere "capture": self.fork_capture, 52*2238dcc3SJonas Devlieghere }, 53*2238dcc3SJonas Devlieghere ], 54*2238dcc3SJonas Devlieghere True, 55*2238dcc3SJonas Devlieghere ) 567fc12da8SMichał Górny ret = self.expect_gdbremote_sequence() 577fc12da8SMichał Górny self.reset_test_sequence() 587fc12da8SMichał Górny 59*2238dcc3SJonas Devlieghere return tuple( 60*2238dcc3SJonas Devlieghere ret[x] for x in ("parent_pid", "parent_tid", "child_pid", "child_tid") 61*2238dcc3SJonas Devlieghere ) 627fc12da8SMichał Górny 637fc12da8SMichał Górny def fork_and_detach_test(self, variant, nonstop=False): 64*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 65*2238dcc3SJonas Devlieghere [variant], variant, nonstop=nonstop 66*2238dcc3SJonas Devlieghere ) 677fc12da8SMichał Górny 687fc12da8SMichał Górny # detach the forked child 69*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 70*2238dcc3SJonas Devlieghere [ 717fc12da8SMichał Górny "read packet: $D;{}#00".format(child_pid), 727fc12da8SMichał Górny "send packet: $OK#00", 737fc12da8SMichał Górny # verify that the current process is correct 747fc12da8SMichał Górny "read packet: $qC#00", 757fc12da8SMichał Górny "send packet: $QCp{}.{}#00".format(parent_pid, parent_tid), 767fc12da8SMichał Górny # verify that the correct processes are detached/available 777fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(child_pid, child_tid), 787fc12da8SMichał Górny "send packet: $Eff#00", 797fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid), 807fc12da8SMichał Górny "send packet: $OK#00", 81*2238dcc3SJonas Devlieghere ], 82*2238dcc3SJonas Devlieghere True, 83*2238dcc3SJonas Devlieghere ) 847fc12da8SMichał Górny self.expect_gdbremote_sequence() 857fc12da8SMichał Górny self.reset_test_sequence() 867fc12da8SMichał Górny return parent_pid, parent_tid 877fc12da8SMichał Górny 887fc12da8SMichał Górny def fork_and_follow_test(self, variant, nonstop=False): 89*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 90*2238dcc3SJonas Devlieghere [variant], variant, nonstop=nonstop 91*2238dcc3SJonas Devlieghere ) 927fc12da8SMichał Górny 937fc12da8SMichał Górny # switch to the forked child 94*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 95*2238dcc3SJonas Devlieghere [ 967fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(child_pid, child_tid), 977fc12da8SMichał Górny "send packet: $OK#00", 987fc12da8SMichał Górny "read packet: $Hcp{}.{}#00".format(child_pid, child_tid), 997fc12da8SMichał Górny "send packet: $OK#00", 1007fc12da8SMichał Górny # detach the parent 1017fc12da8SMichał Górny "read packet: $D;{}#00".format(parent_pid), 1027fc12da8SMichał Górny "send packet: $OK#00", 1037fc12da8SMichał Górny # verify that the correct processes are detached/available 1047fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid), 1057fc12da8SMichał Górny "send packet: $Eff#00", 1067fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(child_pid, child_tid), 1077fc12da8SMichał Górny "send packet: $OK#00", 1087fc12da8SMichał Górny # then resume the child 1097fc12da8SMichał Górny "read packet: $c#00", 110*2238dcc3SJonas Devlieghere ], 111*2238dcc3SJonas Devlieghere True, 112*2238dcc3SJonas Devlieghere ) 1137fc12da8SMichał Górny 1147fc12da8SMichał Górny if nonstop: 115*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 116*2238dcc3SJonas Devlieghere [ 1177fc12da8SMichał Górny "send packet: $OK#00", 1187fc12da8SMichał Górny "send packet: %Stop:W00;process:{}#00".format(child_pid), 1197fc12da8SMichał Górny "read packet: $vStopped#00", 1207fc12da8SMichał Górny "send packet: $OK#00", 121*2238dcc3SJonas Devlieghere ], 122*2238dcc3SJonas Devlieghere True, 123*2238dcc3SJonas Devlieghere ) 1247fc12da8SMichał Górny else: 125*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 126*2238dcc3SJonas Devlieghere [ 1277fc12da8SMichał Górny "send packet: $W00;process:{}#00".format(child_pid), 128*2238dcc3SJonas Devlieghere ], 129*2238dcc3SJonas Devlieghere True, 130*2238dcc3SJonas Devlieghere ) 1317fc12da8SMichał Górny self.expect_gdbremote_sequence() 1327fc12da8SMichał Górny 1337fc12da8SMichał Górny def detach_all_test(self, nonstop=False): 134*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 135*2238dcc3SJonas Devlieghere ["fork"], nonstop=nonstop 136*2238dcc3SJonas Devlieghere ) 1377fc12da8SMichał Górny 138*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 139*2238dcc3SJonas Devlieghere [ 1407fc12da8SMichał Górny # double-check our PIDs 1417fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid), 1427fc12da8SMichał Górny "send packet: $OK#00", 1437fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(child_pid, child_tid), 1447fc12da8SMichał Górny "send packet: $OK#00", 1457fc12da8SMichał Górny # detach all processes 1467fc12da8SMichał Górny "read packet: $D#00", 1477fc12da8SMichał Górny "send packet: $OK#00", 1487fc12da8SMichał Górny # verify that both PIDs are invalid now 1497fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid), 1507fc12da8SMichał Górny "send packet: $Eff#00", 1517fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(child_pid, child_tid), 1527fc12da8SMichał Górny "send packet: $Eff#00", 153*2238dcc3SJonas Devlieghere ], 154*2238dcc3SJonas Devlieghere True, 155*2238dcc3SJonas Devlieghere ) 1567fc12da8SMichał Górny self.expect_gdbremote_sequence() 1577fc12da8SMichał Górny 1587fc12da8SMichał Górny def vkill_test(self, kill_parent=False, kill_child=False, nonstop=False): 1597fc12da8SMichał Górny assert kill_parent or kill_child 160*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 161*2238dcc3SJonas Devlieghere ["fork"], nonstop=nonstop 162*2238dcc3SJonas Devlieghere ) 1637fc12da8SMichał Górny 1647fc12da8SMichał Górny if kill_parent: 165*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 166*2238dcc3SJonas Devlieghere [ 1677fc12da8SMichał Górny # kill the process 1687fc12da8SMichał Górny "read packet: $vKill;{}#00".format(parent_pid), 1697fc12da8SMichał Górny "send packet: $OK#00", 170*2238dcc3SJonas Devlieghere ], 171*2238dcc3SJonas Devlieghere True, 172*2238dcc3SJonas Devlieghere ) 1737fc12da8SMichał Górny if kill_child: 174*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 175*2238dcc3SJonas Devlieghere [ 1767fc12da8SMichał Górny # kill the process 1777fc12da8SMichał Górny "read packet: $vKill;{}#00".format(child_pid), 1787fc12da8SMichał Górny "send packet: $OK#00", 179*2238dcc3SJonas Devlieghere ], 180*2238dcc3SJonas Devlieghere True, 181*2238dcc3SJonas Devlieghere ) 182*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 183*2238dcc3SJonas Devlieghere [ 1847fc12da8SMichał Górny # check child PID/TID 1857fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(child_pid, child_tid), 1867fc12da8SMichał Górny "send packet: ${}#00".format("Eff" if kill_child else "OK"), 1877fc12da8SMichał Górny # check parent PID/TID 1887fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid), 1897fc12da8SMichał Górny "send packet: ${}#00".format("Eff" if kill_parent else "OK"), 190*2238dcc3SJonas Devlieghere ], 191*2238dcc3SJonas Devlieghere True, 192*2238dcc3SJonas Devlieghere ) 1937fc12da8SMichał Górny self.expect_gdbremote_sequence() 1947fc12da8SMichał Górny 1957fc12da8SMichał Górny def resume_one_test(self, run_order, use_vCont=False, nonstop=False): 196*2238dcc3SJonas Devlieghere parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test( 197*2238dcc3SJonas Devlieghere ["fork", "stop"], nonstop=nonstop 198*2238dcc3SJonas Devlieghere ) 1997fc12da8SMichał Górny 2007fc12da8SMichał Górny parent_expect = [ 201251165b2SMichał Górny self.stop_regex_base.format(parent_pid, parent_tid), 2027fc12da8SMichał Górny "W00;process:{}#.*".format(parent_pid), 2037fc12da8SMichał Górny ] 2047fc12da8SMichał Górny child_expect = [ 205251165b2SMichał Górny self.stop_regex_base.format(child_pid, child_tid), 2067fc12da8SMichał Górny "W00;process:{}#.*".format(child_pid), 2077fc12da8SMichał Górny ] 2087fc12da8SMichał Górny 2097fc12da8SMichał Górny for x in run_order: 2107fc12da8SMichał Górny if x == "parent": 2117fc12da8SMichał Górny pidtid = (parent_pid, parent_tid) 2127fc12da8SMichał Górny expect = parent_expect.pop(0) 2137fc12da8SMichał Górny elif x == "child": 2147fc12da8SMichał Górny pidtid = (child_pid, child_tid) 2157fc12da8SMichał Górny expect = child_expect.pop(0) 2167fc12da8SMichał Górny else: 2177fc12da8SMichał Górny assert False, "unexpected x={}".format(x) 2187fc12da8SMichał Górny 2197fc12da8SMichał Górny if use_vCont: 220*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 221*2238dcc3SJonas Devlieghere [ 2227fc12da8SMichał Górny # continue the selected process 2237fc12da8SMichał Górny "read packet: $vCont;c:p{}.{}#00".format(*pidtid), 224*2238dcc3SJonas Devlieghere ], 225*2238dcc3SJonas Devlieghere True, 226*2238dcc3SJonas Devlieghere ) 2277fc12da8SMichał Górny else: 228*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 229*2238dcc3SJonas Devlieghere [ 2307fc12da8SMichał Górny # continue the selected process 2317fc12da8SMichał Górny "read packet: $Hcp{}.{}#00".format(*pidtid), 2327fc12da8SMichał Górny "send packet: $OK#00", 2337fc12da8SMichał Górny "read packet: $c#00", 234*2238dcc3SJonas Devlieghere ], 235*2238dcc3SJonas Devlieghere True, 236*2238dcc3SJonas Devlieghere ) 2377fc12da8SMichał Górny if nonstop: 238*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 239*2238dcc3SJonas Devlieghere [ 2407fc12da8SMichał Górny "send packet: $OK#00", 2417fc12da8SMichał Górny {"direction": "send", "regex": "%Stop:" + expect}, 2427fc12da8SMichał Górny "read packet: $vStopped#00", 2437fc12da8SMichał Górny "send packet: $OK#00", 244*2238dcc3SJonas Devlieghere ], 245*2238dcc3SJonas Devlieghere True, 246*2238dcc3SJonas Devlieghere ) 2477fc12da8SMichał Górny else: 248*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 249*2238dcc3SJonas Devlieghere [ 2507fc12da8SMichał Górny {"direction": "send", "regex": "[$]" + expect}, 251*2238dcc3SJonas Devlieghere ], 252*2238dcc3SJonas Devlieghere True, 253*2238dcc3SJonas Devlieghere ) 2547fc12da8SMichał Górny # if at least one process remained, check both PIDs 2557fc12da8SMichał Górny if parent_expect or child_expect: 256*2238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 257*2238dcc3SJonas Devlieghere [ 2587fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid), 2597fc12da8SMichał Górny "send packet: ${}#00".format("OK" if parent_expect else "Eff"), 2607fc12da8SMichał Górny "read packet: $Hgp{}.{}#00".format(child_pid, child_tid), 2617fc12da8SMichał Górny "send packet: ${}#00".format("OK" if child_expect else "Eff"), 262*2238dcc3SJonas Devlieghere ], 263*2238dcc3SJonas Devlieghere True, 264*2238dcc3SJonas Devlieghere ) 2657fc12da8SMichał Górny self.expect_gdbremote_sequence() 266