• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2Test lldb-vscode setBreakpoints request
3"""
4
5
6import unittest2
7import vscode
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11import lldbvscode_testcase
12import os
13
14
15class TestVSCode_breakpointEvents(lldbvscode_testcase.VSCodeTestCaseBase):
16
17    mydir = TestBase.compute_mydir(__file__)
18
19    @skipIfWindows
20    @skipUnlessDarwin
21    def test_breakpoint_events(self):
22        '''
23            This test sets a breakpoint in a shared library and runs and stops
24            at the entry point of a program. When we stop at the entry point,
25            the shared library won't be loaded yet. At this point the
26            breakpoint should set itself, but not be verified because no
27            locations are resolved. We will then continue and expect to get a
28            breakpoint event that informs us that the breakpoint in the shared
29            library is "changed" and the correct line number should be
30            supplied. We also set a breakpoint using a LLDB command using the
31            "preRunCommands" when launching our program. Any breakpoints set via
32            the command interpreter should not be have breakpoint events sent
33            back to VS Code as the UI isn't able to add new breakpoints to
34            their UI. Code has been added that tags breakpoints set from VS Code
35            DAP packets so we know the IDE knows about them. If VS Code is ever
36            able to register breakpoints that aren't initially set in the GUI,
37            then we will need to revise this.
38        '''
39        main_source_basename = 'main.cpp'
40        main_source_path = os.path.join(os.getcwd(), main_source_basename)
41        foo_source_basename = 'foo.cpp'
42        foo_source_path = os.path.join(os.getcwd(), foo_source_basename)
43        main_bp_line = line_number('main.cpp', 'main breakpoint 1')
44        foo_bp1_line = line_number('foo.cpp', 'foo breakpoint 1')
45        foo_bp2_line = line_number('foo.cpp', 'foo breakpoint 2')
46
47        # Visual Studio Code Debug Adaptors have no way to specify the file
48        # without launching or attaching to a process, so we must start a
49        # process in order to be able to set breakpoints.
50        program = self.getBuildArtifact("a.out")
51
52        # Set a breakpoint after creating the target by running a command line
53        # command. It will eventually resolve and cause a breakpoint changed
54        # event to be sent to lldb-vscode. We want to make sure we don't send a
55        # breakpoint any breakpoints that were set from the command line.
56        # Breakpoints that are set via the VS code DAP packets will be
57        # registered and marked with a special keyword to ensure we deliver
58        # breakpoint events for these breakpoints but not for ones that are not
59        # set via the command interpreter.
60        bp_command = 'breakpoint set --file foo.cpp --line %u' % (foo_bp2_line)
61        self.build_and_launch(program, stopOnEntry=True,
62                              preRunCommands=[bp_command])
63        main_bp_id = 0
64        foo_bp_id = 0
65        # Set breakpoints and verify that they got set correctly
66        vscode_breakpoint_ids = []
67        response = self.vscode.request_setBreakpoints(main_source_path,
68                                                      [main_bp_line])
69        if response:
70            breakpoints = response['body']['breakpoints']
71            for breakpoint in breakpoints:
72                main_bp_id = breakpoint['id']
73                vscode_breakpoint_ids.append("%i" % (main_bp_id))
74                # line = breakpoint['line']
75                self.assertTrue(breakpoint['verified'],
76                                "expect main breakpoint to be verified")
77
78        response = self.vscode.request_setBreakpoints(foo_source_path,
79                                                      [foo_bp1_line])
80        if response:
81            breakpoints = response['body']['breakpoints']
82            for breakpoint in breakpoints:
83                foo_bp_id = breakpoint['id']
84                vscode_breakpoint_ids.append("%i" % (foo_bp_id))
85                self.assertFalse(breakpoint['verified'],
86                                 "expect foo breakpoint to not be verified")
87
88        # Get the stop at the entry point
89        self.continue_to_next_stop()
90
91        # We are now stopped at the entry point to the program. Shared
92        # libraries are not loaded yet (at least on macOS they aren't) and any
93        # breakpoints set in foo.cpp should not be resolved.
94        self.assertTrue(len(self.vscode.breakpoint_events) == 0,
95                        "no breakpoint events when stopped at entry point")
96
97        # Continue to the breakpoint
98        self.continue_to_breakpoints(vscode_breakpoint_ids)
99
100        # Make sure we only get an event for the breakpoint we set via a call
101        # to self.vscode.request_setBreakpoints(...), not the breakpoint
102        # we set with with a LLDB command in preRunCommands.
103        self.assertTrue(len(self.vscode.breakpoint_events) == 1,
104                        "make sure we got a breakpoint event")
105        event = self.vscode.breakpoint_events[0]
106        # Verify the details of the breakpoint changed notification.
107        body = event['body']
108        self.assertTrue(body['reason'] == 'changed',
109                "breakpoint event is says breakpoint is changed")
110        breakpoint = body['breakpoint']
111        self.assertTrue(breakpoint['verified'] == True,
112                "breakpoint event is says it is verified")
113        self.assertTrue(breakpoint['id'] == foo_bp_id,
114                "breakpoint event is for breakpoint %i" % (foo_bp_id))
115        self.assertTrue('line' in breakpoint and breakpoint['line'] > 0,
116                "breakpoint event is has a line number")
117        self.assertNotIn("source", breakpoint,
118                "breakpoint event should not return a source object")
119