Skip to content

Commit d1deaed

Browse files
authored
[lldb] Split some lldb-server tests to avoid timeout (llvm#129614)
Split test cases out of TestLldbGdbServer.py and TestGdbRemoteFork.py into separate files to avoid hitting the 600s timeout limit. The inferior used by these tests (main.cpp) takes approximately 20s to compile with a Debug build of clang, causing timeouts when a single test file contains many tests. By grouping similar tests into separate files, we can prevent timeouts and improve overall test efficiency.
1 parent 8b9031f commit d1deaed

File tree

8 files changed

+517
-480
lines changed

8 files changed

+517
-480
lines changed

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

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -190,52 +190,6 @@ def test_vkill_parent(self):
190190
def test_vkill_both(self):
191191
self.vkill_test(kill_parent=True, kill_child=True)
192192

193-
@add_test_categories(["fork"])
194-
def test_c_parent(self):
195-
self.resume_one_test(run_order=["parent", "parent"])
196-
197-
@add_test_categories(["fork"])
198-
def test_c_child(self):
199-
self.resume_one_test(run_order=["child", "child"])
200-
201-
@add_test_categories(["fork"])
202-
def test_c_parent_then_child(self):
203-
self.resume_one_test(run_order=["parent", "parent", "child", "child"])
204-
205-
@add_test_categories(["fork"])
206-
def test_c_child_then_parent(self):
207-
self.resume_one_test(run_order=["child", "child", "parent", "parent"])
208-
209-
@add_test_categories(["fork"])
210-
def test_c_interspersed(self):
211-
self.resume_one_test(run_order=["parent", "child", "parent", "child"])
212-
213-
@add_test_categories(["fork"])
214-
def test_vCont_parent(self):
215-
self.resume_one_test(run_order=["parent", "parent"], use_vCont=True)
216-
217-
@add_test_categories(["fork"])
218-
def test_vCont_child(self):
219-
self.resume_one_test(run_order=["child", "child"], use_vCont=True)
220-
221-
@add_test_categories(["fork"])
222-
def test_vCont_parent_then_child(self):
223-
self.resume_one_test(
224-
run_order=["parent", "parent", "child", "child"], use_vCont=True
225-
)
226-
227-
@add_test_categories(["fork"])
228-
def test_vCont_child_then_parent(self):
229-
self.resume_one_test(
230-
run_order=["child", "child", "parent", "parent"], use_vCont=True
231-
)
232-
233-
@add_test_categories(["fork"])
234-
def test_vCont_interspersed(self):
235-
self.resume_one_test(
236-
run_order=["parent", "child", "parent", "child"], use_vCont=True
237-
)
238-
239193
@add_test_categories(["fork"])
240194
def test_vCont_two_processes(self):
241195
parent_pid, parent_tid, child_pid, child_tid = self.start_fork_test(
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from lldbsuite.test.decorators import *
2+
from lldbsuite.test.lldbtest import *
3+
4+
from fork_testbase import GdbRemoteForkTestBase
5+
6+
7+
class TestGdbRemoteForkResume(GdbRemoteForkTestBase):
8+
def setUp(self):
9+
GdbRemoteForkTestBase.setUp(self)
10+
if self.getPlatform() == "linux" and self.getArchitecture() in [
11+
"arm",
12+
"aarch64",
13+
]:
14+
self.skipTest("Unsupported for Arm/AArch64 Linux")
15+
16+
@add_test_categories(["fork"])
17+
def test_c_parent(self):
18+
self.resume_one_test(run_order=["parent", "parent"])
19+
20+
@add_test_categories(["fork"])
21+
def test_c_child(self):
22+
self.resume_one_test(run_order=["child", "child"])
23+
24+
@add_test_categories(["fork"])
25+
def test_c_parent_then_child(self):
26+
self.resume_one_test(run_order=["parent", "parent", "child", "child"])
27+
28+
@add_test_categories(["fork"])
29+
def test_c_child_then_parent(self):
30+
self.resume_one_test(run_order=["child", "child", "parent", "parent"])
31+
32+
@add_test_categories(["fork"])
33+
def test_c_interspersed(self):
34+
self.resume_one_test(run_order=["parent", "child", "parent", "child"])
35+
36+
@add_test_categories(["fork"])
37+
def test_vCont_parent(self):
38+
self.resume_one_test(run_order=["parent", "parent"], use_vCont=True)
39+
40+
@add_test_categories(["fork"])
41+
def test_vCont_child(self):
42+
self.resume_one_test(run_order=["child", "child"], use_vCont=True)
43+
44+
@add_test_categories(["fork"])
45+
def test_vCont_parent_then_child(self):
46+
self.resume_one_test(
47+
run_order=["parent", "parent", "child", "child"], use_vCont=True
48+
)
49+
50+
@add_test_categories(["fork"])
51+
def test_vCont_child_then_parent(self):
52+
self.resume_one_test(
53+
run_order=["child", "child", "parent", "parent"], use_vCont=True
54+
)
55+
56+
@add_test_categories(["fork"])
57+
def test_vCont_interspersed(self):
58+
self.resume_one_test(
59+
run_order=["parent", "child", "parent", "child"], use_vCont=True
60+
)
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
import gdbremote_testcase
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test.lldbdwarf import *
5+
6+
7+
class TestGdbRemote_qMemoryRegion(gdbremote_testcase.GdbRemoteTestCaseBase):
8+
def test_qMemoryRegionInfo_is_supported(self):
9+
self.build()
10+
self.set_inferior_startup_launch()
11+
# Start up the inferior.
12+
procs = self.prep_debug_monitor_and_inferior()
13+
14+
# Ask if it supports $qMemoryRegionInfo.
15+
self.test_sequence.add_log_lines(
16+
["read packet: $qMemoryRegionInfo#00", "send packet: $OK#00"], True
17+
)
18+
self.expect_gdbremote_sequence()
19+
20+
@skipIfWindows # No pty support to test any inferior output
21+
def test_qMemoryRegionInfo_reports_code_address_as_executable(self):
22+
self.build()
23+
self.set_inferior_startup_launch()
24+
25+
# Start up the inferior.
26+
procs = self.prep_debug_monitor_and_inferior(
27+
inferior_args=["get-code-address-hex:hello", "sleep:5"]
28+
)
29+
30+
# Run the process
31+
self.test_sequence.add_log_lines(
32+
[
33+
# Start running after initial stop.
34+
"read packet: $c#63",
35+
# Match output line that prints the memory address of the message buffer within the inferior.
36+
# Note we require launch-only testing so we can get inferior otuput.
37+
{
38+
"type": "output_match",
39+
"regex": self.maybe_strict_output_regex(
40+
r"code address: 0x([0-9a-fA-F]+)\r\n"
41+
),
42+
"capture": {1: "code_address"},
43+
},
44+
# Now stop the inferior.
45+
"read packet: {}".format(chr(3)),
46+
# And wait for the stop notification.
47+
{
48+
"direction": "send",
49+
"regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
50+
"capture": {1: "stop_signo", 2: "stop_thread_id"},
51+
},
52+
],
53+
True,
54+
)
55+
56+
# Run the packet stream.
57+
context = self.expect_gdbremote_sequence()
58+
self.assertIsNotNone(context)
59+
60+
# Grab the code address.
61+
self.assertIsNotNone(context.get("code_address"))
62+
code_address = int(context.get("code_address"), 16)
63+
64+
# Grab memory region info from the inferior.
65+
self.reset_test_sequence()
66+
self.add_query_memory_region_packets(code_address)
67+
68+
# Run the packet stream.
69+
context = self.expect_gdbremote_sequence()
70+
self.assertIsNotNone(context)
71+
mem_region_dict = self.parse_memory_region_packet(context)
72+
73+
# Ensure there are no errors reported.
74+
self.assertNotIn("error", mem_region_dict)
75+
76+
# Ensure code address is readable and executable.
77+
self.assertIn("permissions", mem_region_dict)
78+
self.assertIn("r", mem_region_dict["permissions"])
79+
self.assertIn("x", mem_region_dict["permissions"])
80+
81+
# Ensure the start address and size encompass the address we queried.
82+
self.assert_address_within_memory_region(code_address, mem_region_dict)
83+
84+
@skipIfWindows # No pty support to test any inferior output
85+
def test_qMemoryRegionInfo_reports_stack_address_as_rw(self):
86+
self.build()
87+
self.set_inferior_startup_launch()
88+
89+
# Start up the inferior.
90+
procs = self.prep_debug_monitor_and_inferior(
91+
inferior_args=["get-stack-address-hex:", "sleep:5"]
92+
)
93+
94+
# Run the process
95+
self.test_sequence.add_log_lines(
96+
[
97+
# Start running after initial stop.
98+
"read packet: $c#63",
99+
# Match output line that prints the memory address of the message buffer within the inferior.
100+
# Note we require launch-only testing so we can get inferior otuput.
101+
{
102+
"type": "output_match",
103+
"regex": self.maybe_strict_output_regex(
104+
r"stack address: 0x([0-9a-fA-F]+)\r\n"
105+
),
106+
"capture": {1: "stack_address"},
107+
},
108+
# Now stop the inferior.
109+
"read packet: {}".format(chr(3)),
110+
# And wait for the stop notification.
111+
{
112+
"direction": "send",
113+
"regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
114+
"capture": {1: "stop_signo", 2: "stop_thread_id"},
115+
},
116+
],
117+
True,
118+
)
119+
120+
# Run the packet stream.
121+
context = self.expect_gdbremote_sequence()
122+
self.assertIsNotNone(context)
123+
124+
# Grab the address.
125+
self.assertIsNotNone(context.get("stack_address"))
126+
stack_address = int(context.get("stack_address"), 16)
127+
128+
# Grab memory region info from the inferior.
129+
self.reset_test_sequence()
130+
self.add_query_memory_region_packets(stack_address)
131+
132+
# Run the packet stream.
133+
context = self.expect_gdbremote_sequence()
134+
self.assertIsNotNone(context)
135+
mem_region_dict = self.parse_memory_region_packet(context)
136+
137+
# Ensure there are no errors reported.
138+
self.assertNotIn("error", mem_region_dict)
139+
140+
# Ensure address is readable and executable.
141+
self.assertIn("permissions", mem_region_dict)
142+
self.assertIn("r", mem_region_dict["permissions"])
143+
self.assertIn("w", mem_region_dict["permissions"])
144+
145+
# Ensure the start address and size encompass the address we queried.
146+
self.assert_address_within_memory_region(stack_address, mem_region_dict)
147+
148+
@skipIfWindows # No pty support to test any inferior output
149+
def test_qMemoryRegionInfo_reports_heap_address_as_rw(self):
150+
self.build()
151+
self.set_inferior_startup_launch()
152+
153+
# Start up the inferior.
154+
procs = self.prep_debug_monitor_and_inferior(
155+
inferior_args=["get-heap-address-hex:", "sleep:5"]
156+
)
157+
158+
# Run the process
159+
self.test_sequence.add_log_lines(
160+
[
161+
# Start running after initial stop.
162+
"read packet: $c#63",
163+
# Match output line that prints the memory address of the message buffer within the inferior.
164+
# Note we require launch-only testing so we can get inferior otuput.
165+
{
166+
"type": "output_match",
167+
"regex": self.maybe_strict_output_regex(
168+
r"heap address: 0x([0-9a-fA-F]+)\r\n"
169+
),
170+
"capture": {1: "heap_address"},
171+
},
172+
# Now stop the inferior.
173+
"read packet: {}".format(chr(3)),
174+
# And wait for the stop notification.
175+
{
176+
"direction": "send",
177+
"regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
178+
"capture": {1: "stop_signo", 2: "stop_thread_id"},
179+
},
180+
],
181+
True,
182+
)
183+
184+
# Run the packet stream.
185+
context = self.expect_gdbremote_sequence()
186+
self.assertIsNotNone(context)
187+
188+
# Grab the address.
189+
self.assertIsNotNone(context.get("heap_address"))
190+
heap_address = int(context.get("heap_address"), 16)
191+
192+
# Grab memory region info from the inferior.
193+
self.reset_test_sequence()
194+
self.add_query_memory_region_packets(heap_address)
195+
196+
# Run the packet stream.
197+
context = self.expect_gdbremote_sequence()
198+
self.assertIsNotNone(context)
199+
mem_region_dict = self.parse_memory_region_packet(context)
200+
201+
# Ensure there are no errors reported.
202+
self.assertNotIn("error", mem_region_dict)
203+
204+
# Ensure address is readable and executable.
205+
self.assertIn("permissions", mem_region_dict)
206+
self.assertIn("r", mem_region_dict["permissions"])
207+
self.assertIn("w", mem_region_dict["permissions"])
208+
209+
# Ensure the start address and size encompass the address we queried.
210+
self.assert_address_within_memory_region(heap_address, mem_region_dict)

0 commit comments

Comments
 (0)