This is an ongoing series of commits that are reformatting our Python code. Reformatting is done with `black` (23.1.0). If you end up having problems merging this commit because you have made changes to a python file, the best way to handle that is to run `git checkout --ours <yourfile>` and then reformat it with black. RFC: https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style Differential revision: https://reviews.llvm.org/D151460
201 lines
7.7 KiB
Python
201 lines
7.7 KiB
Python
"""
|
|
Test the "process continue -b" option.
|
|
"""
|
|
|
|
|
|
import lldb
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
|
|
|
|
class TestContinueToBkpts(TestBase):
|
|
NO_DEBUG_INFO_TESTCASE = True
|
|
|
|
@add_test_categories(["pyapi"])
|
|
def test_continue_to_breakpoints(self):
|
|
"""Test that the continue to breakpoints feature works correctly."""
|
|
self.build()
|
|
self.do_test_continue_to_breakpoint()
|
|
|
|
def setUp(self):
|
|
# Call super's setUp().
|
|
TestBase.setUp(self)
|
|
self.main_source_spec = lldb.SBFileSpec("main.c")
|
|
|
|
def continue_and_check(self, stop_list, bkpt_to_hit, loc_to_hit=0):
|
|
"""Build up a command that will run a continue -b commands using the breakpoints on stop_list, and
|
|
ensure that we hit bkpt_to_hit.
|
|
If loc_to_hit is not 0, also verify that we hit that location."""
|
|
command = "process continue"
|
|
for elem in stop_list:
|
|
command += " -b {0}".format(elem)
|
|
self.expect(command)
|
|
self.assertStopReason(
|
|
self.thread.stop_reason, lldb.eStopReasonBreakpoint, "Hit a breakpoint"
|
|
)
|
|
self.assertEqual(
|
|
self.thread.GetStopReasonDataAtIndex(0),
|
|
bkpt_to_hit,
|
|
"Hit the right breakpoint",
|
|
)
|
|
if loc_to_hit != 0:
|
|
self.assertEqual(
|
|
self.thread.GetStopReasonDataAtIndex(1),
|
|
loc_to_hit,
|
|
"Hit the right location",
|
|
)
|
|
for bkpt_id in self.bkpt_list:
|
|
bkpt = self.target.FindBreakpointByID(bkpt_id)
|
|
self.assertTrue(bkpt.IsValid(), "Breakpoint id's round trip")
|
|
if bkpt.MatchesName("disabled"):
|
|
self.assertFalse(
|
|
bkpt.IsEnabled(),
|
|
"Disabled breakpoints stay disabled: {0}".format(bkpt.GetID()),
|
|
)
|
|
else:
|
|
self.assertTrue(
|
|
bkpt.IsEnabled(),
|
|
"Enabled breakpoints stay enabled: {0}".format(bkpt.GetID()),
|
|
)
|
|
# Also do our multiple location one:
|
|
bkpt = self.target.FindBreakpointByID(self.multiple_loc_id)
|
|
self.assertTrue(bkpt.IsValid(), "Breakpoint with locations round trip")
|
|
for i in range(1, 3):
|
|
loc = bkpt.FindLocationByID(i)
|
|
self.assertTrue(loc.IsValid(), "Locations round trip")
|
|
if i == 2:
|
|
self.assertTrue(
|
|
loc.IsEnabled(), "Locations that were enabled stay enabled"
|
|
)
|
|
else:
|
|
self.assertFalse(
|
|
loc.IsEnabled(), "Locations that were disabled stay disabled"
|
|
)
|
|
|
|
def do_test_continue_to_breakpoint(self):
|
|
"""Test the continue to breakpoint feature."""
|
|
(self.target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(
|
|
self, "Stop here to get started", self.main_source_spec
|
|
)
|
|
|
|
# Now set up all our breakpoints:
|
|
bkpt_pattern = "This is the {0} stop"
|
|
bkpt_elements = [
|
|
"zeroth",
|
|
"first",
|
|
"second",
|
|
"third",
|
|
"fourth",
|
|
"fifth",
|
|
"sixth",
|
|
"seventh",
|
|
"eighth",
|
|
"nineth",
|
|
]
|
|
disabled_bkpts = ["first", "eigth"]
|
|
bkpts_for_MyBKPT = ["first", "sixth", "nineth"]
|
|
self.bkpt_list = []
|
|
for elem in bkpt_elements:
|
|
bkpt = self.target.BreakpointCreateBySourceRegex(
|
|
bkpt_pattern.format(elem), self.main_source_spec
|
|
)
|
|
self.assertGreater(bkpt.GetNumLocations(), 0, "Found a bkpt match")
|
|
self.bkpt_list.append(bkpt.GetID())
|
|
bkpt.AddName(elem)
|
|
if elem in disabled_bkpts:
|
|
bkpt.AddName("disabled")
|
|
bkpt.SetEnabled(False)
|
|
if elem in bkpts_for_MyBKPT:
|
|
bkpt.AddName("MyBKPT")
|
|
# Also make one that has several locations, so we can test locations:
|
|
mult_bkpt = self.target.BreakpointCreateBySourceRegex(
|
|
bkpt_pattern.format("(seventh|eighth|nineth)"), self.main_source_spec
|
|
)
|
|
self.assertEqual(mult_bkpt.GetNumLocations(), 3, "Got three matches")
|
|
mult_bkpt.AddName("Locations")
|
|
# Disable all of these:
|
|
for i in range(1, 4):
|
|
loc = mult_bkpt.FindLocationByID(i)
|
|
self.assertTrue(loc.IsValid(), "Location {0} is valid".format(i))
|
|
loc.SetEnabled(False)
|
|
self.assertFalse(loc.IsEnabled(), "Loc {0} wasn't disabled".format(i))
|
|
self.multiple_loc_id = mult_bkpt.GetID()
|
|
|
|
# First test out various error conditions
|
|
|
|
# All locations of the multiple_loc_id are disabled, so running to this should be an error:
|
|
self.expect(
|
|
"process continue -b {0}".format(self.multiple_loc_id),
|
|
error=True,
|
|
msg="Running to a disabled breakpoint by number",
|
|
)
|
|
|
|
# Now re-enable the middle one so we can run to it:
|
|
loc = mult_bkpt.FindLocationByID(2)
|
|
loc.SetEnabled(True)
|
|
|
|
self.expect(
|
|
"process continue -b {0}".format(self.bkpt_list[1]),
|
|
error=True,
|
|
msg="Running to a disabled breakpoint by number",
|
|
)
|
|
self.expect(
|
|
"process continue -b {0}.1".format(self.bkpt_list[1]),
|
|
error=True,
|
|
msg="Running to a location of a disabled breakpoint",
|
|
)
|
|
self.expect(
|
|
"process continue -b disabled",
|
|
error=True,
|
|
msg="Running to a disabled set of breakpoints",
|
|
)
|
|
self.expect(
|
|
"process continue -b {0}.{1}".format(self.multiple_loc_id, 1),
|
|
error=True,
|
|
msg="Running to a disabled breakpoint location",
|
|
)
|
|
self.expect(
|
|
"process continue -b {0}".format("THERE_ARE_NO_BREAKPOINTS_BY_THIS_NAME"),
|
|
error=True,
|
|
msg="Running to no such name",
|
|
)
|
|
self.expect(
|
|
"process continue -b {0}".format(1000),
|
|
error=True,
|
|
msg="Running to no such breakpoint",
|
|
)
|
|
self.expect(
|
|
"process continue -b {0}.{1}".format(self.multiple_loc_id, 1000),
|
|
error=True,
|
|
msg="Running to no such location",
|
|
)
|
|
|
|
# Now move forward, this time with breakpoint numbers. First time we don't skip other bkpts.
|
|
bkpt = self.bkpt_list[0]
|
|
self.continue_and_check([str(bkpt)], bkpt)
|
|
|
|
# Now skip to the third stop, do it by name and supply one of the later breakpoints as well:
|
|
# This continue has to muck with the sync mode of the debugger, so let's make sure we
|
|
# put it back. First try if it was in sync mode:
|
|
orig_async = self.dbg.GetAsync()
|
|
self.dbg.SetAsync(True)
|
|
self.continue_and_check([bkpt_elements[2], bkpt_elements[7]], self.bkpt_list[2])
|
|
after_value = self.dbg.GetAsync()
|
|
self.dbg.SetAsync(orig_async)
|
|
self.assertTrue(after_value, "Preserve async as True if it started that way")
|
|
|
|
# Now try a name that has several breakpoints.
|
|
# This time I'm also going to check that we put the debugger async mode back if
|
|
# if was False to begin with:
|
|
self.dbg.SetAsync(False)
|
|
self.continue_and_check(["MyBKPT"], self.bkpt_list[6])
|
|
after_value = self.dbg.GetAsync()
|
|
self.dbg.SetAsync(orig_async)
|
|
self.assertFalse(after_value, "Preserve async as False if it started that way")
|
|
|
|
# Now let's run to a particular location. Also specify a breakpoint we've already hit:
|
|
self.continue_and_check(
|
|
[self.bkpt_list[0], self.multiple_loc_id], self.multiple_loc_id, 2
|
|
)
|