Skip to content

Commit 7fc12da

Browse files
committed
[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
1 parent 9c04851 commit 7fc12da

File tree

3 files changed

+322
-313
lines changed

3 files changed

+322
-313
lines changed
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
import gdbremote_testcase
2+
3+
4+
class GdbRemoteForkTestBase(gdbremote_testcase.GdbRemoteTestCaseBase):
5+
fork_regex = ("[$]T05thread:p([0-9a-f]+)[.]([0-9a-f]+);.*"
6+
"{}:p([0-9a-f]+)[.]([0-9a-f]+).*")
7+
fork_regex_nonstop = ("%Stop:T05thread:p([0-9a-f]+)[.]([0-9a-f]+);.*"
8+
"{}:p([0-9a-f]+)[.]([0-9a-f]+).*")
9+
fork_capture = {1: "parent_pid", 2: "parent_tid",
10+
3: "child_pid", 4: "child_tid"}
11+
12+
def start_fork_test(self, args, variant="fork", nonstop=False):
13+
self.build()
14+
self.prep_debug_monitor_and_inferior(inferior_args=args)
15+
self.add_qSupported_packets(["multiprocess+",
16+
"{}-events+".format(variant)])
17+
ret = self.expect_gdbremote_sequence()
18+
self.assertIn("{}-events+".format(variant), ret["qSupported_response"])
19+
self.reset_test_sequence()
20+
21+
# continue and expect fork
22+
if nonstop:
23+
self.test_sequence.add_log_lines([
24+
"read packet: $QNonStop:1#00",
25+
"send packet: $OK#00",
26+
"read packet: $c#00",
27+
"send packet: $OK#00",
28+
{"direction": "send",
29+
"regex": self.fork_regex_nonstop.format(variant),
30+
"capture": self.fork_capture},
31+
"read packet: $vStopped#00",
32+
"send packet: $OK#00",
33+
], True)
34+
else:
35+
self.test_sequence.add_log_lines([
36+
"read packet: $c#00",
37+
{"direction": "send", "regex": self.fork_regex.format(variant),
38+
"capture": self.fork_capture},
39+
], True)
40+
ret = self.expect_gdbremote_sequence()
41+
self.reset_test_sequence()
42+
43+
return tuple(ret[x] for x in ("parent_pid", "parent_tid",
44+
"child_pid", "child_tid"))
45+
46+
def fork_and_detach_test(self, variant, nonstop=False):
47+
parent_pid, parent_tid, child_pid, child_tid = (
48+
self.start_fork_test([variant], variant, nonstop=nonstop))
49+
50+
# detach the forked child
51+
self.test_sequence.add_log_lines([
52+
"read packet: $D;{}#00".format(child_pid),
53+
"send packet: $OK#00",
54+
# verify that the current process is correct
55+
"read packet: $qC#00",
56+
"send packet: $QCp{}.{}#00".format(parent_pid, parent_tid),
57+
# verify that the correct processes are detached/available
58+
"read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
59+
"send packet: $Eff#00",
60+
"read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
61+
"send packet: $OK#00",
62+
], True)
63+
self.expect_gdbremote_sequence()
64+
self.reset_test_sequence()
65+
return parent_pid, parent_tid
66+
67+
def fork_and_follow_test(self, variant, nonstop=False):
68+
parent_pid, parent_tid, child_pid, child_tid = (
69+
self.start_fork_test([variant], variant, nonstop=nonstop))
70+
71+
# switch to the forked child
72+
self.test_sequence.add_log_lines([
73+
"read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
74+
"send packet: $OK#00",
75+
"read packet: $Hcp{}.{}#00".format(child_pid, child_tid),
76+
"send packet: $OK#00",
77+
# detach the parent
78+
"read packet: $D;{}#00".format(parent_pid),
79+
"send packet: $OK#00",
80+
# verify that the correct processes are detached/available
81+
"read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
82+
"send packet: $Eff#00",
83+
"read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
84+
"send packet: $OK#00",
85+
# then resume the child
86+
"read packet: $c#00",
87+
], True)
88+
89+
if nonstop:
90+
self.test_sequence.add_log_lines([
91+
"send packet: $OK#00",
92+
"send packet: %Stop:W00;process:{}#00".format(child_pid),
93+
"read packet: $vStopped#00",
94+
"send packet: $OK#00",
95+
], True)
96+
else:
97+
self.test_sequence.add_log_lines([
98+
"send packet: $W00;process:{}#00".format(child_pid),
99+
], True)
100+
self.expect_gdbremote_sequence()
101+
102+
def detach_all_test(self, nonstop=False):
103+
parent_pid, parent_tid, child_pid, child_tid = (
104+
self.start_fork_test(["fork"], nonstop=nonstop))
105+
106+
self.test_sequence.add_log_lines([
107+
# double-check our PIDs
108+
"read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
109+
"send packet: $OK#00",
110+
"read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
111+
"send packet: $OK#00",
112+
# detach all processes
113+
"read packet: $D#00",
114+
"send packet: $OK#00",
115+
# verify that both PIDs are invalid now
116+
"read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
117+
"send packet: $Eff#00",
118+
"read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
119+
"send packet: $Eff#00",
120+
], True)
121+
self.expect_gdbremote_sequence()
122+
123+
def vkill_test(self, kill_parent=False, kill_child=False, nonstop=False):
124+
assert kill_parent or kill_child
125+
parent_pid, parent_tid, child_pid, child_tid = (
126+
self.start_fork_test(["fork"], nonstop=nonstop))
127+
128+
if kill_parent:
129+
self.test_sequence.add_log_lines([
130+
# kill the process
131+
"read packet: $vKill;{}#00".format(parent_pid),
132+
"send packet: $OK#00",
133+
], True)
134+
if kill_child:
135+
self.test_sequence.add_log_lines([
136+
# kill the process
137+
"read packet: $vKill;{}#00".format(child_pid),
138+
"send packet: $OK#00",
139+
], True)
140+
self.test_sequence.add_log_lines([
141+
# check child PID/TID
142+
"read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
143+
"send packet: ${}#00".format("Eff" if kill_child else "OK"),
144+
# check parent PID/TID
145+
"read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
146+
"send packet: ${}#00".format("Eff" if kill_parent else "OK"),
147+
], True)
148+
self.expect_gdbremote_sequence()
149+
150+
def resume_one_test(self, run_order, use_vCont=False, nonstop=False):
151+
parent_pid, parent_tid, child_pid, child_tid = (
152+
self.start_fork_test(["fork", "trap"], nonstop=nonstop))
153+
154+
parent_expect = [
155+
"T05thread:p{}.{};.*".format(parent_pid, parent_tid),
156+
"W00;process:{}#.*".format(parent_pid),
157+
]
158+
child_expect = [
159+
"T05thread:p{}.{};.*".format(child_pid, child_tid),
160+
"W00;process:{}#.*".format(child_pid),
161+
]
162+
163+
for x in run_order:
164+
if x == "parent":
165+
pidtid = (parent_pid, parent_tid)
166+
expect = parent_expect.pop(0)
167+
elif x == "child":
168+
pidtid = (child_pid, child_tid)
169+
expect = child_expect.pop(0)
170+
else:
171+
assert False, "unexpected x={}".format(x)
172+
173+
if use_vCont:
174+
self.test_sequence.add_log_lines([
175+
# continue the selected process
176+
"read packet: $vCont;c:p{}.{}#00".format(*pidtid),
177+
], True)
178+
else:
179+
self.test_sequence.add_log_lines([
180+
# continue the selected process
181+
"read packet: $Hcp{}.{}#00".format(*pidtid),
182+
"send packet: $OK#00",
183+
"read packet: $c#00",
184+
], True)
185+
if nonstop:
186+
self.test_sequence.add_log_lines([
187+
"send packet: $OK#00",
188+
{"direction": "send", "regex": "%Stop:" + expect},
189+
"read packet: $vStopped#00",
190+
"send packet: $OK#00",
191+
], True)
192+
else:
193+
self.test_sequence.add_log_lines([
194+
{"direction": "send", "regex": "[$]" + expect},
195+
], True)
196+
# if at least one process remained, check both PIDs
197+
if parent_expect or child_expect:
198+
self.test_sequence.add_log_lines([
199+
"read packet: $Hgp{}.{}#00".format(parent_pid, parent_tid),
200+
"send packet: ${}#00".format("OK" if parent_expect else "Eff"),
201+
"read packet: $Hgp{}.{}#00".format(child_pid, child_tid),
202+
"send packet: ${}#00".format("OK" if child_expect else "Eff"),
203+
], True)
204+
self.expect_gdbremote_sequence()

0 commit comments

Comments
 (0)