2 Test lldb breakpoint command add/list/delete.
5 from __future__ import print_function
11 from lldbsuite.test.lldbtest import *
12 import lldbsuite.test.lldbutil as lldbutil
14 class BreakpointCommandTestCase(TestBase):
16 mydir = TestBase.compute_mydir(__file__)
19 def classCleanup(cls):
20 """Cleanup the test byproduct of breakpoint_command_sequence(self)."""
21 cls.RemoveTempFile("output.txt")
22 cls.RemoveTempFile("output2.txt")
24 @expectedFailureWindows("llvm.org/pr24528")
26 """Test a sequence of breakpoint command add, list, and delete."""
28 self.breakpoint_command_sequence()
29 self.breakpoint_command_script_parameters ()
32 # Call super's setUp().
34 # Find the line number to break inside main().
35 self.line = line_number('main.c', '// Set break point at this line.')
36 # disable "There is a running process, kill it and restart?" prompt
37 self.runCmd("settings set auto-confirm true")
38 self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
40 def breakpoint_command_sequence(self):
41 """Test a sequence of breakpoint command add, list, and delete."""
42 exe = os.path.join(os.getcwd(), "a.out")
43 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
45 # Add three breakpoints on the same line. The first time we don't specify the file,
46 # since the default file is the one containing main:
47 lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1, loc_exact=True)
48 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
49 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
50 # Breakpoint 4 - set at the same location as breakpoint 1 to test setting breakpoint commands on two breakpoints at a time
51 lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1, loc_exact=True)
53 # Now add callbacks for the breakpoints just created.
54 self.runCmd("breakpoint command add -s command -o 'frame variable --show-types --scope' 1 4")
55 self.runCmd("breakpoint command add -s python -o 'here = open(\"output.txt\", \"w\"); here.write(\"lldb\\n\"); here.close()' 2")
56 self.runCmd("breakpoint command add --python-function bktptcmd.function 3")
58 # Check that the breakpoint commands are correctly set.
60 # The breakpoint list now only contains breakpoint 1.
61 self.expect("breakpoint list", "Breakpoints 1 & 2 created",
62 substrs = ["2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line],
63 patterns = ["1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line] )
65 self.expect("breakpoint list -f", "Breakpoints 1 & 2 created",
66 substrs = ["2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line],
67 patterns = ["1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line,
68 "1.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line,
69 "2.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line])
71 self.expect("breakpoint command list 1", "Breakpoint 1 command ok",
72 substrs = ["Breakpoint commands:",
73 "frame variable --show-types --scope"])
74 self.expect("breakpoint command list 2", "Breakpoint 2 command ok",
75 substrs = ["Breakpoint commands:",
79 self.expect("breakpoint command list 3", "Breakpoint 3 command ok",
80 substrs = ["Breakpoint commands:",
81 "bktptcmd.function(frame, bp_loc, internal_dict)"])
83 self.expect("breakpoint command list 4", "Breakpoint 4 command ok",
84 substrs = ["Breakpoint commands:",
85 "frame variable --show-types --scope"])
87 self.runCmd("breakpoint delete 4")
89 self.runCmd("command script import --allow-reload ./bktptcmd.py")
91 # Next lets try some other breakpoint kinds. First break with a regular expression
92 # and then specify only one file. The first time we should get two locations,
93 # the second time only one:
95 lldbutil.run_break_set_by_regexp (self, r"._MyFunction", num_expected_locations=2)
97 lldbutil.run_break_set_by_regexp (self, r"._MyFunction", extra_options="-f a.c", num_expected_locations=1)
99 lldbutil.run_break_set_by_regexp (self, r"._MyFunction", extra_options="-f a.c -f b.c", num_expected_locations=2)
101 # Now try a source regex breakpoint:
102 lldbutil.run_break_set_by_source_regexp (self, r"is about to return [12]0", extra_options="-f a.c -f b.c", num_expected_locations=2)
104 lldbutil.run_break_set_by_source_regexp (self, r"is about to return [12]0", extra_options="-f a.c", num_expected_locations=1)
106 # Run the program. Remove 'output.txt' if it exists.
107 self.RemoveTempFile("output.txt")
108 self.RemoveTempFile("output2.txt")
109 self.runCmd("run", RUN_SUCCEEDED)
111 # Check that the file 'output.txt' exists and contains the string "lldb".
113 # The 'output.txt' file should now exist.
114 self.assertTrue(os.path.isfile("output.txt"),
115 "'output.txt' exists due to breakpoint command for breakpoint 2.")
116 self.assertTrue(os.path.isfile("output2.txt"),
117 "'output2.txt' exists due to breakpoint command for breakpoint 3.")
119 # Read the output file produced by running the program.
120 with open('output.txt', 'r') as f:
123 self.expect(output, "File 'output.txt' and the content matches", exe=False,
126 with open('output2.txt', 'r') as f:
129 self.expect(output, "File 'output2.txt' and the content matches", exe=False,
133 # Finish the program.
134 self.runCmd("process continue")
136 # Remove the breakpoint command associated with breakpoint 1.
137 self.runCmd("breakpoint command delete 1")
139 # Remove breakpoint 2.
140 self.runCmd("breakpoint delete 2")
142 self.expect("breakpoint command list 1",
143 startstr = "Breakpoint 1 does not have an associated command.")
144 self.expect("breakpoint command list 2", error=True,
145 startstr = "error: '2' is not a currently valid breakpoint id.")
147 # The breakpoint list now only contains breakpoint 1.
148 self.expect("breakpoint list -f", "Breakpoint 1 exists",
149 patterns = ["1: file = '.*main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" %
154 self.expect("breakpoint list -f", "No more breakpoint 2", matching=False,
155 substrs = ["2: file = 'main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" %
158 # Run the program again, with breakpoint 1 remaining.
159 self.runCmd("run", RUN_SUCCEEDED)
161 # We should be stopped again due to breakpoint 1.
163 # The stop reason of the thread should be breakpoint.
164 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
165 substrs = ['stopped',
166 'stop reason = breakpoint'])
168 # The breakpoint should have a hit count of 2.
169 self.expect("breakpoint list -f", BREAKPOINT_HIT_TWICE,
170 substrs = ['resolved, hit count = 2'])
172 def breakpoint_command_script_parameters (self):
173 """Test that the frame and breakpoint location are being properly passed to the script breakpoint command function."""
174 exe = os.path.join(os.getcwd(), "a.out")
175 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
178 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
180 # Now add callbacks for the breakpoints just created.
181 self.runCmd("breakpoint command add -s python -o 'here = open(\"output-2.txt\", \"w\"); here.write(str(frame) + \"\\n\"); here.write(str(bp_loc) + \"\\n\"); here.close()' 1")
183 # Remove 'output-2.txt' if it already exists.
185 if (os.path.exists('output-2.txt')):
186 os.remove ('output-2.txt')
188 # Run program, hit breakpoint, and hopefully write out new version of 'output-2.txt'
189 self.runCmd ("run", RUN_SUCCEEDED)
191 # Check that the file 'output.txt' exists and contains the string "lldb".
193 # The 'output-2.txt' file should now exist.
194 self.assertTrue(os.path.isfile("output-2.txt"),
195 "'output-2.txt' exists due to breakpoint command for breakpoint 1.")
197 # Read the output file produced by running the program.
198 with open('output-2.txt', 'r') as f:
201 self.expect (output, "File 'output-2.txt' and the content matches", exe=False,
202 startstr = "frame #0:",
203 patterns = ["1.* where = .*main .* resolved, hit count = 1" ])
205 # Now remove 'output-2.txt'
206 os.remove ('output-2.txt')