Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1d5884d

Browse files
authored
[lldb-dap] Fix the breakpoint events test. (#180518)
Previously the test was written in a way that may be flaky, fixed with the following changes. - The breakpoint are placed on functions and set during the configuration stage of the protocol. - Add the rpath to the test binary. - Check we also hit the breakpoint we set directly using lldb.
1 parent be711a0 commit 1d5884d

3 files changed

Lines changed: 94 additions & 63 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
DYLIB_NAME := unlikely_name
22
DYLIB_CXX_SOURCES := foo.cpp
33
CXX_SOURCES := main.cpp
4+
45
include Makefile.rules

lldb/test/API/tools/lldb-dap/breakpoint-events/TestDAP_breakpointEvents.py

Lines changed: 91 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,29 @@
1111

1212

1313
class TestDAP_breakpointEvents(lldbdap_testcase.DAPTestCaseBase):
14-
@skipUnlessDarwin
14+
@skipIfWindows
1515
def test_breakpoint_events(self):
1616
"""
17-
This test sets a breakpoint in a shared library and runs and stops
18-
at the entry point of a program. When we stop at the entry point,
19-
the shared library won't be loaded yet. At this point the
20-
breakpoint should set itself, but not be verified because no
21-
locations are resolved. We will then continue and expect to get a
22-
breakpoint event that informs us that the breakpoint in the shared
23-
library is "changed" and the correct line number should be
24-
supplied. We also set a breakpoint using a LLDB command using the
25-
"preRunCommands" when launching our program. Any breakpoints set via
26-
the command interpreter should not be have breakpoint events sent
27-
back to VS Code as the UI isn't able to add new breakpoints to
28-
their UI. Code has been added that tags breakpoints set from VS Code
17+
This test follows the following steps.
18+
- Sets a breakpoint in a shared library from the preCommands.
19+
- Runs and stops at the entry point of a program.
20+
- Sets two new breakpoints, one in the main executable and one in the shared library
21+
- Both breakpoint is set but only the the shared library breakpoint is not verified yet.
22+
- We will then continue and expect to get a breakpoint event that
23+
informs us the breakpoint in the shared library has "changed"
24+
and the correct line number should be supplied.
25+
- We also verify the breakpoint set via the command interpreter should not
26+
be have breakpoint events sent back to VS Code as the UI isn't able to
27+
add new breakpoints to their UI.
28+
29+
Code has been added that tags breakpoints set from VS Code
2930
DAP packets so we know the IDE knows about them. If VS Code is ever
3031
able to register breakpoints that aren't initially set in the GUI,
3132
then we will need to revise this.
3233
"""
33-
main_source_basename = "main.cpp"
34-
main_source_path = os.path.join(os.getcwd(), main_source_basename)
35-
foo_source_basename = "foo.cpp"
36-
foo_source_path = os.path.join(os.getcwd(), foo_source_basename)
37-
main_bp_line = line_number("main.cpp", "main breakpoint 1")
38-
foo_bp1_line = line_number("foo.cpp", "foo breakpoint 1")
39-
foo_bp2_line = line_number("foo.cpp", "foo breakpoint 2")
40-
41-
# Visual Studio Code Debug Adapters have no way to specify the file
42-
# without launching or attaching to a process, so we must start a
43-
# process in order to be able to set breakpoints.
34+
main_source_path = self.getSourcePath("main.cpp")
35+
main_bp_line = line_number(main_source_path, "main breakpoint 1")
36+
main_source = Source.build(path=main_source_path)
4437
program = self.getBuildArtifact("a.out")
4538

4639
# Set a breakpoint after creating the target by running a command line
@@ -51,54 +44,91 @@ def test_breakpoint_events(self):
5144
# registered and marked with a special keyword to ensure we deliver
5245
# breakpoint events for these breakpoints but not for ones that are not
5346
# set via the command interpreter.
54-
bp_command = "breakpoint set --file foo.cpp --line %u" % (foo_bp2_line)
55-
self.build_and_launch(program, preRunCommands=[bp_command])
56-
main_bp_id = 0
57-
foo_bp_id = 0
58-
# Set breakpoints and verify that they got set correctly
59-
dap_breakpoint_ids = []
60-
response = self.dap_server.request_setBreakpoints(
61-
Source.build(path=main_source_path), [main_bp_line]
47+
48+
shlib_env_key = self.platformContext.shlib_environment_var
49+
path_separator = self.platformContext.shlib_path_separator
50+
shlib_env_value = os.getenv(shlib_env_key)
51+
shlib_env_new_value = (
52+
self.getBuildDir()
53+
if shlib_env_value is None
54+
else (shlib_env_value + path_separator + self.getBuildDir())
6255
)
56+
57+
# Set preCommand breakpoint
58+
func_unique_function_name = "unique_function_name"
59+
bp_command = f"breakpoint set --name {func_unique_function_name}"
60+
launch_seq = self.build_and_launch(
61+
program,
62+
preRunCommands=[bp_command],
63+
env={shlib_env_key: shlib_env_new_value},
64+
)
65+
self.dap_server.wait_for_event(["initialized"])
66+
dap_breakpoint_ids = []
67+
68+
# We set the breakpoints after initialized event.
69+
# Set and verify new line breakpoint.
70+
response = self.dap_server.request_setBreakpoints(main_source, [main_bp_line])
6371
self.assertTrue(response["success"])
6472
breakpoints = response["body"]["breakpoints"]
65-
for breakpoint in breakpoints:
66-
main_bp_id = breakpoint["id"]
67-
dap_breakpoint_ids.append(main_bp_id)
68-
self.assertTrue(
69-
breakpoint["verified"], "expect main breakpoint to be verified"
70-
)
71-
72-
response = self.dap_server.request_setBreakpoints(
73-
Source.build(path=foo_source_path), [foo_bp1_line]
73+
self.assertEqual(len(breakpoints), 1, "expects only one line breakpoint")
74+
main_breakpoint = breakpoints[0]
75+
main_bp_id = main_breakpoint["id"]
76+
dap_breakpoint_ids.append(main_bp_id)
77+
self.assertTrue(
78+
main_breakpoint["verified"], "expects main breakpoint to be verified"
7479
)
80+
81+
# Set and verify new function breakpoint.
82+
func_foo = "foo"
83+
response = self.dap_server.request_setFunctionBreakpoints([func_foo])
7584
self.assertTrue(response["success"])
7685
breakpoints = response["body"]["breakpoints"]
77-
for breakpoint in breakpoints:
78-
foo_bp_id = breakpoint["id"]
79-
dap_breakpoint_ids.append(foo_bp_id)
80-
self.assertFalse(
81-
breakpoint["verified"], "expect foo breakpoint to not be verified"
82-
)
86+
self.assertEqual(len(breakpoints), 1, "expects only one function breakpoint")
87+
func_foo_breakpoint = breakpoints[0]
88+
foo_bp_id = func_foo_breakpoint["id"]
89+
dap_breakpoint_ids.append(foo_bp_id)
90+
self.assertFalse(
91+
func_foo_breakpoint["verified"],
92+
"expects unique function breakpoint to not be verified",
93+
)
8394

84-
# Flush the breakpoint events.
85-
self.dap_server.wait_for_breakpoint_events()
95+
self.dap_server.request_configurationDone()
96+
launch_response = self.dap_server.receive_response(launch_seq)
97+
self.assertIsNotNone(launch_response)
98+
self.assertTrue(launch_response["success"])
8699

87-
# Continue to the breakpoint
88-
self.continue_to_breakpoints(dap_breakpoint_ids)
100+
# Wait for the next stop (breakpoint foo).
101+
self.verify_breakpoint_hit([foo_bp_id])
102+
unique_bp_id = 1
89103

104+
# Check the breakpoints set in dap is verified.
90105
verified_breakpoint_ids = []
91-
unverified_breakpoint_ids = []
92-
for breakpoint_event in self.dap_server.wait_for_breakpoint_events():
93-
breakpoint = breakpoint_event["body"]["breakpoint"]
94-
id = breakpoint["id"]
95-
if breakpoint["verified"]:
96-
verified_breakpoint_ids.append(id)
97-
else:
98-
unverified_breakpoint_ids.append(id)
106+
events = self.dap_server.wait_for_breakpoint_events()
107+
for breakpoint_event in events:
108+
breakpoint_event_body = breakpoint_event["body"]
109+
if breakpoint_event_body["reason"] != "changed":
110+
continue
111+
breakpoint = breakpoint_event_body["breakpoint"]
99112

100-
self.assertIn(main_bp_id, unverified_breakpoint_ids)
101-
self.assertIn(foo_bp_id, unverified_breakpoint_ids)
113+
if "verified" in breakpoint_event_body:
114+
self.assertFalse(
115+
breakpoint_event_body["verified"],
116+
f"expects changed breakpoint to be verified. event: {breakpoint_event}",
117+
)
118+
id = breakpoint["id"]
119+
verified_breakpoint_ids.append(id)
102120

103121
self.assertIn(main_bp_id, verified_breakpoint_ids)
104122
self.assertIn(foo_bp_id, verified_breakpoint_ids)
123+
self.assertNotIn(unique_bp_id, verified_breakpoint_ids)
124+
125+
# Continue to the unique function breakpoint set from preRunCommands.
126+
unique_function_stop_event = self.continue_to_next_stop()[0]
127+
unique_body = unique_function_stop_event["body"]
128+
self.assertEqual(unique_body["reason"], "breakpoint")
129+
self.assertIn(unique_bp_id, unique_body["hitBreakpointIds"])
130+
131+
# Clear line and function breakpoints and exit.
132+
self.dap_server.request_setFunctionBreakpoints([])
133+
self.dap_server.request_setBreakpoints(main_source, [])
134+
self.continue_to_exit()
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#include <stdio.h>
22

33
static void unique_function_name() {
4-
puts(__PRETTY_FUNCTION__); // foo breakpoint 2
4+
puts(__PRETTY_FUNCTION__); // call puts
55
}
66

77
int foo(int x) {
8-
// foo breakpoint 1
8+
int value = 100;
99
unique_function_name();
1010
return x + 42;
1111
}

0 commit comments

Comments
 (0)