brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.8 KiB · 4d3dee8 Raw
266 lines · python
1import gdbremote_testcase2 3 4class GdbRemoteForkTestBase(gdbremote_testcase.GdbRemoteTestCaseBase):5    fork_regex = (6        "[$]T[0-9a-fA-F]{{2}}thread:p([0-9a-f]+)[.]([0-9a-f]+);.*"7        "{}:p([0-9a-f]+)[.]([0-9a-f]+).*"8    )9    fork_regex_nonstop = (10        "%Stop:T[0-9a-fA-F]{{2}}"11        "thread:p([0-9a-f]+)[.]([0-9a-f]+);.*"12        "{}:p([0-9a-f]+)[.]([0-9a-f]+).*"13    )14    fork_capture = {1: "parent_pid", 2: "parent_tid", 3: "child_pid", 4: "child_tid"}15    stop_regex_base = "T[0-9a-fA-F]{{2}}thread:p{}.{};.*reason:signal.*"16    stop_regex = "^[$]" + stop_regex_base17 18    def start_fork_test(self, args, variant="fork", nonstop=False):19        self.build()20        self.prep_debug_monitor_and_inferior(inferior_args=args)21        self.add_qSupported_packets(["multiprocess+", "{}-events+".format(variant)])22        ret = self.expect_gdbremote_sequence()23        self.assertIn("{}-events+".format(variant), ret["qSupported_response"])24        self.reset_test_sequence()25 26        # continue and expect fork27        if nonstop:28            self.test_sequence.add_log_lines(29                [30                    "read packet: $QNonStop:1#00",31                    "send packet: $OK#00",32                    "read packet: $c#00",33                    "send packet: $OK#00",34                    {35                        "direction": "send",36                        "regex": self.fork_regex_nonstop.format(variant),37                        "capture": self.fork_capture,38                    },39                    "read packet: $vStopped#00",40                    "send packet: $OK#00",41                ],42                True,43            )44        else:45            self.test_sequence.add_log_lines(46                [47                    "read packet: $c#00",48                    {49                        "direction": "send",50                        "regex": self.fork_regex.format(variant),51                        "capture": self.fork_capture,52                    },53                ],54                True,55            )56        ret = self.expect_gdbremote_sequence()57        self.reset_test_sequence()58 59        return tuple(60            ret[x] for x in ("parent_pid", "parent_tid", "child_pid", "child_tid")61        )62 63    def fork_and_detach_test(self, variant, nonstop=False):64        parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test(65            [variant], variant, nonstop=nonstop66        )67 68        # detach the forked child69        self.test_sequence.add_log_lines(70            [71                "read packet: $D;{}#00".format(child_pid),72                "send packet: $OK#00",73                # verify that the current process is correct74                "read packet: $qC#00",75                "send packet: $QCp{}.{}#00".format(parent_pid, parent_tid),76                # verify that the correct processes are detached/available77                "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),78                "send packet: $Eff#00",79                "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),80                "send packet: $OK#00",81            ],82            True,83        )84        self.expect_gdbremote_sequence()85        self.reset_test_sequence()86        return parent_pid, parent_tid87 88    def fork_and_follow_test(self, variant, nonstop=False):89        parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test(90            [variant], variant, nonstop=nonstop91        )92 93        # switch to the forked child94        self.test_sequence.add_log_lines(95            [96                "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),97                "send packet: $OK#00",98                "read packet: $Hcp{}.{}#00".format(child_pid, child_tid),99                "send packet: $OK#00",100                # detach the parent101                "read packet: $D;{}#00".format(parent_pid),102                "send packet: $OK#00",103                # verify that the correct processes are detached/available104                "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),105                "send packet: $Eff#00",106                "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),107                "send packet: $OK#00",108                # then resume the child109                "read packet: $c#00",110            ],111            True,112        )113 114        if nonstop:115            self.test_sequence.add_log_lines(116                [117                    "send packet: $OK#00",118                    "send packet: %Stop:W00;process:{}#00".format(child_pid),119                    "read packet: $vStopped#00",120                    "send packet: $OK#00",121                ],122                True,123            )124        else:125            self.test_sequence.add_log_lines(126                [127                    "send packet: $W00;process:{}#00".format(child_pid),128                ],129                True,130            )131        self.expect_gdbremote_sequence()132 133    def detach_all_test(self, nonstop=False):134        parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test(135            ["fork"], nonstop=nonstop136        )137 138        self.test_sequence.add_log_lines(139            [140                # double-check our PIDs141                "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),142                "send packet: $OK#00",143                "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),144                "send packet: $OK#00",145                # detach all processes146                "read packet: $D#00",147                "send packet: $OK#00",148                # verify that both PIDs are invalid now149                "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),150                "send packet: $Eff#00",151                "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),152                "send packet: $Eff#00",153            ],154            True,155        )156        self.expect_gdbremote_sequence()157 158    def vkill_test(self, kill_parent=False, kill_child=False, nonstop=False):159        assert kill_parent or kill_child160        parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test(161            ["fork"], nonstop=nonstop162        )163 164        if kill_parent:165            self.test_sequence.add_log_lines(166                [167                    # kill the process168                    "read packet: $vKill;{}#00".format(parent_pid),169                    "send packet: $OK#00",170                ],171                True,172            )173        if kill_child:174            self.test_sequence.add_log_lines(175                [176                    # kill the process177                    "read packet: $vKill;{}#00".format(child_pid),178                    "send packet: $OK#00",179                ],180                True,181            )182        self.test_sequence.add_log_lines(183            [184                # check child PID/TID185                "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),186                "send packet: ${}#00".format("Eff" if kill_child else "OK"),187                # check parent PID/TID188                "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),189                "send packet: ${}#00".format("Eff" if kill_parent else "OK"),190            ],191            True,192        )193        self.expect_gdbremote_sequence()194 195    def resume_one_test(self, run_order, use_vCont=False, nonstop=False):196        parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test(197            ["fork", "stop"], nonstop=nonstop198        )199 200        parent_expect = [201            self.stop_regex_base.format(parent_pid, parent_tid),202            "W00;process:{}#.*".format(parent_pid),203        ]204        child_expect = [205            self.stop_regex_base.format(child_pid, child_tid),206            "W00;process:{}#.*".format(child_pid),207        ]208 209        for x in run_order:210            if x == "parent":211                pidtid = (parent_pid, parent_tid)212                expect = parent_expect.pop(0)213            elif x == "child":214                pidtid = (child_pid, child_tid)215                expect = child_expect.pop(0)216            else:217                assert False, "unexpected x={}".format(x)218 219            if use_vCont:220                self.test_sequence.add_log_lines(221                    [222                        # continue the selected process223                        "read packet: $vCont;c:p{}.{}#00".format(*pidtid),224                    ],225                    True,226                )227            else:228                self.test_sequence.add_log_lines(229                    [230                        # continue the selected process231                        "read packet: $Hcp{}.{}#00".format(*pidtid),232                        "send packet: $OK#00",233                        "read packet: $c#00",234                    ],235                    True,236                )237            if nonstop:238                self.test_sequence.add_log_lines(239                    [240                        "send packet: $OK#00",241                        {"direction": "send", "regex": "%Stop:" + expect},242                        "read packet: $vStopped#00",243                        "send packet: $OK#00",244                    ],245                    True,246                )247            else:248                self.test_sequence.add_log_lines(249                    [250                        {"direction": "send", "regex": "[$]" + expect},251                    ],252                    True,253                )254            # if at least one process remained, check both PIDs255            if parent_expect or child_expect:256                self.test_sequence.add_log_lines(257                    [258                        "read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),259                        "send packet: ${}#00".format("OK" if parent_expect else "Eff"),260                        "read packet: $Hgp{}.{}#00".format(child_pid, child_tid),261                        "send packet: ${}#00".format("OK" if child_expect else "Eff"),262                    ],263                    True,264                )265        self.expect_gdbremote_sequence()266