[lldb] Readd missing functionalities/breakpoint tests

It seems when I restructured the test folders the functionalities/breakpoint
was deleted. This just reverts this change and re-adds the tests.

llvm-svn: 371512
This commit is contained in:
Raphael Isemann 2019-09-10 12:04:04 +00:00
parent 3729b17cff
commit d9442afba1
108 changed files with 5369 additions and 0 deletions

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS += -std=c99
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,96 @@
"""
Test address breakpoints set with shared library of SBAddress work correctly.
"""
from __future__ import print_function
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.lldbtest import *
class AddressBreakpointTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
def test_address_breakpoints(self):
"""Test address breakpoints set with shared library of SBAddress work correctly."""
self.build()
self.address_breakpoints()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
def address_breakpoints(self):
"""Test address breakpoints set with shared library of SBAddress work correctly."""
exe = self.getBuildArtifact("a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateBySourceRegex(
"Set a breakpoint here", lldb.SBFileSpec("main.c"))
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() >= 1,
VALID_BREAKPOINT)
# Get the breakpoint location from breakpoint after we verified that,
# indeed, it has one location.
location = breakpoint.GetLocationAtIndex(0)
self.assertTrue(location and
location.IsEnabled(),
VALID_BREAKPOINT_LOCATION)
# Next get the address from the location, and create an address breakpoint using
# that address:
address = location.GetAddress()
target.BreakpointDelete(breakpoint.GetID())
breakpoint = target.BreakpointCreateBySBAddress(address)
# Disable ASLR. This will allow us to actually test (on platforms that support this flag)
# that the breakpoint was able to track the module.
launch_info = lldb.SBLaunchInfo(None)
flags = launch_info.GetLaunchFlags()
flags &= ~lldb.eLaunchFlagDisableASLR
launch_info.SetLaunchFlags(flags)
error = lldb.SBError()
process = target.Launch(launch_info, error)
self.assertTrue(process, PROCESS_IS_VALID)
# Did we hit our breakpoint?
from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
threads = get_threads_stopped_at_breakpoint(process, breakpoint)
self.assertTrue(
len(threads) == 1,
"There should be a thread stopped at our breakpoint")
# The hit count for the breakpoint should be 1.
self.assertTrue(breakpoint.GetHitCount() == 1)
process.Kill()
# Now re-launch and see that we hit the breakpoint again:
launch_info.Clear()
launch_info.SetLaunchFlags(flags)
process = target.Launch(launch_info, error)
self.assertTrue(process, PROCESS_IS_VALID)
thread = get_threads_stopped_at_breakpoint(process, breakpoint)
self.assertTrue(
len(threads) == 1,
"There should be a thread stopped at our breakpoint")
# The hit count for the breakpoint should now be 2.
self.assertTrue(breakpoint.GetHitCount() == 2)

View File

@ -0,0 +1,47 @@
"""
Test that breakpoints set on a bad address say they are bad.
"""
from __future__ import print_function
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.lldbtest import *
class BadAddressBreakpointTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
def test_bad_address_breakpoints(self):
"""Test that breakpoints set on a bad address say they are bad."""
self.build()
self.address_breakpoints()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
def address_breakpoints(self):
"""Test that breakpoints set on a bad address say they are bad."""
target, process, thread, bkpt = \
lldbutil.run_to_source_breakpoint(self,
"Set a breakpoint here",
lldb.SBFileSpec("main.c"))
# Now see if we can read from 0. If I can't do that, I don't
# have a good way to know what an illegal address is...
error = lldb.SBError()
ptr = process.ReadPointerFromMemory(0x0, error)
if not error.Success():
bkpt = target.BreakpointCreateByAddress(0x0)
for bp_loc in bkpt:
self.assertTrue(bp_loc.IsResolved() == False)
else:
self.fail(
"Could not find an illegal address at which to set a bad breakpoint.")

View File

@ -0,0 +1,8 @@
#include <stdio.h>
int
main()
{
printf ("Set a breakpoint here.\n");
return 0;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS += -std=c99
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,101 @@
"""
Test that the breakpoint auto-continue flag works correctly.
"""
from __future__ import print_function
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.lldbtest import *
class BreakpointAutoContinue(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
def test_breakpoint_auto_continue(self):
"""Make sure the auto continue continues with no other complications"""
self.build()
self.simple_auto_continue()
def test_auto_continue_with_command(self):
"""Add a command, make sure the command gets run"""
self.build()
self.auto_continue_with_command()
def test_auto_continue_on_location(self):
"""Set auto-continue on a location and make sure only that location continues"""
self.build()
self.auto_continue_location()
def make_target_and_bkpt(self, additional_options=None, num_expected_loc=1,
pattern="Set a breakpoint here"):
exe = self.getBuildArtifact("a.out")
self.target = self.dbg.CreateTarget(exe)
self.assertTrue(self.target.IsValid(), "Target is not valid")
extra_options_txt = "--auto-continue 1 "
if additional_options:
extra_options_txt += additional_options
bpno = lldbutil.run_break_set_by_source_regexp(self, pattern,
extra_options = extra_options_txt,
num_expected_locations = num_expected_loc)
return bpno
def launch_it (self, expected_state):
error = lldb.SBError()
launch_info = lldb.SBLaunchInfo(None)
launch_info.SetWorkingDirectory(self.get_process_working_directory())
process = self.target.Launch(launch_info, error)
self.assertTrue(error.Success(), "Launch failed.")
state = process.GetState()
self.assertEqual(state, expected_state, "Didn't get expected state")
return process
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
def simple_auto_continue(self):
bpno = self.make_target_and_bkpt()
process = self.launch_it(lldb.eStateExited)
bkpt = self.target.FindBreakpointByID(bpno)
self.assertEqual(bkpt.GetHitCount(), 2, "Should have run through the breakpoint twice")
def auto_continue_with_command(self):
bpno = self.make_target_and_bkpt("-N BKPT -C 'break modify --auto-continue 0 BKPT'")
process = self.launch_it(lldb.eStateStopped)
state = process.GetState()
self.assertEqual(state, lldb.eStateStopped, "Process should be stopped")
bkpt = self.target.FindBreakpointByID(bpno)
threads = lldbutil.get_threads_stopped_at_breakpoint(process, bkpt)
self.assertEqual(len(threads), 1, "There was a thread stopped at our breakpoint")
self.assertEqual(bkpt.GetHitCount(), 2, "Should have hit the breakpoint twice")
def auto_continue_location(self):
bpno = self.make_target_and_bkpt(pattern="Set a[^ ]* breakpoint here", num_expected_loc=2)
bkpt = self.target.FindBreakpointByID(bpno)
bkpt.SetAutoContinue(False)
loc = lldb.SBBreakpointLocation()
for i in range(0,2):
func_name = bkpt.location[i].GetAddress().function.name
if func_name == "main":
loc = bkpt.location[i]
self.assertTrue(loc.IsValid(), "Didn't find a location in main")
loc.SetAutoContinue(True)
process = self.launch_it(lldb.eStateStopped)
threads = lldbutil.get_threads_stopped_at_breakpoint(process, bkpt)
self.assertEqual(len(threads), 1, "Didn't get one thread stopped at our breakpoint")
func_name = threads[0].frame[0].function.name
self.assertEqual(func_name, "call_me")

View File

@ -0,0 +1,19 @@
#include <stdio.h>
void
call_me()
{
printf("Set another breakpoint here.\n");
}
int
main()
{
int change_me = 0;
for (int i = 0; i < 2; i++)
{
printf ("Set a breakpoint here: %d with: %d.\n", i, change_me);
}
call_me();
return 0;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS += -std=c99 -gcolumn-info
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,45 @@
"""
Test setting a breakpoint by line and column.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointByLineAndColumnTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
## Skip gcc version less 7.1 since it doesn't support -gcolumn-info
@skipIf(compiler="gcc", compiler_version=['<', '7.1'])
def testBreakpointByLineAndColumn(self):
self.build()
main_c = lldb.SBFileSpec("main.c")
_, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self,
main_c, 19, 50)
self.expect("fr v did_call", substrs='1')
in_then = False
for i in range(breakpoint.GetNumLocations()):
b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry()
self.assertEqual(b_loc.GetLine(), 19)
in_then |= b_loc.GetColumn() == 50
self.assertTrue(in_then)
## Skip gcc version less 7.1 since it doesn't support -gcolumn-info
@skipIf(compiler="gcc", compiler_version=['<', '7.1'])
def testBreakpointByLine(self):
self.build()
main_c = lldb.SBFileSpec("main.c")
_, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self, main_c, 19)
self.expect("fr v did_call", substrs='0')
in_condition = False
for i in range(breakpoint.GetNumLocations()):
b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry()
self.assertEqual(b_loc.GetLine(), 19)
in_condition |= b_loc.GetColumn() < 30
self.assertTrue(in_condition)

View File

@ -0,0 +1,22 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
int square(int x)
{
return x * x;
}
int main (int argc, char const *argv[])
{
int did_call = 0;
// Line 20. v Column 50.
if(square(argc+1) != 0) { did_call = 1; return square(argc); }
// ^
return square(0);
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
C_SOURCES := main.c a.c b.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,285 @@
"""
Test lldb breakpoint command add/list/delete.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
import side_effect
class BreakpointCommandTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
mydir = TestBase.compute_mydir(__file__)
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
def test_breakpoint_command_sequence(self):
"""Test a sequence of breakpoint command add, list, and delete."""
self.build()
self.breakpoint_command_sequence()
def test_script_parameters(self):
"""Test a sequence of breakpoint command add, list, and delete."""
self.build()
self.breakpoint_command_script_parameters()
def test_commands_on_creation(self):
self.build()
self.breakpoint_commands_on_creation()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set break point at this line.')
# disable "There is a running process, kill it and restart?" prompt
self.runCmd("settings set auto-confirm true")
self.addTearDownHook(
lambda: self.runCmd("settings clear auto-confirm"))
def test_delete_all_breakpoints(self):
"""Test that deleting all breakpoints works."""
self.build()
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
lldbutil.run_break_set_by_symbol(self, "main")
lldbutil.run_break_set_by_file_and_line(
self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
self.runCmd("breakpoint delete")
self.runCmd("process continue")
self.expect("process status", PROCESS_STOPPED,
patterns=['Process .* exited with status = 0'])
def breakpoint_command_sequence(self):
"""Test a sequence of breakpoint command add, list, and delete."""
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Add three breakpoints on the same line. The first time we don't specify the file,
# since the default file is the one containing main:
lldbutil.run_break_set_by_file_and_line(
self, None, self.line, num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line(
self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line(
self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
# Breakpoint 4 - set at the same location as breakpoint 1 to test
# setting breakpoint commands on two breakpoints at a time
lldbutil.run_break_set_by_file_and_line(
self, None, self.line, num_expected_locations=1, loc_exact=True)
# Make sure relative path source breakpoints work as expected. We test
# with partial paths with and without "./" prefixes.
lldbutil.run_break_set_by_file_and_line(
self, "./main.c", self.line,
num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line(
self, "breakpoint_command/main.c", self.line,
num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line(
self, "./breakpoint_command/main.c", self.line,
num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line(
self, "breakpoint/breakpoint_command/main.c", self.line,
num_expected_locations=1, loc_exact=True)
lldbutil.run_break_set_by_file_and_line(
self, "./breakpoint/breakpoint_command/main.c", self.line,
num_expected_locations=1, loc_exact=True)
# Test relative breakpoints with incorrect paths and make sure we get
# no breakpoint locations
lldbutil.run_break_set_by_file_and_line(
self, "invalid/main.c", self.line,
num_expected_locations=0, loc_exact=True)
lldbutil.run_break_set_by_file_and_line(
self, "./invalid/main.c", self.line,
num_expected_locations=0, loc_exact=True)
# Now add callbacks for the breakpoints just created.
self.runCmd(
"breakpoint command add -s command -o 'frame variable --show-types --scope' 1 4")
self.runCmd(
"breakpoint command add -s python -o 'import side_effect; side_effect.one_liner = \"one liner was here\"' 2")
self.runCmd(
"breakpoint command add --python-function bktptcmd.function 3")
# Check that the breakpoint commands are correctly set.
# The breakpoint list now only contains breakpoint 1.
self.expect(
"breakpoint list", "Breakpoints 1 & 2 created", substrs=[
"2: file = 'main.c', line = %d, exact_match = 0, locations = 1" %
self.line], patterns=[
"1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" %
self.line])
self.expect(
"breakpoint list -f",
"Breakpoints 1 & 2 created",
substrs=[
"2: file = 'main.c', line = %d, exact_match = 0, locations = 1" %
self.line],
patterns=[
"1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" %
self.line,
"1.1: .+at main.c:%d:?[0-9]*, .+unresolved, hit count = 0" %
self.line,
"2.1: .+at main.c:%d:?[0-9]*, .+unresolved, hit count = 0" %
self.line])
self.expect("breakpoint command list 1", "Breakpoint 1 command ok",
substrs=["Breakpoint commands:",
"frame variable --show-types --scope"])
self.expect("breakpoint command list 2", "Breakpoint 2 command ok",
substrs=["Breakpoint commands (Python):",
"import side_effect",
"side_effect.one_liner"])
self.expect("breakpoint command list 3", "Breakpoint 3 command ok",
substrs=["Breakpoint commands (Python):",
"bktptcmd.function(frame, bp_loc, internal_dict)"])
self.expect("breakpoint command list 4", "Breakpoint 4 command ok",
substrs=["Breakpoint commands:",
"frame variable --show-types --scope"])
self.runCmd("breakpoint delete 4")
self.runCmd("command script import --allow-reload ./bktptcmd.py")
# Next lets try some other breakpoint kinds. First break with a regular expression
# and then specify only one file. The first time we should get two locations,
# the second time only one:
lldbutil.run_break_set_by_regexp(
self, r"._MyFunction", num_expected_locations=2)
lldbutil.run_break_set_by_regexp(
self,
r"._MyFunction",
extra_options="-f a.c",
num_expected_locations=1)
lldbutil.run_break_set_by_regexp(
self,
r"._MyFunction",
extra_options="-f a.c -f b.c",
num_expected_locations=2)
# Now try a source regex breakpoint:
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)
lldbutil.run_break_set_by_source_regexp(
self,
r"is about to return [12]0",
extra_options="-f a.c",
num_expected_locations=1)
# Reset our canary variables and run the program.
side_effect.one_liner = None
side_effect.bktptcmd = None
self.runCmd("run", RUN_SUCCEEDED)
# Check the value of canary variables.
self.assertEquals("one liner was here", side_effect.one_liner)
self.assertEquals("function was here", side_effect.bktptcmd)
# Finish the program.
self.runCmd("process continue")
# Remove the breakpoint command associated with breakpoint 1.
self.runCmd("breakpoint command delete 1")
# Remove breakpoint 2.
self.runCmd("breakpoint delete 2")
self.expect(
"breakpoint command list 1",
startstr="Breakpoint 1 does not have an associated command.")
self.expect(
"breakpoint command list 2",
error=True,
startstr="error: '2' is not a currently valid breakpoint ID.")
# The breakpoint list now only contains breakpoint 1.
self.expect(
"breakpoint list -f",
"Breakpoint 1 exists",
patterns=[
"1: file = '.*main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" %
self.line,
"hit count = 1"])
# Not breakpoint 2.
self.expect(
"breakpoint list -f",
"No more breakpoint 2",
matching=False,
substrs=[
"2: file = 'main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" %
self.line])
# Run the program again, with breakpoint 1 remaining.
self.runCmd("run", RUN_SUCCEEDED)
# We should be stopped again due to breakpoint 1.
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs=['stopped',
'stop reason = breakpoint'])
# The breakpoint should have a hit count of 2.
self.expect("breakpoint list -f", BREAKPOINT_HIT_TWICE,
substrs=['resolved, hit count = 2'])
def breakpoint_command_script_parameters(self):
"""Test that the frame and breakpoint location are being properly passed to the script breakpoint command function."""
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Add a breakpoint.
lldbutil.run_break_set_by_file_and_line(
self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
# Now add callbacks for the breakpoints just created.
self.runCmd("breakpoint command add -s python -o 'import side_effect; side_effect.frame = str(frame); side_effect.bp_loc = str(bp_loc)' 1")
# Reset canary variables and run.
side_effect.frame = None
side_effect.bp_loc = None
self.runCmd("run", RUN_SUCCEEDED)
self.expect(side_effect.frame, exe=False, startstr="frame #0:")
self.expect(side_effect.bp_loc, exe=False,
patterns=["1.* where = .*main .* resolved, hit count = 1"])
def breakpoint_commands_on_creation(self):
"""Test that setting breakpoint commands when creating the breakpoint works"""
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target.IsValid(), "Created an invalid target.")
# Add a breakpoint.
lldbutil.run_break_set_by_file_and_line(
self, "main.c", self.line, num_expected_locations=1, loc_exact=True,
extra_options='-C bt -C "thread list" -C continue')
bkpt = target.FindBreakpointByID(1)
self.assertTrue(bkpt.IsValid(), "Couldn't find breakpoint 1")
com_list = lldb.SBStringList()
bkpt.GetCommandLineCommands(com_list)
self.assertEqual(com_list.GetSize(), 3, "Got the wrong number of commands")
self.assertEqual(com_list.GetStringAtIndex(0), "bt", "First bt")
self.assertEqual(com_list.GetStringAtIndex(1), "thread list", "Next thread list")
self.assertEqual(com_list.GetStringAtIndex(2), "continue", "Last continue")

View File

@ -0,0 +1,99 @@
"""
Test that you can set breakpoint commands successfully with the Python API's:
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
import side_effect
class PythonBreakpointCommandSettingTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
@add_test_categories(['pyapi'])
def test_step_out_python(self):
"""Test stepping out using avoid-no-debug with dsyms."""
self.build()
self.do_set_python_command_from_python()
def setUp(self):
TestBase.setUp(self)
self.main_source = "main.c"
self.main_source_spec = lldb.SBFileSpec(self.main_source)
def do_set_python_command_from_python(self):
exe = self.getBuildArtifact("a.out")
error = lldb.SBError()
self.target = self.dbg.CreateTarget(exe)
self.assertTrue(self.target, VALID_TARGET)
body_bkpt = self.target.BreakpointCreateBySourceRegex(
"Set break point at this line.", self.main_source_spec)
self.assertTrue(body_bkpt, VALID_BREAKPOINT)
func_bkpt = self.target.BreakpointCreateBySourceRegex(
"Set break point at this line.", self.main_source_spec)
self.assertTrue(func_bkpt, VALID_BREAKPOINT)
# Also test that setting a source regex breakpoint with an empty file
# spec list sets it on all files:
no_files_bkpt = self.target.BreakpointCreateBySourceRegex(
"Set a breakpoint here", lldb.SBFileSpecList(), lldb.SBFileSpecList())
self.assertTrue(no_files_bkpt, VALID_BREAKPOINT)
num_locations = no_files_bkpt.GetNumLocations()
self.assertTrue(
num_locations >= 2,
"Got at least two breakpoint locations")
got_one_in_A = False
got_one_in_B = False
for idx in range(0, num_locations):
comp_unit = no_files_bkpt.GetLocationAtIndex(idx).GetAddress().GetSymbolContext(
lldb.eSymbolContextCompUnit).GetCompileUnit().GetFileSpec()
print("Got comp unit: ", comp_unit.GetFilename())
if comp_unit.GetFilename() == "a.c":
got_one_in_A = True
elif comp_unit.GetFilename() == "b.c":
got_one_in_B = True
self.assertTrue(got_one_in_A, "Failed to match the pattern in A")
self.assertTrue(got_one_in_B, "Failed to match the pattern in B")
self.target.BreakpointDelete(no_files_bkpt.GetID())
error = lldb.SBError()
error = body_bkpt.SetScriptCallbackBody(
"import side_effect; side_effect.callback = 'callback was here'")
self.assertTrue(
error.Success(),
"Failed to set the script callback body: %s." %
(error.GetCString()))
self.dbg.HandleCommand(
"command script import --allow-reload ./bktptcmd.py")
func_bkpt.SetScriptCallbackFunction("bktptcmd.function")
# Clear out canary variables
side_effect.bktptcmd = None
side_effect.callback = None
# Now launch the process, and do not stop at entry point.
self.process = self.target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(self.process, PROCESS_IS_VALID)
# Now finish, and make sure the return value is correct.
threads = lldbutil.get_threads_stopped_at_breakpoint(
self.process, body_bkpt)
self.assertTrue(len(threads) == 1, "Stopped at inner breakpoint.")
self.thread = threads[0]
self.assertEquals("callback was here", side_effect.callback)
self.assertEquals("function was here", side_effect.bktptcmd)

View File

@ -0,0 +1,71 @@
"""
Test _regexp-break command which uses regular expression matching to dispatch to other built in breakpoint commands.
"""
from __future__ import print_function
import os
import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
class RegexpBreakCommandTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def test(self):
"""Test _regexp-break command."""
self.build()
self.regexp_break_command()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.source = 'main.c'
self.line = line_number(
self.source, '// Set break point at this line.')
def regexp_break_command(self):
"""Test the super consie "b" command, which is analias for _regexp-break."""
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
break_results = lldbutil.run_break_set_command(
self, "b %d" %
self.line)
lldbutil.check_breakpoint_result(
self,
break_results,
file_name='main.c',
line_number=self.line,
num_locations=1)
break_results = lldbutil.run_break_set_command(
self, "b %s:%d" % (self.source, self.line))
lldbutil.check_breakpoint_result(
self,
break_results,
file_name='main.c',
line_number=self.line,
num_locations=1)
# Check breakpoint with full file path.
full_path = os.path.join(self.getSourceDir(), self.source)
break_results = lldbutil.run_break_set_command(
self, "b %s:%d" % (full_path, self.line))
lldbutil.check_breakpoint_result(
self,
break_results,
file_name='main.c',
line_number=self.line,
num_locations=1)
self.runCmd("run", RUN_SUCCEEDED)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs=['stopped',
'stop reason = breakpoint'])

View File

@ -0,0 +1,9 @@
#include <stdio.h>
int
a_MyFunction ()
{
// Set a breakpoint here.
printf ("a is about to return 10.\n");
return 10;
}

View File

@ -0,0 +1,9 @@
#include <stdio.h>
int
b_MyFunction ()
{
// Set a breakpoint here.
printf ("b is about to return 20.\n");
return 20;
}

View File

@ -0,0 +1,5 @@
from __future__ import print_function
import side_effect
def function(frame, bp_loc, dict):
side_effect.bktptcmd = "function was here"

View File

@ -0,0 +1,16 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
int main (int argc, char const *argv[])
{
// Add a body to the function, so we can set more than one
// breakpoint in it.
static volatile int var = 0;
var++;
return 0; // Set break point at this line.
}

View File

@ -0,0 +1,5 @@
"""
A dummy module for testing the execution of various breakpoint commands. A
command will modify a global variable in this module and test will check its
value.
"""

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS += -std=c99
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,226 @@
"""
Test breakpoint conditions with 'breakpoint modify -c <expr> id'.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointConditionsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def test_breakpoint_condition_and_run_command(self):
"""Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""
self.build()
self.breakpoint_conditions()
def test_breakpoint_condition_inline_and_run_command(self):
"""Exercise breakpoint condition inline with 'breakpoint set'."""
self.build()
self.breakpoint_conditions(inline=True)
@add_test_categories(['pyapi'])
def test_breakpoint_condition_and_python_api(self):
"""Use Python APIs to set breakpoint conditions."""
self.build()
self.breakpoint_conditions_python()
@add_test_categories(['pyapi'])
def test_breakpoint_invalid_condition_and_python_api(self):
"""Use Python APIs to set breakpoint conditions."""
self.build()
self.breakpoint_invalid_conditions_python()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to of function 'c'.
self.line1 = line_number(
'main.c', '// Find the line number of function "c" here.')
self.line2 = line_number(
'main.c', "// Find the line number of c's parent call here.")
def breakpoint_conditions(self, inline=False):
"""Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
if inline:
# Create a breakpoint by function name 'c' and set the condition.
lldbutil.run_break_set_by_symbol(
self,
"c",
extra_options="-c 'val == 3'",
num_expected_locations=1,
sym_exact=True)
else:
# Create a breakpoint by function name 'c'.
lldbutil.run_break_set_by_symbol(
self, "c", num_expected_locations=1, sym_exact=True)
# And set a condition on the breakpoint to stop on when 'val == 3'.
self.runCmd("breakpoint modify -c 'val == 3' 1")
# Now run the program.
self.runCmd("run", RUN_SUCCEEDED)
# The process should be stopped at this point.
self.expect("process status", PROCESS_STOPPED,
patterns=['Process .* stopped'])
# 'frame variable --show-types val' should return 3 due to breakpoint condition.
self.expect(
"frame variable --show-types val",
VARIABLES_DISPLAYED_CORRECTLY,
startstr='(int) val = 3')
# Also check the hit count, which should be 3, by design.
self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
substrs=["resolved = 1",
"Condition: val == 3",
"hit count = 1"])
# The frame #0 should correspond to main.c:36, the executable statement
# in function name 'c'. And the parent frame should point to
# main.c:24.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT_CONDITION,
#substrs = ["stop reason = breakpoint"],
patterns=["frame #0.*main.c:%d" % self.line1,
"frame #1.*main.c:%d" % self.line2])
# Test that "breakpoint modify -c ''" clears the condition for the last
# created breakpoint, so that when the breakpoint hits, val == 1.
self.runCmd("process kill")
self.runCmd("breakpoint modify -c ''")
self.expect(
"breakpoint list -f",
BREAKPOINT_STATE_CORRECT,
matching=False,
substrs=["Condition:"])
# Now run the program again.
self.runCmd("run", RUN_SUCCEEDED)
# The process should be stopped at this point.
self.expect("process status", PROCESS_STOPPED,
patterns=['Process .* stopped'])
# 'frame variable --show-types val' should return 1 since it is the first breakpoint hit.
self.expect(
"frame variable --show-types val",
VARIABLES_DISPLAYED_CORRECTLY,
startstr='(int) val = 1')
self.runCmd("process kill")
def breakpoint_conditions_python(self):
"""Use Python APIs to set breakpoint conditions."""
exe = self.getBuildArtifact("a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByName('c', 'a.out')
#print("breakpoint:", breakpoint)
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# We didn't associate a thread index with the breakpoint, so it should
# be invalid.
self.assertTrue(breakpoint.GetThreadIndex() == lldb.UINT32_MAX,
"The thread index should be invalid")
# The thread name should be invalid, too.
self.assertTrue(breakpoint.GetThreadName() is None,
"The thread name should be invalid")
# Let's set the thread index for this breakpoint and verify that it is,
# indeed, being set correctly.
# There's only one thread for the process.
breakpoint.SetThreadIndex(1)
self.assertTrue(breakpoint.GetThreadIndex() == 1,
"The thread index has been set correctly")
# Get the breakpoint location from breakpoint after we verified that,
# indeed, it has one location.
location = breakpoint.GetLocationAtIndex(0)
self.assertTrue(location and
location.IsEnabled(),
VALID_BREAKPOINT_LOCATION)
# Set the condition on the breakpoint location.
location.SetCondition('val == 3')
self.expect(location.GetCondition(), exe=False,
startstr='val == 3')
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# Frame #0 should be on self.line1 and the break condition should hold.
from lldbsuite.test.lldbutil import get_stopped_thread
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(
thread.IsValid(),
"There should be a thread stopped due to breakpoint condition")
frame0 = thread.GetFrameAtIndex(0)
var = frame0.FindValue('val', lldb.eValueTypeVariableArgument)
self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and
var.GetValue() == '3')
# The hit count for the breakpoint should be 1.
self.assertTrue(breakpoint.GetHitCount() == 1)
# Test that the condition expression didn't create a result variable:
options = lldb.SBExpressionOptions()
value = frame0.EvaluateExpression("$0", options)
self.assertTrue(value.GetError().Fail(),
"Conditions should not make result variables.")
process.Continue()
def breakpoint_invalid_conditions_python(self):
"""Use Python APIs to set breakpoint conditions."""
exe = self.getBuildArtifact("a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByName('c', 'a.out')
#print("breakpoint:", breakpoint)
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Set the condition on the breakpoint.
breakpoint.SetCondition('no_such_variable == not_this_one_either')
self.expect(breakpoint.GetCondition(), exe=False,
startstr='no_such_variable == not_this_one_either')
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# Frame #0 should be on self.line1 and the break condition should hold.
from lldbsuite.test.lldbutil import get_stopped_thread
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(
thread.IsValid(),
"There should be a thread stopped due to breakpoint condition")
frame0 = thread.GetFrameAtIndex(0)
var = frame0.FindValue('val', lldb.eValueTypeVariableArgument)
self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1)
# The hit count for the breakpoint should be 1.
self.assertTrue(breakpoint.GetHitCount() == 1)

View File

@ -0,0 +1,53 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to demonstrate the capability of the lldb command
// "breakpoint modify -c 'val == 3' breakpt-id" to break within c(int val) only
// when the value of the arg is 3.
int a(int);
int b(int);
int c(int);
int a(int val)
{
if (val <= 1)
return b(val);
else if (val >= 3)
return c(val); // Find the line number of c's parent call here.
return val;
}
int b(int val)
{
return c(val);
}
int c(int val)
{
return val + 3; // Find the line number of function "c" here.
}
int main (int argc, char const *argv[])
{
int A1 = a(1); // a(1) -> b(1) -> c(1)
printf("a(1) returns %d\n", A1);
int B2 = b(2); // b(2) -> c(2)
printf("b(2) returns %d\n", B2);
int A3 = a(3); // a(3) -> c(3)
printf("a(3) returns %d\n", A3);
for (int i = 0; i < 2; ++i)
printf("Loop\n");
return 0;
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,134 @@
"""
Test breakpoint hit count features.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointHitCountTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
mydir = TestBase.compute_mydir(__file__)
@add_test_categories(['pyapi'])
def test_breakpoint_location_hit_count(self):
"""Use Python APIs to check breakpoint hit count."""
self.build()
self.do_test_breakpoint_location_hit_count()
def test_breakpoint_one_shot(self):
"""Check that one-shot breakpoints trigger only once."""
self.build()
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
self.runCmd("tb a")
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
from lldbsuite.test.lldbutil import get_stopped_thread
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(
thread.IsValid(),
"There should be a thread stopped due to breakpoint")
frame0 = thread.GetFrameAtIndex(0)
self.assertTrue(frame0.GetFunctionName() == "a(int)" or frame0.GetFunctionName() == "int a(int)");
process.Continue()
self.assertEqual(process.GetState(), lldb.eStateExited)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
self.a_int_body_line_no = line_number(
'main.cpp', '// Breakpoint Location 1')
self.a_float_body_line_no = line_number(
'main.cpp', '// Breakpoint Location 2')
def do_test_breakpoint_location_hit_count(self):
"""Use Python APIs to check breakpoint hit count."""
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Create a breakpoint in main.cpp by name 'a',
# there should be two locations.
breakpoint = target.BreakpointCreateByName('a', 'a.out')
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 2,
VALID_BREAKPOINT)
# Verify all breakpoint locations are enabled.
location1 = breakpoint.GetLocationAtIndex(0)
self.assertTrue(location1 and
location1.IsEnabled(),
VALID_BREAKPOINT_LOCATION)
location2 = breakpoint.GetLocationAtIndex(1)
self.assertTrue(location2 and
location2.IsEnabled(),
VALID_BREAKPOINT_LOCATION)
# Launch the process, and do not stop at entry point.
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# Verify 1st breakpoint location is hit.
from lldbsuite.test.lldbutil import get_stopped_thread
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(
thread.IsValid(),
"There should be a thread stopped due to breakpoint")
frame0 = thread.GetFrameAtIndex(0)
location1 = breakpoint.FindLocationByAddress(frame0.GetPC())
self.assertTrue(
frame0.GetLineEntry().GetLine() == self.a_int_body_line_no,
"Stopped in int a(int)")
self.assertTrue(location1)
self.assertEqual(location1.GetHitCount(), 1)
self.assertEqual(breakpoint.GetHitCount(), 1)
process.Continue()
# Verify 2nd breakpoint location is hit.
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(
thread.IsValid(),
"There should be a thread stopped due to breakpoint")
frame0 = thread.GetFrameAtIndex(0)
location2 = breakpoint.FindLocationByAddress(frame0.GetPC())
self.assertTrue(
frame0.GetLineEntry().GetLine() == self.a_float_body_line_no,
"Stopped in float a(float)")
self.assertTrue(location2)
self.assertEqual(location2.GetHitCount(), 1)
self.assertEqual(location1.GetHitCount(), 1)
self.assertEqual(breakpoint.GetHitCount(), 2)
process.Continue()
# Verify 2nd breakpoint location is hit again.
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(
thread.IsValid(),
"There should be a thread stopped due to breakpoint")
self.assertEqual(location2.GetHitCount(), 2)
self.assertEqual(location1.GetHitCount(), 1)
self.assertEqual(breakpoint.GetHitCount(), 3)
process.Continue()

View File

@ -0,0 +1,26 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
int a(int val)
{
return val; // Breakpoint Location 1
}
float a(float val)
{
return val; // Breakpoint Location 2
}
int main (int argc, char const *argv[])
{
int A1 = a(1);
float A2 = a(2.0f);
float A3 = a(3.0f);
return 0;
}

View File

@ -0,0 +1,9 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
ifneq (,$(findstring icc,$(CC)))
CXXFLAGS += -debug inline-debug-info
endif
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,58 @@
"""
Test lldb breakpoint ids.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
class BreakpointIDTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def test(self):
self.build()
exe = self.getBuildArtifact("a.out")
self.expect("file " + exe,
patterns=["Current executable set to .*a.out"])
bpno = lldbutil.run_break_set_by_symbol(
self, 'product', num_expected_locations=-1, sym_exact=False)
self.assertTrue(bpno == 1, "First breakpoint number is 1.")
bpno = lldbutil.run_break_set_by_symbol(
self, 'sum', num_expected_locations=-1, sym_exact=False)
self.assertTrue(bpno == 2, "Second breakpoint number is 2.")
bpno = lldbutil.run_break_set_by_symbol(
self, 'junk', num_expected_locations=0, sym_exact=False)
self.assertTrue(bpno == 3, "Third breakpoint number is 3.")
self.expect(
"breakpoint disable 1.1 - 2.2 ",
COMMAND_FAILED_AS_EXPECTED,
error=True,
startstr="error: Invalid range: Ranges that specify particular breakpoint locations must be within the same major breakpoint; you specified two different major breakpoints, 1 and 2.")
self.expect(
"breakpoint disable 2 - 2.2",
COMMAND_FAILED_AS_EXPECTED,
error=True,
startstr="error: Invalid breakpoint id range: Either both ends of range must specify a breakpoint location, or neither can specify a breakpoint location.")
self.expect(
"breakpoint disable 2.1 - 2",
COMMAND_FAILED_AS_EXPECTED,
error=True,
startstr="error: Invalid breakpoint id range: Either both ends of range must specify a breakpoint location, or neither can specify a breakpoint location.")
self.expect("breakpoint disable 2.1 - 2.2",
startstr="2 breakpoints disabled.")
self.expect("breakpoint enable 2.*",
patterns=[".* breakpoints enabled."])

View File

@ -0,0 +1,64 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <cstdlib>
#include <string>
#include <fstream>
#include <iostream>
#define INLINE inline __attribute__((always_inline))
INLINE int
product (int x, int y)
{
int result = x * y;
return result;
}
INLINE int
sum (int a, int b)
{
int result = a + b;
return result;
}
int
strange_max (int m, int n)
{
if (m > n)
return m;
else if (n > m)
return n;
else
return 0;
}
int
foo (int i, int j)
{
if (strange_max (i, j) == i)
return product (i, j);
else if (strange_max (i, j) == j)
return sum (i, j);
else
return product (sum (i, i), sum (j, j));
}
int
main(int argc, char const *argv[])
{
int array[3];
array[0] = foo (1238, 78392);
array[1] = foo (379265, 23674);
array[2] = foo (872934, 234);
return 0;
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,151 @@
"""
Test breakpoint ignore count features.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointIgnoreCountTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # This test will hang on windows llvm.org/pr21753
def test_with_run_command(self):
"""Exercise breakpoint ignore count with 'breakpoint set -i <count>'."""
self.build()
self.breakpoint_ignore_count()
@add_test_categories(['pyapi'])
@skipIfWindows # This test will hang on windows llvm.org/pr21753
def test_with_python_api(self):
"""Use Python APIs to set breakpoint ignore count."""
self.build()
self.breakpoint_ignore_count_python()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to of function 'c'.
self.line1 = line_number(
'main.c', '// Find the line number of function "c" here.')
self.line2 = line_number(
'main.c', '// b(2) -> c(2) Find the call site of b(2).')
self.line3 = line_number(
'main.c', '// a(3) -> c(3) Find the call site of c(3).')
self.line4 = line_number(
'main.c', '// a(3) -> c(3) Find the call site of a(3).')
self.line5 = line_number(
'main.c', '// Find the call site of c in main.')
def breakpoint_ignore_count(self):
"""Exercise breakpoint ignore count with 'breakpoint set -i <count>'."""
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Create a breakpoint in main.c at line1.
lldbutil.run_break_set_by_file_and_line(
self,
'main.c',
self.line1,
extra_options='-i 1',
num_expected_locations=1,
loc_exact=True)
# Now run the program.
self.runCmd("run", RUN_SUCCEEDED)
# The process should be stopped at this point.
self.expect("process status", PROCESS_STOPPED,
patterns=['Process .* stopped'])
# Also check the hit count, which should be 2, due to ignore count of
# 1.
self.expect("breakpoint list -f", BREAKPOINT_HIT_THRICE,
substrs=["resolved = 1",
"hit count = 2"])
# The frame #0 should correspond to main.c:37, the executable statement
# in function name 'c'. And frame #2 should point to main.c:45.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT,
#substrs = ["stop reason = breakpoint"],
patterns=["frame #0.*main.c:%d" % self.line1,
"frame #2.*main.c:%d" % self.line2])
# continue -i 1 is the same as setting the ignore count to 1 again, try that:
# Now run the program.
self.runCmd("process continue -i 1", RUN_SUCCEEDED)
# The process should be stopped at this point.
self.expect("process status", PROCESS_STOPPED,
patterns=['Process .* stopped'])
# Also check the hit count, which should be 2, due to ignore count of
# 1.
self.expect("breakpoint list -f", BREAKPOINT_HIT_THRICE,
substrs=["resolved = 1",
"hit count = 4"])
# The frame #0 should correspond to main.c:37, the executable statement
# in function name 'c'. And frame #2 should point to main.c:45.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT,
#substrs = ["stop reason = breakpoint"],
patterns=["frame #0.*main.c:%d" % self.line1,
"frame #1.*main.c:%d" % self.line5])
def breakpoint_ignore_count_python(self):
"""Use Python APIs to set breakpoint ignore count."""
exe = self.getBuildArtifact("a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByName('c', 'a.out')
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Get the breakpoint location from breakpoint after we verified that,
# indeed, it has one location.
location = breakpoint.GetLocationAtIndex(0)
self.assertTrue(location and
location.IsEnabled(),
VALID_BREAKPOINT_LOCATION)
# Set the ignore count on the breakpoint location.
location.SetIgnoreCount(2)
self.assertTrue(location.GetIgnoreCount() == 2,
"SetIgnoreCount() works correctly")
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# Frame#0 should be on main.c:37, frame#1 should be on main.c:25, and
# frame#2 should be on main.c:48.
# lldbutil.print_stacktraces(process)
from lldbsuite.test.lldbutil import get_stopped_thread
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(
thread.IsValid(),
"There should be a thread stopped due to breakpoint")
frame0 = thread.GetFrameAtIndex(0)
frame1 = thread.GetFrameAtIndex(1)
frame2 = thread.GetFrameAtIndex(2)
self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and
frame1.GetLineEntry().GetLine() == self.line3 and
frame2.GetLineEntry().GetLine() == self.line4,
STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT)
# The hit count for the breakpoint should be 3.
self.assertTrue(breakpoint.GetHitCount() == 3)
process.Continue()

View File

@ -0,0 +1,53 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to demonstrate the capability of the lldb command
// "breakpoint modify -i <count> breakpt-id" to set the number of times a
// breakpoint is skipped before stopping. Ignore count can also be set upon
// breakpoint creation by 'breakpoint set ... -i <count>'.
int a(int);
int b(int);
int c(int);
int a(int val)
{
if (val <= 1)
return b(val);
else if (val >= 3)
return c(val); // a(3) -> c(3) Find the call site of c(3).
return val;
}
int b(int val)
{
return c(val);
}
int c(int val)
{
return val + 3; // Find the line number of function "c" here.
}
int main (int argc, char const *argv[])
{
int A1 = a(1); // a(1) -> b(1) -> c(1)
printf("a(1) returns %d\n", A1);
int B2 = b(2); // b(2) -> c(2) Find the call site of b(2).
printf("b(2) returns %d\n", B2);
int A3 = a(3); // a(3) -> c(3) Find the call site of a(3).
printf("a(3) returns %d\n", A3);
int C1 = c(5); // Find the call site of c in main.
printf ("c(5) returns %d\n", C1);
return 0;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,87 @@
"""
Test specific to MIPS
"""
from __future__ import print_function
import re
import unittest2
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class AvoidBreakpointInDelaySlotAPITestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIf(archs=no_match(re.compile('mips*')))
def test(self):
self.build()
exe = self.getBuildArtifact("a.out")
self.expect("file " + exe,
patterns=["Current executable set to .*a.out.*"])
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
breakpoint = target.BreakpointCreateByName('main', 'a.out')
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
list = target.FindFunctions('foo', lldb.eFunctionNameTypeAuto)
self.assertTrue(list.GetSize() == 1)
sc = list.GetContextAtIndex(0)
self.assertTrue(sc.GetSymbol().GetName() == "foo")
function = sc.GetFunction()
self.assertTrue(function)
self.function(function, target)
def function(self, function, target):
"""Iterate over instructions in function and place a breakpoint on delay slot instruction"""
# Get the list of all instructions in the function
insts = function.GetInstructions(target)
print(insts)
i = 0
for inst in insts:
if (inst.HasDelaySlot()):
# Remember the address of branch instruction.
branchinstaddress = inst.GetAddress().GetLoadAddress(target)
# Get next instruction i.e delay slot instruction.
delayinst = insts.GetInstructionAtIndex(i + 1)
delayinstaddr = delayinst.GetAddress().GetLoadAddress(target)
# Set breakpoint on delay slot instruction
breakpoint = target.BreakpointCreateByAddress(delayinstaddr)
# Verify the breakpoint.
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Get the location from breakpoint
location = breakpoint.GetLocationAtIndex(0)
# Get the address where breakpoint is actually set.
bpaddr = location.GetLoadAddress()
# Breakpoint address should be adjusted to the address of
# branch instruction.
self.assertTrue(branchinstaddress == bpaddr)
i += 1
else:
i += 1
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@ -0,0 +1,21 @@
#include <stdio.h>
foo (int a, int b)
{
int c;
if (a<=b)
c=b-a;
else
c=b+a;
return c;
}
int main()
{
int a=7, b=8, c;
c = foo(a, b);
return 0;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := a.c
CXX_SOURCES := main.cpp b.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,133 @@
"""
Test that the language option for breakpoints works correctly
parser.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
class TestBreakpointLanguage(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
def check_location_file(self, bp, loc, test_name):
bp_loc = bp.GetLocationAtIndex(loc)
addr = bp_loc.GetAddress()
comp_unit = addr.GetCompileUnit()
comp_name = comp_unit.GetFileSpec().GetFilename()
return comp_name == test_name
def test_regex_breakpoint_language(self):
"""Test that the name regex breakpoint commands obey the language filter."""
self.build()
# Create a target by the debugger.
exe = self.getBuildArtifact("a.out")
error = lldb.SBError()
# Don't read in dependencies so we don't come across false matches that
# add unwanted breakpoint hits.
self.target = self.dbg.CreateTarget(exe, None, None, False, error)
self.assertTrue(self.target, VALID_TARGET)
cpp_bp = self.target.BreakpointCreateByRegex(
"func_from",
lldb.eLanguageTypeC_plus_plus,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
cpp_bp.GetNumLocations() == 1,
"Only one C++ symbol matches")
self.assertTrue(self.check_location_file(cpp_bp, 0, "b.cpp"))
c_bp = self.target.BreakpointCreateByRegex(
"func_from",
lldb.eLanguageTypeC,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
c_bp.GetNumLocations() == 1,
"Only one C symbol matches")
self.assertTrue(self.check_location_file(c_bp, 0, "a.c"))
objc_bp = self.target.BreakpointCreateByRegex(
"func_from",
lldb.eLanguageTypeObjC,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
objc_bp.GetNumLocations() == 0,
"No ObjC symbol matches")
def test_by_name_breakpoint_language(self):
"""Test that the name regex breakpoint commands obey the language filter."""
self.build()
# Create a target by the debugger.
exe = self.getBuildArtifact("a.out")
error = lldb.SBError()
# Don't read in dependencies so we don't come across false matches that
# add unwanted breakpoint hits.
self.target = self.dbg.CreateTarget(exe, None, None, False, error)
self.assertTrue(self.target, VALID_TARGET)
cpp_bp = self.target.BreakpointCreateByName(
"func_from_cpp",
lldb.eFunctionNameTypeAuto,
lldb.eLanguageTypeC_plus_plus,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
cpp_bp.GetNumLocations() == 1,
"Only one C++ symbol matches")
self.assertTrue(self.check_location_file(cpp_bp, 0, "b.cpp"))
no_cpp_bp = self.target.BreakpointCreateByName(
"func_from_c",
lldb.eFunctionNameTypeAuto,
lldb.eLanguageTypeC_plus_plus,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
no_cpp_bp.GetNumLocations() == 0,
"And the C one doesn't match")
c_bp = self.target.BreakpointCreateByName(
"func_from_c",
lldb.eFunctionNameTypeAuto,
lldb.eLanguageTypeC,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
c_bp.GetNumLocations() == 1,
"Only one C symbol matches")
self.assertTrue(self.check_location_file(c_bp, 0, "a.c"))
no_c_bp = self.target.BreakpointCreateByName(
"func_from_cpp",
lldb.eFunctionNameTypeAuto,
lldb.eLanguageTypeC,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
no_c_bp.GetNumLocations() == 0,
"And the C++ one doesn't match")
objc_bp = self.target.BreakpointCreateByName(
"func_from_cpp",
lldb.eFunctionNameTypeAuto,
lldb.eLanguageTypeObjC,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
objc_bp.GetNumLocations() == 0,
"No ObjC symbol matches")

View File

@ -0,0 +1,5 @@
int
func_from_c ()
{
return 5;
}

View File

@ -0,0 +1,5 @@
int
func_from_cpp()
{
return 10;
}

View File

@ -0,0 +1,11 @@
#include <stdio.h>
extern "C" int func_from_c();
extern int func_from_cpp();
int
main()
{
func_from_c();
func_from_cpp();
return 0;
}

View File

@ -0,0 +1,9 @@
LEVEL = ../../../make
C_SOURCES := main.c
ifneq (,$(findstring icc,$(CC)))
CFLAGS += -debug inline-debug-info
endif
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,198 @@
"""
Test breakpoint commands for a breakpoint ID with multiple locations.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointLocationsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
def test_enable(self):
"""Test breakpoint enable/disable for a breakpoint ID with multiple locations."""
self.build()
self.breakpoint_locations_test()
def test_shadowed_cond_options(self):
"""Test that options set on the breakpoint and location behave correctly."""
self.build()
self.shadowed_bkpt_cond_test()
def test_shadowed_command_options(self):
"""Test that options set on the breakpoint and location behave correctly."""
self.build()
self.shadowed_bkpt_command_test()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set break point at this line.')
def set_breakpoint (self):
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, "Target %s is not valid"%(exe))
# This should create a breakpoint with 3 locations.
bkpt = target.BreakpointCreateByLocation("main.c", self.line)
# The breakpoint list should show 3 locations.
self.assertEqual(bkpt.GetNumLocations(), 3, "Wrong number of locations")
self.expect(
"breakpoint list -f",
"Breakpoint locations shown correctly",
substrs=[
"1: file = 'main.c', line = %d, exact_match = 0, locations = 3" %
self.line],
patterns=[
"where = a.out`func_inlined .+unresolved, hit count = 0",
"where = a.out`main .+\[inlined\].+unresolved, hit count = 0"])
return bkpt
def shadowed_bkpt_cond_test(self):
"""Test that options set on the breakpoint and location behave correctly."""
# Breakpoint option propagation from bkpt to loc used to be done the first time
# a breakpoint location option was specifically set. After that the other options
# on that location would stop tracking the breakpoint. That got fixed, and this test
# makes sure only the option touched is affected.
bkpt = self.set_breakpoint()
bkpt_cond = "1 == 0"
bkpt.SetCondition(bkpt_cond)
self.assertEqual(bkpt.GetCondition(), bkpt_cond,"Successfully set condition")
self.assertTrue(bkpt.location[0].GetCondition() == bkpt.GetCondition(), "Conditions are the same")
# Now set a condition on the locations, make sure that this doesn't effect the bkpt:
bkpt_loc_1_cond = "1 == 1"
bkpt.location[0].SetCondition(bkpt_loc_1_cond)
self.assertEqual(bkpt.location[0].GetCondition(), bkpt_loc_1_cond, "Successfully changed location condition")
self.assertNotEqual(bkpt.GetCondition(), bkpt_loc_1_cond, "Changed location changed Breakpoint condition")
self.assertEqual(bkpt.location[1].GetCondition(), bkpt_cond, "Changed another location's condition")
# Now make sure that setting one options doesn't fix the value of another:
bkpt.SetIgnoreCount(10)
self.assertEqual(bkpt.GetIgnoreCount(), 10, "Set the ignore count successfully")
self.assertEqual(bkpt.location[0].GetIgnoreCount(), 10, "Location doesn't track top-level bkpt.")
# Now make sure resetting the condition to "" resets the tracking:
bkpt.location[0].SetCondition("")
bkpt_new_cond = "1 == 3"
bkpt.SetCondition(bkpt_new_cond)
self.assertEqual(bkpt.location[0].GetCondition(), bkpt_new_cond, "Didn't go back to tracking condition")
def shadowed_bkpt_command_test(self):
"""Test that options set on the breakpoint and location behave correctly."""
# Breakpoint option propagation from bkpt to loc used to be done the first time
# a breakpoint location option was specifically set. After that the other options
# on that location would stop tracking the breakpoint. That got fixed, and this test
# makes sure only the option touched is affected.
bkpt = self.set_breakpoint()
commands = ["AAAAAA", "BBBBBB", "CCCCCC"]
str_list = lldb.SBStringList()
str_list.AppendList(commands, len(commands))
bkpt.SetCommandLineCommands(str_list)
cmd_list = lldb.SBStringList()
bkpt.GetCommandLineCommands(cmd_list)
list_size = str_list.GetSize()
self.assertEqual(cmd_list.GetSize() , list_size, "Added the right number of commands")
for i in range(0,list_size):
self.assertEqual(str_list.GetStringAtIndex(i), cmd_list.GetStringAtIndex(i), "Mismatched commands.")
commands = ["DDDDDD", "EEEEEE", "FFFFFF", "GGGGGG"]
loc_list = lldb.SBStringList()
loc_list.AppendList(commands, len(commands))
bkpt.location[1].SetCommandLineCommands(loc_list)
loc_cmd_list = lldb.SBStringList()
bkpt.location[1].GetCommandLineCommands(loc_cmd_list)
loc_list_size = loc_list.GetSize()
# Check that the location has the right commands:
self.assertEqual(loc_cmd_list.GetSize() , loc_list_size, "Added the right number of commands to location")
for i in range(0,loc_list_size):
self.assertEqual(loc_list.GetStringAtIndex(i), loc_cmd_list.GetStringAtIndex(i), "Mismatched commands.")
# Check that we didn't mess up the breakpoint level commands:
self.assertEqual(cmd_list.GetSize() , list_size, "Added the right number of commands")
for i in range(0,list_size):
self.assertEqual(str_list.GetStringAtIndex(i), cmd_list.GetStringAtIndex(i), "Mismatched commands.")
# And check we didn't mess up another location:
untouched_loc_cmds = lldb.SBStringList()
bkpt.location[0].GetCommandLineCommands(untouched_loc_cmds)
self.assertEqual(untouched_loc_cmds.GetSize() , 0, "Changed the wrong location")
def breakpoint_locations_test(self):
"""Test breakpoint enable/disable for a breakpoint ID with multiple locations."""
self.set_breakpoint()
# The 'breakpoint disable 3.*' command should fail gracefully.
self.expect("breakpoint disable 3.*",
"Disabling an invalid breakpoint should fail gracefully",
error=True,
startstr="error: '3' is not a valid breakpoint ID.")
# The 'breakpoint disable 1.*' command should disable all 3 locations.
self.expect(
"breakpoint disable 1.*",
"All 3 breakpoint locatons disabled correctly",
startstr="3 breakpoints disabled.")
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
# We should not stopped on any breakpoint at all.
self.expect("process status", "No stopping on any disabled breakpoint",
patterns=["^Process [0-9]+ exited with status = 0"])
# The 'breakpoint enable 1.*' command should enable all 3 breakpoints.
self.expect(
"breakpoint enable 1.*",
"All 3 breakpoint locatons enabled correctly",
startstr="3 breakpoints enabled.")
# The 'breakpoint disable 1.1' command should disable 1 location.
self.expect(
"breakpoint disable 1.1",
"1 breakpoint locatons disabled correctly",
startstr="1 breakpoints disabled.")
# Run the program again. We should stop on the two breakpoint
# locations.
self.runCmd("run", RUN_SUCCEEDED)
# Stopped once.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs=["stop reason = breakpoint 1."])
# Continue the program, there should be another stop.
self.runCmd("process continue")
# Stopped again.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs=["stop reason = breakpoint 1."])
# At this point, 1.1 has a hit count of 0 and the other a hit count of
# 1".
self.expect(
"breakpoint list -f",
"The breakpoints should report correct hit counts",
patterns=[
"1\.1: .+ unresolved, hit count = 0 +Options: disabled",
"1\.2: .+ resolved, hit count = 1",
"1\.3: .+ resolved, hit count = 1"])

View File

@ -0,0 +1,43 @@
#include <stdio.h>
#define INLINE inline __attribute__((always_inline))
int
func_not_inlined (void)
{
printf ("Called func_not_inlined.\n");
return 0;
}
INLINE int
func_inlined (void)
{
static int func_inline_call_count = 0;
printf ("Called func_inlined.\n");
++func_inline_call_count;
printf ("Returning func_inlined call count: %d.\n", func_inline_call_count);
return func_inline_call_count; // Set break point at this line.
}
extern int func_inlined (void);
int
main (int argc, char **argv)
{
printf ("Starting...\n");
int (*func_ptr) (void);
func_ptr = func_inlined;
int a = func_inlined();
printf("First call to func_inlined() returns: %d.\n", a);
func_not_inlined ();
func_ptr ();
printf("Last call to func_inlined() returns: %d.\n", func_inlined ());
return 0;
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,365 @@
"""
Test breakpoint names.
"""
from __future__ import print_function
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointNames(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
@add_test_categories(['pyapi'])
def test_setting_names(self):
"""Use Python APIs to test that we can set breakpoint names."""
self.build()
self.setup_target()
self.do_check_names()
def test_illegal_names(self):
"""Use Python APIs to test that we don't allow illegal names."""
self.build()
self.setup_target()
self.do_check_illegal_names()
def test_using_names(self):
"""Use Python APIs to test that operations on names works correctly."""
self.build()
self.setup_target()
self.do_check_using_names()
def test_configuring_names(self):
"""Use Python APIs to test that configuring options on breakpoint names works correctly."""
self.build()
self.make_a_dummy_name()
self.setup_target()
self.do_check_configuring_names()
def test_configuring_permissions_sb(self):
"""Use Python APIs to test that configuring permissions on names works correctly."""
self.build()
self.setup_target()
self.do_check_configuring_permissions_sb()
def test_configuring_permissions_cli(self):
"""Use Python APIs to test that configuring permissions on names works correctly."""
self.build()
self.setup_target()
self.do_check_configuring_permissions_cli()
def setup_target(self):
exe = self.getBuildArtifact("a.out")
# Create a targets we are making breakpoint in and copying to:
self.target = self.dbg.CreateTarget(exe)
self.assertTrue(self.target, VALID_TARGET)
self.main_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "main.c"))
def check_name_in_target(self, bkpt_name):
name_list = lldb.SBStringList()
self.target.GetBreakpointNames(name_list)
found_it = False
for name in name_list:
if name == bkpt_name:
found_it = True
break
self.assertTrue(found_it, "Didn't find the name %s in the target's name list:"%(bkpt_name))
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# These are the settings we're going to be putting into names & breakpoints:
self.bp_name_string = "ABreakpoint"
self.is_one_shot = True
self.ignore_count = 1000
self.condition = "1 == 2"
self.auto_continue = True
self.tid = 0xaaaa
self.tidx = 10
self.thread_name = "Fooey"
self.queue_name = "Blooey"
self.cmd_list = lldb.SBStringList()
self.cmd_list.AppendString("frame var")
self.cmd_list.AppendString("bt")
self.help_string = "I do something interesting"
def do_check_names(self):
"""Use Python APIs to check that we can set & retrieve breakpoint names"""
bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
bkpt_name = "ABreakpoint"
other_bkpt_name = "_AnotherBreakpoint"
# Add a name and make sure we match it:
success = bkpt.AddName(bkpt_name)
self.assertTrue(success, "We couldn't add a legal name to a breakpoint.")
matches = bkpt.MatchesName(bkpt_name)
self.assertTrue(matches, "We didn't match the name we just set")
# Make sure we don't match irrelevant names:
matches = bkpt.MatchesName("NotABreakpoint")
self.assertTrue(not matches, "We matched a name we didn't set.")
# Make sure the name is also in the target:
self.check_name_in_target(bkpt_name)
# Add another name, make sure that works too:
bkpt.AddName(other_bkpt_name)
matches = bkpt.MatchesName(bkpt_name)
self.assertTrue(matches, "Adding a name means we didn't match the name we just set")
self.check_name_in_target(other_bkpt_name)
# Remove the name and make sure we no longer match it:
bkpt.RemoveName(bkpt_name)
matches = bkpt.MatchesName(bkpt_name)
self.assertTrue(not matches,"We still match a name after removing it.")
# Make sure the name list has the remaining name:
name_list = lldb.SBStringList()
bkpt.GetNames(name_list)
num_names = name_list.GetSize()
self.assertTrue(num_names == 1, "Name list has %d items, expected 1."%(num_names))
name = name_list.GetStringAtIndex(0)
self.assertTrue(name == other_bkpt_name, "Remaining name was: %s expected %s."%(name, other_bkpt_name))
def do_check_illegal_names(self):
"""Use Python APIs to check that we reject illegal names."""
bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
bad_names = ["-CantStartWithADash",
"1CantStartWithANumber",
"^CantStartWithNonAlpha",
"CantHave-ADash",
"Cant Have Spaces"]
for bad_name in bad_names:
success = bkpt.AddName(bad_name)
self.assertTrue(not success,"We allowed an illegal name: %s"%(bad_name))
bp_name = lldb.SBBreakpointName(self.target, bad_name)
self.assertFalse(bp_name.IsValid(), "We made a breakpoint name with an illegal name: %s"%(bad_name));
retval =lldb.SBCommandReturnObject()
self.dbg.GetCommandInterpreter().HandleCommand("break set -n whatever -N '%s'"%(bad_name), retval)
self.assertTrue(not retval.Succeeded(), "break set succeeded with: illegal name: %s"%(bad_name))
def do_check_using_names(self):
"""Use Python APIs to check names work in place of breakpoint ID's."""
bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
bkpt_name = "ABreakpoint"
other_bkpt_name= "_AnotherBreakpoint"
# Add a name and make sure we match it:
success = bkpt.AddName(bkpt_name)
self.assertTrue(success, "We couldn't add a legal name to a breakpoint.")
bkpts = lldb.SBBreakpointList(self.target)
self.target.FindBreakpointsByName(bkpt_name, bkpts)
self.assertTrue(bkpts.GetSize() == 1, "One breakpoint matched.")
found_bkpt = bkpts.GetBreakpointAtIndex(0)
self.assertTrue(bkpt.GetID() == found_bkpt.GetID(),"The right breakpoint.")
retval = lldb.SBCommandReturnObject()
self.dbg.GetCommandInterpreter().HandleCommand("break disable %s"%(bkpt_name), retval)
self.assertTrue(retval.Succeeded(), "break disable failed with: %s."%(retval.GetError()))
self.assertTrue(not bkpt.IsEnabled(), "We didn't disable the breakpoint.")
# Also make sure we don't apply commands to non-matching names:
self.dbg.GetCommandInterpreter().HandleCommand("break modify --one-shot 1 %s"%(other_bkpt_name), retval)
self.assertTrue(retval.Succeeded(), "break modify failed with: %s."%(retval.GetError()))
self.assertTrue(not bkpt.IsOneShot(), "We applied one-shot to the wrong breakpoint.")
def check_option_values(self, bp_object):
self.assertEqual(bp_object.IsOneShot(), self.is_one_shot, "IsOneShot")
self.assertEqual(bp_object.GetIgnoreCount(), self.ignore_count, "IgnoreCount")
self.assertEqual(bp_object.GetCondition(), self.condition, "Condition")
self.assertEqual(bp_object.GetAutoContinue(), self.auto_continue, "AutoContinue")
self.assertEqual(bp_object.GetThreadID(), self.tid, "Thread ID")
self.assertEqual(bp_object.GetThreadIndex(), self.tidx, "Thread Index")
self.assertEqual(bp_object.GetThreadName(), self.thread_name, "Thread Name")
self.assertEqual(bp_object.GetQueueName(), self.queue_name, "Queue Name")
set_cmds = lldb.SBStringList()
bp_object.GetCommandLineCommands(set_cmds)
self.assertEqual(set_cmds.GetSize(), self.cmd_list.GetSize(), "Size of command line commands")
for idx in range(0, set_cmds.GetSize()):
self.assertEqual(self.cmd_list.GetStringAtIndex(idx), set_cmds.GetStringAtIndex(idx), "Command %d"%(idx))
def make_a_dummy_name(self):
"This makes a breakpoint name in the dummy target to make sure it gets copied over"
dummy_target = self.dbg.GetDummyTarget()
self.assertTrue(dummy_target.IsValid(), "Dummy target was not valid.")
def cleanup ():
self.dbg.GetDummyTarget().DeleteBreakpointName(self.bp_name_string)
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
# Now find it in the dummy target, and make sure these settings took:
bp_name = lldb.SBBreakpointName(dummy_target, self.bp_name_string)
# Make sure the name is right:
self.assertTrue (bp_name.GetName() == self.bp_name_string, "Wrong bp_name: %s"%(bp_name.GetName()))
bp_name.SetOneShot(self.is_one_shot)
bp_name.SetIgnoreCount(self.ignore_count)
bp_name.SetCondition(self.condition)
bp_name.SetAutoContinue(self.auto_continue)
bp_name.SetThreadID(self.tid)
bp_name.SetThreadIndex(self.tidx)
bp_name.SetThreadName(self.thread_name)
bp_name.SetQueueName(self.queue_name)
bp_name.SetCommandLineCommands(self.cmd_list)
# Now look it up again, and make sure it got set correctly.
bp_name = lldb.SBBreakpointName(dummy_target, self.bp_name_string)
self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name.")
self.check_option_values(bp_name)
def do_check_configuring_names(self):
"""Use Python APIs to check that configuring breakpoint names works correctly."""
other_bp_name_string = "AnotherBreakpointName"
cl_bp_name_string = "CLBreakpointName"
# Now find the version copied in from the dummy target, and make sure these settings took:
bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name.")
self.check_option_values(bp_name)
# Now add this name to a breakpoint, and make sure it gets configured properly
bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
success = bkpt.AddName(self.bp_name_string)
self.assertTrue(success, "Couldn't add this name to the breakpoint")
self.check_option_values(bkpt)
# Now make a name from this breakpoint, and make sure the new name is properly configured:
new_name = lldb.SBBreakpointName(bkpt, other_bp_name_string)
self.assertTrue(new_name.IsValid(), "Couldn't make a valid bp_name from a breakpoint.")
self.check_option_values(bkpt)
# Now change the name's option and make sure it gets propagated to
# the breakpoint:
new_auto_continue = not self.auto_continue
bp_name.SetAutoContinue(new_auto_continue)
self.assertEqual(bp_name.GetAutoContinue(), new_auto_continue, "Couldn't change auto-continue on the name")
self.assertEqual(bkpt.GetAutoContinue(), new_auto_continue, "Option didn't propagate to the breakpoint.")
# Now make this same breakpoint name - but from the command line
cmd_str = "breakpoint name configure %s -o %d -i %d -c '%s' -G %d -t %d -x %d -T '%s' -q '%s' -H '%s'"%(cl_bp_name_string,
self.is_one_shot,
self.ignore_count,
self.condition,
self.auto_continue,
self.tid,
self.tidx,
self.thread_name,
self.queue_name,
self.help_string)
for cmd in self.cmd_list:
cmd_str += " -C '%s'"%(cmd)
self.runCmd(cmd_str, check=True)
# Now look up this name again and check its options:
cl_name = lldb.SBBreakpointName(self.target, cl_bp_name_string)
self.check_option_values(cl_name)
# Also check the help string:
self.assertEqual(self.help_string, cl_name.GetHelpString(), "Help string didn't match")
# Change the name and make sure that works:
new_help = "I do something even more interesting"
cl_name.SetHelpString(new_help)
self.assertEqual(new_help, cl_name.GetHelpString(), "SetHelpString didn't")
# We should have three names now, make sure the target can list them:
name_list = lldb.SBStringList()
self.target.GetBreakpointNames(name_list)
for name_string in [self.bp_name_string, other_bp_name_string, cl_bp_name_string]:
self.assertTrue(name_string in name_list, "Didn't find %s in names"%(name_string))
# Delete the name from the current target. Make sure that works and deletes the
# name from the breakpoint as well:
self.target.DeleteBreakpointName(self.bp_name_string)
name_list.Clear()
self.target.GetBreakpointNames(name_list)
self.assertTrue(self.bp_name_string not in name_list, "Didn't delete %s from a real target"%(self.bp_name_string))
# Also make sure the name got removed from breakpoints holding it:
self.assertFalse(bkpt.MatchesName(self.bp_name_string), "Didn't remove the name from the breakpoint.")
# Test that deleting the name we injected into the dummy target works (there's also a
# cleanup that will do this, but that won't test the result...
dummy_target = self.dbg.GetDummyTarget()
dummy_target.DeleteBreakpointName(self.bp_name_string)
name_list.Clear()
dummy_target.GetBreakpointNames(name_list)
self.assertTrue(self.bp_name_string not in name_list, "Didn't delete %s from the dummy target"%(self.bp_name_string))
# Also make sure the name got removed from breakpoints holding it:
self.assertFalse(bkpt.MatchesName(self.bp_name_string), "Didn't remove the name from the breakpoint.")
def check_permission_results(self, bp_name):
self.assertEqual(bp_name.GetAllowDelete(), False, "Didn't set allow delete.")
protected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
protected_id = protected_bkpt.GetID()
unprotected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
unprotected_id = unprotected_bkpt.GetID()
success = protected_bkpt.AddName(self.bp_name_string)
self.assertTrue(success, "Couldn't add this name to the breakpoint")
self.target.DisableAllBreakpoints()
self.assertEqual(protected_bkpt.IsEnabled(), True, "Didnt' keep breakpoint from being disabled")
self.assertEqual(unprotected_bkpt.IsEnabled(), False, "Protected too many breakpoints from disabling.")
# Try from the command line too:
unprotected_bkpt.SetEnabled(True)
result = lldb.SBCommandReturnObject()
self.dbg.GetCommandInterpreter().HandleCommand("break disable", result)
self.assertTrue(result.Succeeded())
self.assertEqual(protected_bkpt.IsEnabled(), True, "Didnt' keep breakpoint from being disabled")
self.assertEqual(unprotected_bkpt.IsEnabled(), False, "Protected too many breakpoints from disabling.")
self.target.DeleteAllBreakpoints()
bkpt = self.target.FindBreakpointByID(protected_id)
self.assertTrue(bkpt.IsValid(), "Didn't keep the breakpoint from being deleted.")
bkpt = self.target.FindBreakpointByID(unprotected_id)
self.assertFalse(bkpt.IsValid(), "Protected too many breakpoints from deletion.")
# Remake the unprotected breakpoint and try again from the command line:
unprotected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
unprotected_id = unprotected_bkpt.GetID()
self.dbg.GetCommandInterpreter().HandleCommand("break delete -f", result)
self.assertTrue(result.Succeeded())
bkpt = self.target.FindBreakpointByID(protected_id)
self.assertTrue(bkpt.IsValid(), "Didn't keep the breakpoint from being deleted.")
bkpt = self.target.FindBreakpointByID(unprotected_id)
self.assertFalse(bkpt.IsValid(), "Protected too many breakpoints from deletion.")
def do_check_configuring_permissions_sb(self):
bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
# Make a breakpoint name with delete disallowed:
bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name for valid name.")
bp_name.SetAllowDelete(False)
bp_name.SetAllowDisable(False)
bp_name.SetAllowList(False)
self.check_permission_results(bp_name)
def do_check_configuring_permissions_cli(self):
# Make the name with the right options using the command line:
self.runCmd("breakpoint name configure -L 0 -D 0 -A 0 %s"%(self.bp_name_string), check=True)
# Now look up the breakpoint we made, and check that it works.
bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
self.assertTrue(bp_name.IsValid(), "Didn't make a breakpoint name we could find.")
self.check_permission_results(bp_name)

View File

@ -0,0 +1,53 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to demonstrate the capability of the lldb command
// "breakpoint modify -i <count> breakpt-id" to set the number of times a
// breakpoint is skipped before stopping. Ignore count can also be set upon
// breakpoint creation by 'breakpoint set ... -i <count>'.
int a(int);
int b(int);
int c(int);
int a(int val)
{
if (val <= 1)
return b(val);
else if (val >= 3)
return c(val); // a(3) -> c(3) Find the call site of c(3).
return val;
}
int b(int val)
{
return c(val);
}
int c(int val)
{
return val + 3; // Find the line number of function "c" here.
}
int main (int argc, char const *argv[])
{
int A1 = a(1); // a(1) -> b(1) -> c(1)
printf("a(1) returns %d\n", A1);
int B2 = b(2); // b(2) -> c(2) Find the call site of b(2).
printf("b(2) returns %d\n", B2);
int A3 = a(3); // a(3) -> c(3) Find the call site of a(3).
printf("a(3) returns %d\n", A3);
int C1 = c(5); // Find the call site of c in main.
printf ("c(5) returns %d\n", C1);
return 0;
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp foo.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,114 @@
"""
Test breakpoint command for different options.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
class BreakpointOptionsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def test(self):
"""Test breakpoint command for different options."""
self.build()
self.breakpoint_options_test()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.cpp', '// Set break point at this line.')
def breakpoint_options_test(self):
"""Test breakpoint command for different options."""
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# This should create a breakpoint with 1 locations.
lldbutil.run_break_set_by_file_and_line(
self,
"main.cpp",
self.line,
extra_options="-K 1",
num_expected_locations=1)
lldbutil.run_break_set_by_file_and_line(
self,
"main.cpp",
self.line,
extra_options="-K 0",
num_expected_locations=1)
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
# Stopped once.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs=["stop reason = breakpoint 2."])
# Check the list of breakpoint.
self.expect(
"breakpoint list -f",
"Breakpoint locations shown correctly",
substrs=[
"1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" %
self.line,
"2: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" %
self.line])
# Continue the program, there should be another stop.
self.runCmd("process continue")
# Stopped again.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs=["stop reason = breakpoint 1."])
# Continue the program, we should exit.
self.runCmd("process continue")
# We should exit.
self.expect("process status", "Process exited successfully",
patterns=["^Process [0-9]+ exited with status = 0"])
def breakpoint_options_language_test(self):
"""Test breakpoint command for language option."""
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# This should create a breakpoint with 1 locations.
lldbutil.run_break_set_by_symbol(
self,
'ns::func',
sym_exact=False,
extra_options="-L c++",
num_expected_locations=1)
# This should create a breakpoint with 0 locations.
lldbutil.run_break_set_by_symbol(
self,
'ns::func',
sym_exact=False,
extra_options="-L c",
num_expected_locations=0)
self.runCmd("settings set target.language c")
lldbutil.run_break_set_by_symbol(
self, 'ns::func', sym_exact=False, num_expected_locations=0)
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
# Stopped once.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs=["stop reason = breakpoint 1."])
# Continue the program, we should exit.
self.runCmd("process continue")
# We should exit.
self.expect("process status", "Process exited successfully",
patterns=["^Process [0-9]+ exited with status = 0"])

View File

@ -0,0 +1,12 @@
namespace ns {
int func(void)
{
return 0;
}
}
extern "C" int foo(void)
{
return ns::func();
}

View File

@ -0,0 +1,4 @@
extern "C" int foo(void);
int main (int argc, char **argv) { // Set break point at this line.
return foo();
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,50 @@
"""
Test inferior restart when breakpoint is set on running target.
"""
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
class BreakpointSetRestart(TestBase):
mydir = TestBase.compute_mydir(__file__)
BREAKPOINT_TEXT = 'Set a breakpoint here'
@skipIfNetBSD
def test_breakpoint_set_restart(self):
self.build()
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
self.dbg.SetAsync(True)
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
event = lldb.SBEvent()
# Wait for inferior to transition to running state
while self.dbg.GetListener().WaitForEvent(2, event):
if lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateRunning:
break
bp = target.BreakpointCreateBySourceRegex(
self.BREAKPOINT_TEXT, lldb.SBFileSpec('main.cpp'))
self.assertTrue(
bp.IsValid() and bp.GetNumLocations() == 1,
VALID_BREAKPOINT)
while self.dbg.GetListener().WaitForEvent(2, event):
if lldb.SBProcess.GetStateFromEvent(
event) == lldb.eStateStopped and lldb.SBProcess.GetRestartedFromEvent(event):
continue
if lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateRunning:
continue
self.fail(
"Setting a breakpoint generated an unexpected event: %s" %
lldb.SBDebugger.StateAsCString(
lldb.SBProcess.GetStateFromEvent(event)))

View File

@ -0,0 +1,24 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <chrono>
#include <stdio.h>
#include <thread>
int main(int argc, char const *argv[])
{
static bool done = false;
while (!done)
{
std::this_thread::sleep_for(std::chrono::milliseconds{100});
}
printf("Set a breakpoint here.\n");
return 0;
}

View File

@ -0,0 +1,14 @@
LEVEL = ../../../make
CXX_SOURCES := relative.cpp
EXE := CompDirSymLink
include $(LEVEL)/Makefile.rules
# Force relative filenames by copying it into the build directory.
relative.cpp: main.cpp
cp -f $< $@
clean::
rm -rf relative.cpp

View File

@ -0,0 +1,79 @@
"""
Test breakpoint command with AT_comp_dir set to symbolic link.
"""
from __future__ import print_function
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
_EXE_NAME = 'CompDirSymLink' # Must match Makefile
_SRC_FILE = 'relative.cpp'
_COMP_DIR_SYM_LINK_PROP = 'plugin.symbol-file.dwarf.comp-dir-symlink-paths'
class CompDirSymLinkTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number(
os.path.join(self.getSourceDir(), "main.cpp"),
'// Set break point at this line.')
@skipIf(hostoslist=["windows"])
def test_symlink_paths_set(self):
pwd_symlink = self.create_src_symlink()
self.doBuild(pwd_symlink)
self.runCmd(
"settings set %s %s" %
(_COMP_DIR_SYM_LINK_PROP, pwd_symlink))
src_path = self.getBuildArtifact(_SRC_FILE)
lldbutil.run_break_set_by_file_and_line(self, src_path, self.line)
@skipIf(hostoslist=no_match(["linux"]))
def test_symlink_paths_set_procselfcwd(self):
os.chdir(self.getBuildDir())
pwd_symlink = '/proc/self/cwd'
self.doBuild(pwd_symlink)
self.runCmd(
"settings set %s %s" %
(_COMP_DIR_SYM_LINK_PROP, pwd_symlink))
src_path = self.getBuildArtifact(_SRC_FILE)
# /proc/self/cwd points to a realpath form of current directory.
src_path = os.path.realpath(src_path)
lldbutil.run_break_set_by_file_and_line(self, src_path, self.line)
@skipIf(hostoslist=["windows"])
def test_symlink_paths_unset(self):
pwd_symlink = self.create_src_symlink()
self.doBuild(pwd_symlink)
self.runCmd('settings clear ' + _COMP_DIR_SYM_LINK_PROP)
src_path = self.getBuildArtifact(_SRC_FILE)
self.assertRaises(
AssertionError,
lldbutil.run_break_set_by_file_and_line,
self,
src_path,
self.line)
def create_src_symlink(self):
pwd_symlink = self.getBuildArtifact('pwd_symlink')
if os.path.exists(pwd_symlink):
os.unlink(pwd_symlink)
os.symlink(self.getBuildDir(), pwd_symlink)
self.addTearDownHook(lambda: os.remove(pwd_symlink))
return pwd_symlink
def doBuild(self, pwd_symlink):
self.build(None, None, {'PWD': pwd_symlink})
exe = self.getBuildArtifact(_EXE_NAME)
self.runCmd('file ' + exe, CURRENT_EXECUTABLE_SET)

View File

@ -0,0 +1,12 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
int main (int argc, char const *argv[])
{
return 0; // Set break point at this line.
}

View File

@ -0,0 +1,9 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
ifneq (,$(findstring icc,$(CC)))
CXXFLAGS += -debug inline-debug-info
endif
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,104 @@
"""
Test that we handle breakpoints on consecutive instructions correctly.
"""
from __future__ import print_function
import unittest2
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class ConsecutiveBreakpointsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def prepare_test(self):
self.build()
(self.target, self.process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(
self, "Set breakpoint here", lldb.SBFileSpec("main.cpp"))
# Set breakpoint to the next instruction
frame = self.thread.GetFrameAtIndex(0)
address = frame.GetPCAddress()
instructions = self.target.ReadInstructions(address, 2)
self.assertTrue(len(instructions) == 2)
self.bkpt_address = instructions[1].GetAddress()
self.breakpoint2 = self.target.BreakpointCreateByAddress(
self.bkpt_address.GetLoadAddress(self.target))
self.assertTrue(
self.breakpoint2 and self.breakpoint2.GetNumLocations() == 1,
VALID_BREAKPOINT)
def finish_test(self):
# Run the process until termination
self.process.Continue()
self.assertEquals(self.process.GetState(), lldb.eStateExited)
@no_debug_info_test
def test_continue(self):
"""Test that continue stops at the second breakpoint."""
self.prepare_test()
self.process.Continue()
self.assertEquals(self.process.GetState(), lldb.eStateStopped)
# We should be stopped at the second breakpoint
self.thread = lldbutil.get_one_thread_stopped_at_breakpoint(
self.process, self.breakpoint2)
self.assertIsNotNone(
self.thread,
"Expected one thread to be stopped at breakpoint 2")
self.finish_test()
@no_debug_info_test
def test_single_step(self):
"""Test that single step stops at the second breakpoint."""
self.prepare_test()
step_over = False
self.thread.StepInstruction(step_over)
self.assertEquals(self.process.GetState(), lldb.eStateStopped)
self.assertEquals(
self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(
self.target), self.bkpt_address.GetLoadAddress(
self.target))
self.thread = lldbutil.get_one_thread_stopped_at_breakpoint(
self.process, self.breakpoint2)
self.assertIsNotNone(
self.thread,
"Expected one thread to be stopped at breakpoint 2")
self.finish_test()
@no_debug_info_test
def test_single_step_thread_specific(self):
"""Test that single step stops, even though the second breakpoint is not valid."""
self.prepare_test()
# Choose a thread other than the current one. A non-existing thread is
# fine.
thread_index = self.process.GetNumThreads() + 1
self.assertFalse(self.process.GetThreadAtIndex(thread_index).IsValid())
self.breakpoint2.SetThreadIndex(thread_index)
step_over = False
self.thread.StepInstruction(step_over)
self.assertEquals(self.process.GetState(), lldb.eStateStopped)
self.assertEquals(
self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(
self.target), self.bkpt_address.GetLoadAddress(
self.target))
self.assertEquals(
self.thread.GetStopReason(),
lldb.eStopReasonPlanComplete,
"Stop reason should be 'plan complete'")
self.finish_test()

View File

@ -0,0 +1,18 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
int
main(int argc, char const *argv[])
{
int a = 0;
int b = 1;
a = b + 1; // Set breakpoint here
b = a + 1;
return 0;
}

View File

@ -0,0 +1,9 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
ifneq (,$(findstring icc,$(CC)))
CXXFLAGS += -debug inline-debug-info
endif
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,112 @@
"""
Test lldb breakpoint ids.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestCPPBreakpointLocations(TestBase):
mydir = TestBase.compute_mydir(__file__)
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
def test(self):
self.build()
self.breakpoint_id_tests()
def verify_breakpoint_locations(self, target, bp_dict):
name = bp_dict['name']
names = bp_dict['loc_names']
bp = target.BreakpointCreateByName(name)
self.assertEquals(
bp.GetNumLocations(),
len(names),
"Make sure we find the right number of breakpoint locations")
bp_loc_names = list()
for bp_loc in bp:
bp_loc_names.append(bp_loc.GetAddress().GetFunction().GetName())
for name in names:
found = name in bp_loc_names
if not found:
print("Didn't find '%s' in: %s" % (name, bp_loc_names))
self.assertTrue(found, "Make sure we find all required locations")
def breakpoint_id_tests(self):
# Create a target by the debugger.
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
bp_dicts = [
{'name': 'func1', 'loc_names': ['a::c::func1()', 'b::c::func1()']},
{'name': 'func2', 'loc_names': ['a::c::func2()', 'c::d::func2()']},
{'name': 'func3', 'loc_names': ['a::c::func3()', 'b::c::func3()', 'c::d::func3()']},
{'name': 'c::func1', 'loc_names': ['a::c::func1()', 'b::c::func1()']},
{'name': 'c::func2', 'loc_names': ['a::c::func2()']},
{'name': 'c::func3', 'loc_names': ['a::c::func3()', 'b::c::func3()']},
{'name': 'a::c::func1', 'loc_names': ['a::c::func1()']},
{'name': 'b::c::func1', 'loc_names': ['b::c::func1()']},
{'name': 'c::d::func2', 'loc_names': ['c::d::func2()']},
{'name': 'a::c::func1()', 'loc_names': ['a::c::func1()']},
{'name': 'b::c::func1()', 'loc_names': ['b::c::func1()']},
{'name': 'c::d::func2()', 'loc_names': ['c::d::func2()']},
]
for bp_dict in bp_dicts:
self.verify_breakpoint_locations(target, bp_dict)
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
def test_destructors(self):
self.build()
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
# Don't skip prologue, so we can check the breakpoint address more
# easily
self.runCmd("settings set target.skip-prologue false")
try:
names = ['~c', 'c::~c', 'c::~c()']
loc_names = {'a::c::~c()', 'b::c::~c()'}
# TODO: For windows targets we should put windows mangled names
# here
symbols = [
'_ZN1a1cD1Ev',
'_ZN1a1cD2Ev',
'_ZN1b1cD1Ev',
'_ZN1b1cD2Ev']
for name in names:
bp = target.BreakpointCreateByName(name)
bp_loc_names = {bp_loc.GetAddress().GetFunction().GetName()
for bp_loc in bp}
self.assertEquals(
bp_loc_names,
loc_names,
"Breakpoint set on the correct symbol")
bp_addresses = {bp_loc.GetLoadAddress() for bp_loc in bp}
symbol_addresses = set()
for symbol in symbols:
sc_list = target.FindSymbols(symbol, lldb.eSymbolTypeCode)
self.assertEquals(
sc_list.GetSize(), 1, "Found symbol " + symbol)
symbol = sc_list.GetContextAtIndex(0).GetSymbol()
symbol_addresses.add(
symbol.GetStartAddress().GetLoadAddress(target))
self.assertEquals(
symbol_addresses,
bp_addresses,
"Breakpoint set on correct address")
finally:
self.runCmd("settings clear target.skip-prologue")

View File

@ -0,0 +1,82 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include <stdint.h>
namespace a {
class c {
public:
c();
~c();
void func1()
{
puts (__PRETTY_FUNCTION__);
}
void func2()
{
puts (__PRETTY_FUNCTION__);
}
void func3()
{
puts (__PRETTY_FUNCTION__);
}
};
c::c() {}
c::~c() {}
}
namespace b {
class c {
public:
c();
~c();
void func1()
{
puts (__PRETTY_FUNCTION__);
}
void func3()
{
puts (__PRETTY_FUNCTION__);
}
};
c::c() {}
c::~c() {}
}
namespace c {
class d {
public:
d () {}
~d() {}
void func2()
{
puts (__PRETTY_FUNCTION__);
}
void func3()
{
puts (__PRETTY_FUNCTION__);
}
};
}
int main (int argc, char const *argv[])
{
a::c ac;
b::c bc;
c::d cd;
ac.func1();
ac.func2();
ac.func3();
bc.func1();
bc.func3();
cd.func2();
cd.func3();
return 0;
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,52 @@
"""
Test that you can set breakpoint and hit the C++ language exception breakpoint
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestCPPExceptionBreakpoint (TestBase):
mydir = TestBase.compute_mydir(__file__)
my_var = 10
@add_test_categories(['pyapi'])
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24538")
@expectedFailureNetBSD
def test_cpp_exception_breakpoint(self):
"""Test setting and hitting the C++ exception breakpoint."""
self.build()
self.do_cpp_exception_bkpt()
def setUp(self):
TestBase.setUp(self)
self.main_source = "main.c"
self.main_source_spec = lldb.SBFileSpec(self.main_source)
def do_cpp_exception_bkpt(self):
exe = self.getBuildArtifact("a.out")
error = lldb.SBError()
self.target = self.dbg.CreateTarget(exe)
self.assertTrue(self.target, VALID_TARGET)
exception_bkpt = self.target.BreakpointCreateForException(
lldb.eLanguageTypeC_plus_plus, False, True)
self.assertTrue(
exception_bkpt.IsValid(),
"Created exception breakpoint.")
process = self.target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
thread_list = lldbutil.get_threads_stopped_at_breakpoint(
process, exception_bkpt)
self.assertTrue(len(thread_list) == 1,
"One thread stopped at the exception breakpoint.")

View File

@ -0,0 +1,13 @@
#include <exception>
void
throws_int ()
{
throw 5;
}
int
main ()
{
throws_int();
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,58 @@
"""
Test embedded breakpoints, like `asm int 3;` in x86 or or `__debugbreak` on Windows.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class DebugBreakTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIf(archs=no_match(["i386", "i686", "x86_64"]))
@no_debug_info_test
def test_asm_int_3(self):
"""Test that intrinsics like `__debugbreak();` and `asm {"int3"}` are treated like breakpoints."""
self.build()
exe = self.getBuildArtifact("a.out")
# Run the program.
target = self.dbg.CreateTarget(exe)
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
# We've hit the first stop, so grab the frame.
self.assertEqual(process.GetState(), lldb.eStateStopped)
stop_reason = lldb.eStopReasonException if (lldbplatformutil.getPlatform(
) == "windows" or lldbplatformutil.getPlatform() == "macosx") else lldb.eStopReasonSignal
thread = lldbutil.get_stopped_thread(process, stop_reason)
self.assertIsNotNone(
thread, "Unable to find thread stopped at the __debugbreak()")
frame = thread.GetFrameAtIndex(0)
# We should be in funciton 'bar'.
self.assertTrue(frame.IsValid())
function_name = frame.GetFunctionName()
self.assertTrue('bar' in function_name,
"Unexpected function name {}".format(function_name))
# We should be able to evaluate the parameter foo.
value = frame.EvaluateExpression('*foo')
self.assertEqual(value.GetValueAsSigned(), 42)
# The counter should be 1 at the first stop and increase by 2 for each
# subsequent stop.
counter = 1
while counter < 20:
value = frame.EvaluateExpression('count')
self.assertEqual(value.GetValueAsSigned(), counter)
counter += 2
process.Continue()
# The inferior should exit after the last iteration.
self.assertEqual(process.GetState(), lldb.eStateExited)

View File

@ -0,0 +1,29 @@
#ifdef _MSC_VER
#include <intrin.h>
#define BREAKPOINT_INTRINSIC() __debugbreak()
#else
#define BREAKPOINT_INTRINSIC() __asm__ __volatile__ ("int3")
#endif
int
bar(int const *foo)
{
int count = 0, i = 0;
for (; i < 10; ++i)
{
count += 1;
BREAKPOINT_INTRINSIC();
count += 1;
}
return *foo;
}
int
main(int argc, char **argv)
{
int foo = 42;
bar(&foo);
return 0;
}

View File

@ -0,0 +1,9 @@
LEVEL = ../../../make
C_SOURCES := main.c
ifneq (,$(findstring icc,$(CC)))
CFLAGS += -debug inline-debug-info
endif
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,72 @@
"""
Test breakpoint commands set before we have a target
"""
from __future__ import print_function
import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
class BreakpointInDummyTarget (TestBase):
mydir = TestBase.compute_mydir(__file__)
def test(self):
"""Test breakpoint set before we have a target. """
self.build()
self.dummy_breakpoint_test()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', 'Set a breakpoint on this line.')
self.line2 = line_number('main.c', 'Set another on this line.')
def dummy_breakpoint_test(self):
"""Test breakpoint set before we have a target. """
# This should create a breakpoint with 3 locations.
lldbutil.run_break_set_by_file_and_line(
self, "main.c", self.line, num_expected_locations=0)
lldbutil.run_break_set_by_file_and_line(
self, "main.c", self.line2, num_expected_locations=0)
# This is the function to remove breakpoints from the dummy target
# to get a clean slate for the next test case.
def cleanup():
self.runCmd('breakpoint delete -D -f', check=False)
self.runCmd('breakpoint list', check=False)
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# The breakpoint list should show 3 locations.
self.expect(
"breakpoint list -f",
"Breakpoint locations shown correctly",
substrs=[
"1: file = 'main.c', line = %d, exact_match = 0, locations = 1" %
self.line,
"2: file = 'main.c', line = %d, exact_match = 0, locations = 1" %
self.line2])
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
# Stopped once.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs=["stop reason = breakpoint 1."])
# Continue the program, there should be another stop.
self.runCmd("process continue")
# Stopped again.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs=["stop reason = breakpoint 2."])

View File

@ -0,0 +1,11 @@
#include <stdio.h>
int
main (int argc, char **argv)
{
printf ("Set a breakpoint on this line.\n");
return 0; // Set another on this line.
}

View File

@ -0,0 +1,7 @@
LEVEL = ../../../make
DYLIB_NAME := foo
DYLIB_CXX_SOURCES := foo.cpp
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,47 @@
"""
Test that we can hit breakpoints in global constructors
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestBreakpointInGlobalConstructors(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
@expectedFailureNetBSD
def test(self):
self.build()
self.line_foo = line_number('foo.cpp', '// !BR_foo')
self.line_main = line_number('main.cpp', '// !BR_main')
target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
self.assertTrue(target, VALID_TARGET)
env= self.registerSharedLibrariesWithTarget(target, ["foo"])
bp_main = lldbutil.run_break_set_by_file_and_line(
self, 'main.cpp', self.line_main)
bp_foo = lldbutil.run_break_set_by_file_and_line(
self, 'foo.cpp', self.line_foo, num_expected_locations=-2)
process = target.LaunchSimple(
None, env, self.get_process_working_directory())
self.assertIsNotNone(
lldbutil.get_one_thread_stopped_at_breakpoint_id(
self.process(), bp_foo))
self.runCmd("continue")
self.assertIsNotNone(
lldbutil.get_one_thread_stopped_at_breakpoint_id(
self.process(), bp_main))

View File

@ -0,0 +1,7 @@
#include "foo.h"
Foo::Foo() : x(42) {
bool some_code = x == 42; // !BR_foo
}
Foo FooObj;

View File

@ -0,0 +1,11 @@
#ifndef FOO_H
#define FOO_H
struct LLDB_TEST_API Foo {
Foo();
int x;
};
extern LLDB_TEST_API Foo FooObj;
#endif

View File

@ -0,0 +1,14 @@
#include "foo.h"
struct Main {
Main();
int x;
};
Main::Main() : x(47) {
bool some_code = x == 47; // !BR_main
}
Main MainObj;
int main() { return MainObj.x + FooObj.x; }

View File

@ -0,0 +1,6 @@
LEVEL = ../../../../make
ENABLE_THREADS := YES
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,105 @@
"""
Test hardware breakpoints for multiple threads.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
# Hardware breakpoints are supported only by platforms mentioned in oslist.
@skipUnlessPlatform(oslist=['linux'])
class HardwareBreakpointMultiThreadTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
mydir = TestBase.compute_mydir(__file__)
# LLDB supports hardware breakpoints for arm and aarch64 architectures.
@skipIf(archs=no_match(['arm', 'aarch64']))
def test_hw_break_set_delete_multi_thread(self):
self.build()
self.setTearDownCleanup()
self.break_multi_thread('delete')
# LLDB supports hardware breakpoints for arm and aarch64 architectures.
@skipIf(archs=no_match(['arm', 'aarch64']))
def test_hw_break_set_disable_multi_thread(self):
self.build()
self.setTearDownCleanup()
self.break_multi_thread('disable')
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Our simple source filename.
self.source = 'main.cpp'
# Find the line number to break inside main().
self.first_stop = line_number(
self.source, 'Starting thread creation with hardware breakpoint set')
def break_multi_thread(self, removal_type):
"""Test that lldb hardware breakpoints work for multiple threads."""
self.runCmd("file " + self.getBuildArtifact("a.out"),
CURRENT_EXECUTABLE_SET)
# Stop in main before creating any threads.
lldbutil.run_break_set_by_file_and_line(
self, None, self.first_stop, num_expected_locations=1)
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
# We should be stopped again due to the breakpoint.
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs=['stopped',
'stop reason = breakpoint'])
# Now set a hardware breakpoint in thread function.
self.expect("breakpoint set -b hw_break_function --hardware",
substrs=[
'Breakpoint',
'hw_break_function',
'address = 0x'])
# We should stop in hw_break_function function for 4 threads.
count = 0
while count < 2 :
self.runCmd("process continue")
# We should be stopped in hw_break_function
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs=[
'stop reason = breakpoint',
'hw_break_function'])
# Continue the loop and test that we are stopped 4 times.
count += 1
if removal_type == 'delete':
self.runCmd("settings set auto-confirm true")
# Now 'breakpoint delete' should just work fine without confirmation
# prompt from the command interpreter.
self.expect("breakpoint delete",
startstr="All breakpoints removed")
# Restore the original setting of auto-confirm.
self.runCmd("settings clear auto-confirm")
elif removal_type == 'disable':
self.expect("breakpoint disable",
startstr="All breakpoints disabled.")
# Continue. Program should exit without stopping anywhere.
self.runCmd("process continue")
# Process should have stopped and exited with status = 0
self.expect("process status", PROCESS_STOPPED,
patterns=['Process .* exited with status = 0'])

View File

@ -0,0 +1,50 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <chrono>
#include <cstdio>
#include <mutex>
#include <random>
#include <thread>
#define NUM_OF_THREADS 4
std::mutex hw_break_mutex;
void
hw_break_function (uint32_t thread_index) {
printf ("%s called by Thread #%u...\n", __FUNCTION__, thread_index);
}
void
thread_func (uint32_t thread_index) {
printf ("%s (thread index = %u) starting...\n", __FUNCTION__, thread_index);
hw_break_mutex.lock();
hw_break_function(thread_index); // Call hw_break_function
hw_break_mutex.unlock();
}
int main (int argc, char const *argv[])
{
std::thread threads[NUM_OF_THREADS];
printf ("Starting thread creation with hardware breakpoint set...\n");
for (auto &thread : threads)
thread = std::thread{thread_func, std::distance(threads, &thread)};
for (auto &thread : threads)
thread.join();
return 0;
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
CXX_SOURCES := int.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,67 @@
"""
Test that inlined breakpoints (breakpoint set on a file/line included from
another source file) works correctly.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
class InlinedBreakpointsTestCase(TestBase):
"""Bug fixed: rdar://problem/8464339"""
mydir = TestBase.compute_mydir(__file__)
def test_with_run_command(self):
"""Test 'b basic_types.cpp:176' does break (where int.cpp includes basic_type.cpp)."""
self.build()
self.inlined_breakpoints()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside basic_type.cpp.
self.line = line_number(
'basic_type.cpp',
'// Set break point at this line.')
def inlined_breakpoints(self):
"""Test 'b basic_types.cpp:176' does break (where int.cpp includes basic_type.cpp)."""
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# With the inline-breakpoint-strategy, our file+line breakpoint should
# not resolve to a location.
self.runCmd('settings set target.inline-breakpoint-strategy headers')
# Set a breakpoint and fail because it is in an inlined source
# implemenation file
lldbutil.run_break_set_by_file_and_line(
self, "basic_type.cpp", self.line, num_expected_locations=0)
# Now enable breakpoints in implementation files and see the breakpoint
# set succeed
self.runCmd('settings set target.inline-breakpoint-strategy always')
# And add hooks to restore the settings during tearDown().
self.addTearDownHook(lambda: self.runCmd(
"settings set target.inline-breakpoint-strategy always"))
lldbutil.run_break_set_by_file_and_line(
self,
"basic_type.cpp",
self.line,
num_expected_locations=1,
loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
# The stop reason of the thread should be breakpoint.
# And it should break at basic_type.cpp:176.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs=['stopped',
'stop reason = breakpoint',
'basic_type.cpp:%d' % self.line])

View File

@ -0,0 +1,178 @@
// This file must have the following defined before it is included:
// T defined to the type to test (int, float, etc)
// T_CSTR a C string representation of the type T ("int", "float")
// T_VALUE_1 defined to a valid initializer value for TEST_TYPE (7 for int, 2.0 for float)
// T_VALUE_2, T_VALUE_3, T_VALUE_4 defined to a valid initializer value for TEST_TYPE that is different from TEST_VALUE_1
// T_PRINTF_FORMAT defined if T can be printed with printf
//
// An example for integers is below
#if 0
#define T int
#define T_CSTR "int"
#define T_VALUE_1 11001110
#define T_VALUE_2 22002220
#define T_VALUE_3 33003330
#define T_VALUE_4 44044440
#define T_PRINTF_FORMAT "%i"
#include "basic_type.cpp"
#endif
#include <cstdint>
#include <cstdio>
class a_class
{
public:
a_class (const T& a, const T& b) :
m_a (a),
m_b (b)
{
}
~a_class ()
{
}
const T&
get_a()
{
return m_a;
}
void
set_a (const T& a)
{
m_a = a;
}
const T&
get_b()
{
return m_b;
}
void
set_b (const T& b)
{
m_b = b;
}
protected:
T m_a;
T m_b;
};
typedef struct a_struct_tag {
T a;
T b;
} a_struct_t;
typedef union a_union_zero_tag {
T a;
double a_double;
} a_union_zero_t;
typedef struct a_union_nonzero_tag {
double a_double;
a_union_zero_t u;
} a_union_nonzero_t;
void Puts(char const *msg)
{
std::puts(msg);
}
int
main (int argc, char const *argv[])
{
T a = T_VALUE_1;
T* a_ptr = &a;
T& a_ref = a;
T a_array_bounded[2] = { T_VALUE_1, T_VALUE_2 };
T a_array_unbounded[] = { T_VALUE_1, T_VALUE_2 };
a_class a_class_instance (T_VALUE_1, T_VALUE_2);
a_class *a_class_ptr = &a_class_instance;
a_class &a_class_ref = a_class_instance;
a_struct_t a_struct = { T_VALUE_1, T_VALUE_2 };
a_struct_t *a_struct_ptr = &a_struct;
a_struct_t &a_struct_ref = a_struct;
// Create a union with type T at offset zero
a_union_zero_t a_union_zero;
a_union_zero.a = T_VALUE_1;
a_union_zero_t *a_union_zero_ptr = &a_union_zero;
a_union_zero_t &a_union_zero_ref = a_union_zero;
// Create a union with type T at a non-zero offset
a_union_nonzero_t a_union_nonzero;
a_union_nonzero.u.a = T_VALUE_1;
a_union_nonzero_t *a_union_nonzero_ptr = &a_union_nonzero;
a_union_nonzero_t &a_union_nonzero_ref = a_union_nonzero;
a_struct_t a_struct_array_bounded[2] = {{ T_VALUE_1, T_VALUE_2 }, { T_VALUE_3, T_VALUE_4 }};
a_struct_t a_struct_array_unbounded[] = {{ T_VALUE_1, T_VALUE_2 }, { T_VALUE_3, T_VALUE_4 }};
a_union_zero_t a_union_zero_array_bounded[2];
a_union_zero_array_bounded[0].a = T_VALUE_1;
a_union_zero_array_bounded[1].a = T_VALUE_2;
a_union_zero_t a_union_zero_array_unbounded[] = {{ T_VALUE_1 }, { T_VALUE_2 }};
#ifdef T_PRINTF_FORMAT
std::printf ("%s: a = '" T_PRINTF_FORMAT "'\n", T_CSTR, a);
std::printf ("%s*: %p => *a_ptr = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_ptr, *a_ptr);
std::printf ("%s&: @%p => a_ref = '" T_PRINTF_FORMAT "'\n", T_CSTR, &a_ref, a_ref);
std::printf ("%s[2]: a_array_bounded[0] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_bounded[0]);
std::printf ("%s[2]: a_array_bounded[1] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_bounded[1]);
std::printf ("%s[]: a_array_unbounded[0] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_unbounded[0]);
std::printf ("%s[]: a_array_unbounded[1] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_unbounded[1]);
std::printf ("(a_class) a_class_instance.m_a = '" T_PRINTF_FORMAT "'\n", a_class_instance.get_a());
std::printf ("(a_class) a_class_instance.m_b = '" T_PRINTF_FORMAT "'\n", a_class_instance.get_b());
std::printf ("(a_class*) a_class_ptr = %p, a_class_ptr->m_a = '" T_PRINTF_FORMAT "'\n", a_class_ptr, a_class_ptr->get_a());
std::printf ("(a_class*) a_class_ptr = %p, a_class_ptr->m_b = '" T_PRINTF_FORMAT "'\n", a_class_ptr, a_class_ptr->get_b());
std::printf ("(a_class&) a_class_ref = %p, a_class_ref.m_a = '" T_PRINTF_FORMAT "'\n", &a_class_ref, a_class_ref.get_a());
std::printf ("(a_class&) a_class_ref = %p, a_class_ref.m_b = '" T_PRINTF_FORMAT "'\n", &a_class_ref, a_class_ref.get_b());
std::printf ("(a_struct_t) a_struct.a = '" T_PRINTF_FORMAT "'\n", a_struct.a);
std::printf ("(a_struct_t) a_struct.b = '" T_PRINTF_FORMAT "'\n", a_struct.b);
std::printf ("(a_struct_t*) a_struct_ptr = %p, a_struct_ptr->a = '" T_PRINTF_FORMAT "'\n", a_struct_ptr, a_struct_ptr->a);
std::printf ("(a_struct_t*) a_struct_ptr = %p, a_struct_ptr->b = '" T_PRINTF_FORMAT "'\n", a_struct_ptr, a_struct_ptr->b);
std::printf ("(a_struct_t&) a_struct_ref = %p, a_struct_ref.a = '" T_PRINTF_FORMAT "'\n", &a_struct_ref, a_struct_ref.a);
std::printf ("(a_struct_t&) a_struct_ref = %p, a_struct_ref.b = '" T_PRINTF_FORMAT "'\n", &a_struct_ref, a_struct_ref.b);
std::printf ("(a_union_zero_t) a_union_zero.a = '" T_PRINTF_FORMAT "'\n", a_union_zero.a);
std::printf ("(a_union_zero_t*) a_union_zero_ptr = %p, a_union_zero_ptr->a = '" T_PRINTF_FORMAT "'\n", a_union_zero_ptr, a_union_zero_ptr->a);
std::printf ("(a_union_zero_t&) a_union_zero_ref = %p, a_union_zero_ref.a = '" T_PRINTF_FORMAT "'\n", &a_union_zero_ref, a_union_zero_ref.a);
std::printf ("(a_union_nonzero_t) a_union_nonzero.u.a = '" T_PRINTF_FORMAT "'\n", a_union_nonzero.u.a);
std::printf ("(a_union_nonzero_t*) a_union_nonzero_ptr = %p, a_union_nonzero_ptr->u.a = '" T_PRINTF_FORMAT "'\n", a_union_nonzero_ptr, a_union_nonzero_ptr->u.a);
std::printf ("(a_union_nonzero_t&) a_union_nonzero_ref = %p, a_union_nonzero_ref.u.a = '" T_PRINTF_FORMAT "'\n", &a_union_nonzero_ref, a_union_nonzero_ref.u.a);
std::printf ("(a_struct_t[2]) a_struct_array_bounded[0].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[0].a);
std::printf ("(a_struct_t[2]) a_struct_array_bounded[0].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[0].b);
std::printf ("(a_struct_t[2]) a_struct_array_bounded[1].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[1].a);
std::printf ("(a_struct_t[2]) a_struct_array_bounded[1].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[1].b);
std::printf ("(a_struct_t[]) a_struct_array_unbounded[0].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[0].a);
std::printf ("(a_struct_t[]) a_struct_array_unbounded[0].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[0].b);
std::printf ("(a_struct_t[]) a_struct_array_unbounded[1].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[1].a);
std::printf ("(a_struct_t[]) a_struct_array_unbounded[1].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[1].b);
std::printf ("(a_union_zero_t[2]) a_union_zero_array_bounded[0].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_bounded[0].a);
std::printf ("(a_union_zero_t[2]) a_union_zero_array_bounded[1].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_bounded[1].a);
std::printf ("(a_union_zero_t[]) a_union_zero_array_unbounded[0].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_unbounded[0].a);
std::printf ("(a_union_zero_t[]) a_union_zero_array_unbounded[1].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_unbounded[1].a);
#endif
Puts("About to exit, break here to check values..."); // Set break point at this line.
return 0;
}

View File

@ -0,0 +1,9 @@
#define T int
#define T_CSTR "int"
#define T_VALUE_1 11001110
#define T_VALUE_2 22002220
#define T_VALUE_3 33003330
#define T_VALUE_4 44004440
#define T_PRINTF_FORMAT "%i"
#include "basic_type.cpp"

View File

@ -0,0 +1,7 @@
LEVEL = ../../../make
DYLIB_NAME := foo
DYLIB_CXX_SOURCES := foo.cpp
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,69 @@
from __future__ import print_function
import unittest2
import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
class TestMoveNearest(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line1 = line_number('foo.h', '// !BR1')
self.line2 = line_number('foo.h', '// !BR2')
self.line_between = line_number('main.cpp', "// BR_Between")
print("BR_Between found at", self.line_between)
self.line_main = line_number('main.cpp', '// !BR_main')
def test(self):
"""Test target.move-to-nearest logic"""
self.build()
target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
self.assertTrue(target, VALID_TARGET)
lldbutil.run_break_set_by_symbol(self, 'main', sym_exact=True)
environment = self.registerSharedLibrariesWithTarget(target, ["foo"])
process = target.LaunchSimple(None, environment, self.get_process_working_directory())
self.assertEquals(process.GetState(), lldb.eStateStopped)
# Regardless of the -m value the breakpoint should have exactly one
# location on the foo functions
self.runCmd("settings set target.move-to-nearest-code true")
lldbutil.run_break_set_by_file_and_line(self, 'foo.h', self.line1,
loc_exact=True, extra_options="-m 1")
lldbutil.run_break_set_by_file_and_line(self, 'foo.h', self.line2,
loc_exact=True, extra_options="-m 1")
self.runCmd("settings set target.move-to-nearest-code false")
lldbutil.run_break_set_by_file_and_line(self, 'foo.h', self.line1,
loc_exact=True, extra_options="-m 0")
lldbutil.run_break_set_by_file_and_line(self, 'foo.h', self.line2,
loc_exact=True, extra_options="-m 0")
# Make sure we set a breakpoint in main with -m 1 for various lines in
# the function declaration
# "int"
lldbutil.run_break_set_by_file_and_line(self, 'main.cpp',
self.line_main-1, extra_options="-m 1")
# "main()"
lldbutil.run_break_set_by_file_and_line(self, 'main.cpp',
self.line_main, extra_options="-m 1")
# "{"
lldbutil.run_break_set_by_file_and_line(self, 'main.cpp',
self.line_main+1, extra_options="-m 1")
# "return .."
lldbutil.run_break_set_by_file_and_line(self, 'main.cpp',
self.line_main+2, extra_options="-m 1")
# Make sure we don't put move the breakpoint if it is set between two functions:
lldbutil.run_break_set_by_file_and_line(self, 'main.cpp',
self.line_between, extra_options="-m 1", num_expected_locations=0)

View File

@ -0,0 +1,3 @@
#include "foo.h"
int call_foo1() { return foo1(); }

View File

@ -0,0 +1,5 @@
inline int foo1() { return 1; } // !BR1
inline int foo2() { return 2; } // !BR2
LLDB_TEST_API extern int call_foo1();

View File

@ -0,0 +1,9 @@
#include "foo.h"
int call_foo2() { return foo2(); }
// BR_Between
int
main() // !BR_main
{
return call_foo1() + call_foo2();
}

View File

@ -0,0 +1,7 @@
LEVEL = ../../../make
OBJC_SOURCES := main.m
include $(LEVEL)/Makefile.rules
LDFLAGS += -framework Foundation

View File

@ -0,0 +1,130 @@
"""
Test that objective-c constant strings are generated correctly by the expression
parser.
"""
from __future__ import print_function
import shutil
import subprocess
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
@skipUnlessDarwin
class TestObjCBreakpoints(TestBase):
mydir = TestBase.compute_mydir(__file__)
def test_break(self):
"""Test setting Objective-C specific breakpoints (DWARF in .o files)."""
self.build()
self.setTearDownCleanup()
self.check_objc_breakpoints(False)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.main_source = "main.m"
self.line = line_number(self.main_source, '// Set breakpoint here')
def check_category_breakpoints(self):
name_bp = self.target.BreakpointCreateByName("myCategoryFunction")
selector_bp = self.target.BreakpointCreateByName(
"myCategoryFunction",
lldb.eFunctionNameTypeSelector,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
name_bp.GetNumLocations() == selector_bp.GetNumLocations(),
'Make sure setting a breakpoint by name "myCategoryFunction" sets a breakpoint even though it is in a category')
for bp_loc in selector_bp:
function_name = bp_loc.GetAddress().GetSymbol().GetName()
self.assertTrue(
" myCategoryFunction]" in function_name,
'Make sure all function names have " myCategoryFunction]" in their names')
category_bp = self.target.BreakpointCreateByName(
"-[MyClass(MyCategory) myCategoryFunction]")
stripped_bp = self.target.BreakpointCreateByName(
"-[MyClass myCategoryFunction]")
stripped2_bp = self.target.BreakpointCreateByName(
"[MyClass myCategoryFunction]")
self.assertTrue(
category_bp.GetNumLocations() == 1,
"Make sure we can set a breakpoint using a full objective C function name with the category included (-[MyClass(MyCategory) myCategoryFunction])")
self.assertTrue(
stripped_bp.GetNumLocations() == 1,
"Make sure we can set a breakpoint using a full objective C function name without the category included (-[MyClass myCategoryFunction])")
self.assertTrue(
stripped2_bp.GetNumLocations() == 1,
"Make sure we can set a breakpoint using a full objective C function name without the category included ([MyClass myCategoryFunction])")
def check_objc_breakpoints(self, have_dsym):
"""Test constant string generation amd comparison by the expression parser."""
# Set debugger into synchronous mode
self.dbg.SetAsync(False)
# Create a target by the debugger.
exe = self.getBuildArtifact("a.out")
self.target = self.dbg.CreateTarget(exe)
self.assertTrue(self.target, VALID_TARGET)
#----------------------------------------------------------------------
# Set breakpoints on all selectors whose name is "count". This should
# catch breakpoints that are both C functions _and_ anything whose
# selector is "count" because just looking at "count" we can't tell
# definitively if the name is a selector or a C function
#----------------------------------------------------------------------
name_bp = self.target.BreakpointCreateByName("count")
selector_bp = self.target.BreakpointCreateByName(
"count",
lldb.eFunctionNameTypeSelector,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
name_bp.GetNumLocations() >= selector_bp.GetNumLocations(),
'Make sure we get at least the same amount of breakpoints if not more when setting by name "count"')
self.assertTrue(
selector_bp.GetNumLocations() > 50,
'Make sure we find a lot of "count" selectors') # There are 93 on the latest MacOSX
for bp_loc in selector_bp:
function_name = bp_loc.GetAddress().GetSymbol().GetName()
self.assertTrue(
" count]" in function_name,
'Make sure all function names have " count]" in their names')
#----------------------------------------------------------------------
# Set breakpoints on all selectors whose name is "isEqual:". This should
# catch breakpoints that are only ObjC selectors because no C function
# can end with a :
#----------------------------------------------------------------------
name_bp = self.target.BreakpointCreateByName("isEqual:")
selector_bp = self.target.BreakpointCreateByName(
"isEqual:",
lldb.eFunctionNameTypeSelector,
lldb.SBFileSpecList(),
lldb.SBFileSpecList())
self.assertTrue(
name_bp.GetNumLocations() == selector_bp.GetNumLocations(),
'Make sure setting a breakpoint by name "isEqual:" only sets selector breakpoints')
for bp_loc in selector_bp:
function_name = bp_loc.GetAddress().GetSymbol().GetName()
self.assertTrue(
" isEqual:]" in function_name,
'Make sure all function names have " isEqual:]" in their names')
self.check_category_breakpoints()
if have_dsym:
shutil.rmtree(exe + ".dSYM")
self.assertTrue(subprocess.call(
['/usr/bin/strip', '-Sx', exe]) == 0, 'stripping dylib succeeded')
# Check breakpoints again, this time using the symbol table only
self.check_category_breakpoints()

View File

@ -0,0 +1,98 @@
#import <Foundation/Foundation.h>
#include <unistd.h>
@interface MyClass : NSObject
@end
@implementation MyClass : NSObject
@end
@implementation MyClass (MyCategory)
- (void) myCategoryFunction {
NSLog (@"myCategoryFunction");
}
@end
int
Test_Selector ()
{
SEL sel = @selector(length);
printf("sel = %p\n", sel);
// Expressions to test here for selector:
// expression (char *)sel_getName(sel)
// The expression above should return "sel" as it should be just
// a uniqued C string pointer. We were seeing the result pointer being
// truncated with recent LLDBs.
return 0; // Break here for selector: tests
}
int
Test_NSString (const char *program)
{
NSString *str = [NSString stringWithFormat:@"Hello from '%s'", program];
NSLog(@"NSString instance: %@", str);
printf("str = '%s'\n", [str cStringUsingEncoding: [NSString defaultCStringEncoding]]);
printf("[str length] = %zu\n", (size_t)[str length]);
printf("[str description] = %s\n", [[str description] UTF8String]);
id str_id = str;
// Expressions to test here for NSString:
// expression (char *)sel_getName(sel)
// expression [str length]
// expression [str_id length]
// expression [str description]
// expression [str_id description]
// expression str.length
// expression str.description
// expression str = @"new"
// expression str = [NSString stringWithFormat: @"%cew", 'N']
return 0; // Break here for NSString tests
}
NSString *my_global_str = NULL;
int
Test_NSArray ()
{
NSMutableArray *nil_mutable_array = nil;
NSArray *array1 = [NSArray arrayWithObjects: @"array1 object1", @"array1 object2", @"array1 object3", nil];
NSArray *array2 = [NSArray arrayWithObjects: array1, @"array2 object2", @"array2 object3", nil];
// Expressions to test here for NSArray:
// expression [nil_mutable_array count]
// expression [array1 count]
// expression array1.count
// expression [array2 count]
// expression array2.count
id obj;
// After each object at index call, use expression and validate object
obj = [array1 objectAtIndex: 0]; // Break here for NSArray tests
obj = [array1 objectAtIndex: 1];
obj = [array1 objectAtIndex: 2];
obj = [array2 objectAtIndex: 0];
obj = [array2 objectAtIndex: 1];
obj = [array2 objectAtIndex: 2];
NSUInteger count = [nil_mutable_array count];
return 0;
}
int main (int argc, char const *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Test_Selector(); // Set breakpoint here
Test_NSArray ();
Test_NSString (argv[0]);
MyClass *my_class = [[MyClass alloc] init];
[my_class myCategoryFunction];
printf("sizeof(id) = %zu\n", sizeof(id));
printf("sizeof(Class) = %zu\n", sizeof(Class));
printf("sizeof(SEL) = %zu\n", sizeof(SEL));
[pool release];
return 0;
}

View File

@ -0,0 +1,9 @@
LEVEL = ../../../make
C_SOURCES := main.c
ifneq (,$(findstring icc,$(CC)))
CFLAGS += -debug inline-debug-info
endif
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,103 @@
"""
Test require hardware breakpoints.
"""
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointLocationsTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
mydir = TestBase.compute_mydir(__file__)
def test_breakpoint(self):
"""Test regular breakpoints when hardware breakpoints are required."""
self.build()
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.runCmd("settings set target.require-hardware-breakpoint true")
breakpoint = target.BreakpointCreateByLocation("main.c", 1)
self.assertTrue(breakpoint.IsHardware())
@skipIfWindows
def test_step_range(self):
"""Test stepping when hardware breakpoints are required."""
self.build()
_, _, thread, _ = lldbutil.run_to_line_breakpoint(
self, lldb.SBFileSpec("main.c"), 1)
self.runCmd("settings set target.require-hardware-breakpoint true")
# Ensure we fail in the interpreter.
self.expect("thread step-in")
self.expect("thread step-in", error=True)
# Ensure we fail when stepping through the API.
error = lldb.SBError()
thread.StepInto('', 4, error)
self.assertTrue(error.Fail())
self.assertTrue("Could not create hardware breakpoint for thread plan"
in error.GetCString())
@skipIfWindows
def test_step_out(self):
"""Test stepping out when hardware breakpoints are required."""
self.build()
_, _, thread, _ = lldbutil.run_to_line_breakpoint(
self, lldb.SBFileSpec("main.c"), 1)
self.runCmd("settings set target.require-hardware-breakpoint true")
# Ensure this fails in the command interpreter.
self.expect("thread step-out", error=True)
# Ensure we fail when stepping through the API.
error = lldb.SBError()
thread.StepOut(error)
self.assertTrue(error.Fail())
self.assertTrue("Could not create hardware breakpoint for thread plan"
in error.GetCString())
@skipIfWindows
def test_step_over(self):
"""Test stepping over when hardware breakpoints are required."""
self.build()
_, _, thread, _ = lldbutil.run_to_line_breakpoint(
self, lldb.SBFileSpec("main.c"), 7)
self.runCmd("settings set target.require-hardware-breakpoint true")
# Step over doesn't fail immediately but fails later on.
self.expect(
"thread step-over",
error=True,
substrs=[
'error: Could not create hardware breakpoint for thread plan.'
])
@skipIfWindows
def test_step_until(self):
"""Test stepping until when hardware breakpoints are required."""
self.build()
_, _, thread, _ = lldbutil.run_to_line_breakpoint(
self, lldb.SBFileSpec("main.c"), 7)
self.runCmd("settings set target.require-hardware-breakpoint true")
self.expect("thread until 5", error=True)
# Ensure we fail when stepping through the API.
error = thread.StepOverUntil(lldb.SBFrame(), lldb.SBFileSpec(), 5)
self.assertTrue(error.Fail())
self.assertTrue("Could not create hardware breakpoint for thread plan"
in error.GetCString())

View File

@ -0,0 +1,9 @@
int break_on_me() {
int i = 10;
i++;
return i;
}
int main() {
return break_on_me();
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS += -std=c99
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,197 @@
"""
Test setting breakpoints using a scripted resolver
"""
from __future__ import print_function
import os
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
class TestScriptedResolver(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
def test_scripted_resolver(self):
"""Use a scripted resolver to set a by symbol name breakpoint"""
self.build()
self.do_test()
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
def test_search_depths(self):
""" Make sure we are called at the right depths depending on what we return
from __get_depth__"""
self.build()
self.do_test_depths()
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
def test_command_line(self):
""" Make sure we are called at the right depths depending on what we return
from __get_depth__"""
self.build()
self.do_test_cli()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
def make_target_and_import(self):
target = lldbutil.run_to_breakpoint_make_target(self)
interp = self.dbg.GetCommandInterpreter()
error = lldb.SBError()
script_name = os.path.join(self.getSourceDir(), "resolver.py")
source_name = os.path.join(self.getSourceDir(), "main.c")
command = "command script import " + script_name
result = lldb.SBCommandReturnObject()
interp.HandleCommand(command, result)
self.assertTrue(result.Succeeded(), "com scr imp failed: %s"%(result.GetError()))
return target
def make_extra_args(self):
json_string = '{"symbol":"break_on_me", "test1": "value1"}'
json_stream = lldb.SBStream()
json_stream.Print(json_string)
extra_args = lldb.SBStructuredData()
error = extra_args.SetFromJSON(json_stream)
self.assertTrue(error.Success(), "Error making SBStructuredData: %s"%(error.GetCString()))
return extra_args
def do_test(self):
"""This reads in a python file and sets a breakpoint using it."""
target = self.make_target_and_import()
extra_args = self.make_extra_args()
file_list = lldb.SBFileSpecList()
module_list = lldb.SBFileSpecList()
# Make breakpoints with this resolver using different filters, first ones that will take:
right = []
# one with no file or module spec - this one should fire:
right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))
# one with the right source file and no module - should also fire:
file_list.Append(lldb.SBFileSpec("main.c"))
right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))
# Make sure the help text shows up in the "break list" output:
self.expect("break list", substrs=["I am a python breakpoint resolver"], msg="Help is listed in break list")
# one with the right source file and right module - should also fire:
module_list.Append(lldb.SBFileSpec("a.out"))
right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))
# And one with no source file but the right module:
file_list.Clear()
right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))
# Make sure these all got locations:
for i in range (0, len(right)):
self.assertTrue(right[i].GetNumLocations() >= 1, "Breakpoint %d has no locations."%(i))
# Now some ones that won't take:
module_list.Clear()
file_list.Clear()
wrong = []
# one with the wrong module - should not fire:
module_list.Append(lldb.SBFileSpec("noSuchModule"))
wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))
# one with the wrong file - also should not fire:
file_list.Clear()
module_list.Clear()
file_list.Append(lldb.SBFileSpec("noFileOfThisName.xxx"))
wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))
# Now make sure the CU level iteration obeys the file filters:
file_list.Clear()
module_list.Clear()
file_list.Append(lldb.SBFileSpec("no_such_file.xxx"))
wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list))
# And the Module filters:
file_list.Clear()
module_list.Clear()
module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib"))
wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list))
# Now make sure the Function level iteration obeys the file filters:
file_list.Clear()
module_list.Clear()
file_list.Append(lldb.SBFileSpec("no_such_file.xxx"))
wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list))
# And the Module filters:
file_list.Clear()
module_list.Clear()
module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib"))
wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list))
# Make sure these didn't get locations:
for i in range(0, len(wrong)):
self.assertEqual(wrong[i].GetNumLocations(), 0, "Breakpoint %d has locations."%(i))
# Now run to main and ensure we hit the breakpoints we should have:
lldbutil.run_to_breakpoint_do_run(self, target, right[0])
# Test the hit counts:
for i in range(0, len(right)):
self.assertEqual(right[i].GetHitCount(), 1, "Breakpoint %d has the wrong hit count"%(i))
for i in range(0, len(wrong)):
self.assertEqual(wrong[i].GetHitCount(), 0, "Breakpoint %d has the wrong hit count"%(i))
def do_test_depths(self):
"""This test uses a class variable in resolver.Resolver which gets set to 1 if we saw
compile unit and 2 if we only saw modules. If the search depth is module, you get passed just
the modules with no comp_unit. If the depth is comp_unit you get comp_units. So we can use
this to test that our callback gets called at the right depth."""
target = self.make_target_and_import()
extra_args = self.make_extra_args()
file_list = lldb.SBFileSpecList()
module_list = lldb.SBFileSpecList()
module_list.Append(lldb.SBFileSpec("a.out"))
# Make a breakpoint that has no __get_depth__, check that that is converted to eSearchDepthModule:
bkpt = target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)
self.assertTrue(bkpt.GetNumLocations() > 0, "Resolver got no locations.")
self.expect("script print(resolver.Resolver.got_files)", substrs=["2"], msg="Was only passed modules")
# Make a breakpoint that asks for modules, check that we didn't get any files:
bkpt = target.BreakpointCreateFromScript("resolver.ResolverModuleDepth", extra_args, module_list, file_list)
self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverModuleDepth got no locations.")
self.expect("script print(resolver.Resolver.got_files)", substrs=["2"], msg="Was only passed modules")
# Make a breakpoint that asks for compile units, check that we didn't get any files:
bkpt = target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list)
self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverCUDepth got no locations.")
self.expect("script print(resolver.Resolver.got_files)", substrs=["1"], msg="Was passed compile units")
# Make a breakpoint that returns a bad value - we should convert that to "modules" so check that:
bkpt = target.BreakpointCreateFromScript("resolver.ResolverBadDepth", extra_args, module_list, file_list)
self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverBadDepth got no locations.")
self.expect("script print(resolver.Resolver.got_files)", substrs=["2"], msg="Was only passed modules")
# Make a breakpoint that searches at function depth:
bkpt = target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list)
self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverFuncDepth got no locations.")
self.expect("script print(resolver.Resolver.got_files)", substrs=["3"], msg="Was only passed modules")
self.expect("script print(resolver.Resolver.func_list)", substrs=["break_on_me", "main", "test_func"], msg="Saw all the functions")
def do_test_cli(self):
target = self.make_target_and_import()
lldbutil.run_break_set_by_script(self, "resolver.Resolver", extra_options="-k symbol -v break_on_me")

View File

@ -0,0 +1,21 @@
#include <stdio.h>
int
test_func()
{
return printf("I am a test function.");
}
void
break_on_me()
{
printf("I was called.\n");
}
int
main()
{
break_on_me();
test_func();
return 0;
}

View File

@ -0,0 +1,54 @@
import lldb
class Resolver:
got_files = 0
func_list = []
def __init__(self, bkpt, extra_args, dict):
self.bkpt = bkpt
self.extra_args = extra_args
Resolver.func_list = []
Resolver.got_files = 0
def __callback__(self, sym_ctx):
sym_name = "not_a_real_function_name"
sym_item = self.extra_args.GetValueForKey("symbol")
if sym_item.IsValid():
sym_name = sym_item.GetStringValue(1000)
if sym_ctx.compile_unit.IsValid():
Resolver.got_files = 1
else:
Resolver.got_files = 2
if sym_ctx.function.IsValid():
Resolver.got_files = 3
func_name = sym_ctx.function.GetName()
Resolver.func_list.append(func_name)
if sym_name == func_name:
self.bkpt.AddLocation(sym_ctx.function.GetStartAddress())
return
if sym_ctx.module.IsValid():
sym = sym_ctx.module.FindSymbol(sym_name, lldb.eSymbolTypeCode)
if sym.IsValid():
self.bkpt.AddLocation(sym.GetStartAddress())
def get_short_help(self):
return "I am a python breakpoint resolver"
class ResolverModuleDepth(Resolver):
def __get_depth__ (self):
return lldb.eSearchDepthModule
class ResolverCUDepth(Resolver):
def __get_depth__ (self):
return lldb.eSearchDepthCompUnit
class ResolverFuncDepth(Resolver):
def __get_depth__ (self):
return lldb.eSearchDepthFunction
class ResolverBadDepth(Resolver):
def __get_depth__ (self):
return lldb.kLastSearchDepthKind + 1

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,291 @@
"""
Test breakpoint serialization.
"""
from __future__ import print_function
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointSerialization(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
@add_test_categories(['pyapi'])
def test_resolvers(self):
"""Use Python APIs to test that we serialize resolvers."""
self.build()
self.setup_targets_and_cleanup()
self.do_check_resolvers()
def test_filters(self):
"""Use Python APIs to test that we serialize search filters correctly."""
self.build()
self.setup_targets_and_cleanup()
self.do_check_filters()
def test_options(self):
"""Use Python APIs to test that we serialize breakpoint options correctly."""
self.build()
self.setup_targets_and_cleanup()
self.do_check_options()
def test_appending(self):
"""Use Python APIs to test that we serialize breakpoint options correctly."""
self.build()
self.setup_targets_and_cleanup()
self.do_check_appending()
def test_name_filters(self):
"""Use python APIs to test that reading in by name works correctly."""
self.build()
self.setup_targets_and_cleanup()
self.do_check_names()
def setup_targets_and_cleanup(self):
def cleanup ():
self.RemoveTempFile(self.bkpts_file_path)
if self.orig_target.IsValid():
self.dbg.DeleteTarget(self.orig_target)
self.dbg.DeleteTarget(self.copy_target)
self.addTearDownHook(cleanup)
self.RemoveTempFile(self.bkpts_file_path)
exe = self.getBuildArtifact("a.out")
# Create the targets we are making breakpoints in and copying them to:
self.orig_target = self.dbg.CreateTarget(exe)
self.assertTrue(self.orig_target, VALID_TARGET)
self.copy_target = self.dbg.CreateTarget(exe)
self.assertTrue(self.copy_target, VALID_TARGET)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
self.bkpts_file_path = self.getBuildArtifact("breakpoints.json")
self.bkpts_file_spec = lldb.SBFileSpec(self.bkpts_file_path)
def check_equivalence(self, source_bps, do_write = True):
error = lldb.SBError()
if (do_write):
error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps)
self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
copy_bps = lldb.SBBreakpointList(self.copy_target)
error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, copy_bps)
self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
num_source_bps = source_bps.GetSize()
num_copy_bps = copy_bps.GetSize()
self.assertTrue(num_source_bps == num_copy_bps, "Didn't get same number of input and output breakpoints - orig: %d copy: %d"%(num_source_bps, num_copy_bps))
for i in range(0, num_source_bps):
source_bp = source_bps.GetBreakpointAtIndex(i)
source_desc = lldb.SBStream()
source_bp.GetDescription(source_desc, False)
source_text = source_desc.GetData()
# I am assuming here that the breakpoints will get written out in breakpoint ID order, and
# read back in ditto. That is true right now, and I can't see any reason to do it differently
# but if we do we can go to writing the breakpoints one by one, or sniffing the descriptions to
# see which one is which.
copy_id = source_bp.GetID()
copy_bp = copy_bps.FindBreakpointByID(copy_id)
self.assertTrue(copy_bp.IsValid(), "Could not find copy breakpoint %d."%(copy_id))
copy_desc = lldb.SBStream()
copy_bp.GetDescription(copy_desc, False)
copy_text = copy_desc.GetData()
# These two should be identical.
# print ("Source text for %d is %s."%(i, source_text))
self.assertTrue (source_text == copy_text, "Source and dest breakpoints are not identical: \nsource: %s\ndest: %s"%(source_text, copy_text))
def do_check_resolvers(self):
"""Use Python APIs to check serialization of breakpoint resolvers"""
empty_module_list = lldb.SBFileSpecList()
empty_cu_list = lldb.SBFileSpecList()
blubby_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "blubby.c"))
# It isn't actually important for these purposes that these breakpoint
# actually have locations.
source_bps = lldb.SBBreakpointList(self.orig_target)
source_bps.Append(self.orig_target.BreakpointCreateByLocation("blubby.c", 666))
# Make sure we do one breakpoint right:
self.check_equivalence(source_bps)
source_bps.Clear()
source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list))
source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list))
source_bps.Append(self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec))
# And some number greater than one:
self.check_equivalence(source_bps)
def do_check_filters(self):
"""Use Python APIs to check serialization of breakpoint filters."""
module_list = lldb.SBFileSpecList()
module_list.Append(lldb.SBFileSpec("SomeBinary"))
module_list.Append(lldb.SBFileSpec("SomeOtherBinary"))
cu_list = lldb.SBFileSpecList()
cu_list.Append(lldb.SBFileSpec("SomeCU.c"))
cu_list.Append(lldb.SBFileSpec("AnotherCU.c"))
cu_list.Append(lldb.SBFileSpec("ThirdCU.c"))
blubby_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "blubby.c"))
# It isn't actually important for these purposes that these breakpoint
# actually have locations.
source_bps = lldb.SBBreakpointList(self.orig_target)
bkpt = self.orig_target.BreakpointCreateByLocation(blubby_file_spec, 666, 0, module_list)
source_bps.Append(bkpt)
# Make sure we do one right:
self.check_equivalence(source_bps)
source_bps.Clear()
bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, module_list, cu_list)
source_bps.Append(bkpt)
bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, module_list, cu_list)
source_bps.Append(bkpt)
bkpt = self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec)
source_bps.Append(bkpt)
# And some number greater than one:
self.check_equivalence(source_bps)
def do_check_options(self):
"""Use Python APIs to check serialization of breakpoint options."""
empty_module_list = lldb.SBFileSpecList()
empty_cu_list = lldb.SBFileSpecList()
blubby_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "blubby.c"))
# It isn't actually important for these purposes that these breakpoint
# actually have locations.
source_bps = lldb.SBBreakpointList(self.orig_target)
bkpt = self.orig_target.BreakpointCreateByLocation(
lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList())
bkpt.SetEnabled(False)
bkpt.SetOneShot(True)
bkpt.SetThreadID(10)
source_bps.Append(bkpt)
# Make sure we get one right:
self.check_equivalence(source_bps)
source_bps.Clear()
bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)
bkpt.SetIgnoreCount(10)
bkpt.SetThreadName("grubby")
source_bps.Append(bkpt)
bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)
bkpt.SetCondition("gonna remove this")
bkpt.SetCondition("")
source_bps.Append(bkpt)
bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list)
bkpt.SetCondition("something != something_else")
bkpt.SetQueueName("grubby")
bkpt.AddName("FirstName")
bkpt.AddName("SecondName")
bkpt.SetScriptCallbackBody('\tprint("I am a function that prints.")\n\tprint("I don\'t do anything else")\n')
source_bps.Append(bkpt)
bkpt = self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec)
cmd_list = lldb.SBStringList()
cmd_list.AppendString("frame var")
cmd_list.AppendString("thread backtrace")
bkpt.SetCommandLineCommands(cmd_list)
source_bps.Append(bkpt)
self.check_equivalence(source_bps)
def do_check_appending(self):
"""Use Python APIs to check appending to already serialized options."""
empty_module_list = lldb.SBFileSpecList()
empty_cu_list = lldb.SBFileSpecList()
blubby_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "blubby.c"))
# It isn't actually important for these purposes that these breakpoint
# actually have locations.
all_bps = lldb.SBBreakpointList(self.orig_target)
source_bps = lldb.SBBreakpointList(self.orig_target)
bkpt = self.orig_target.BreakpointCreateByLocation(
lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList())
bkpt.SetEnabled(False)
bkpt.SetOneShot(True)
bkpt.SetThreadID(10)
source_bps.Append(bkpt)
all_bps.Append(bkpt)
error = lldb.SBError()
error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps)
self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
source_bps.Clear()
bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)
bkpt.SetIgnoreCount(10)
bkpt.SetThreadName("grubby")
source_bps.Append(bkpt)
all_bps.Append(bkpt)
bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list)
bkpt.SetCondition("something != something_else")
bkpt.SetQueueName("grubby")
bkpt.AddName("FirstName")
bkpt.AddName("SecondName")
source_bps.Append(bkpt)
all_bps.Append(bkpt)
error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps, True)
self.assertTrue(error.Success(), "Failed appending breakpoints to file: %s."%(error.GetCString()))
self.check_equivalence(all_bps)
def do_check_names(self):
bkpt = self.orig_target.BreakpointCreateByLocation(
lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList())
good_bkpt_name = "GoodBreakpoint"
write_bps = lldb.SBBreakpointList(self.orig_target)
bkpt.AddName(good_bkpt_name)
write_bps.Append(bkpt)
error = lldb.SBError()
error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps)
self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
copy_bps = lldb.SBBreakpointList(self.copy_target)
names_list = lldb.SBStringList()
names_list.AppendString("NoSuchName")
error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, names_list, copy_bps)
self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
self.assertTrue(copy_bps.GetSize() == 0, "Found breakpoints with a nonexistent name.")
names_list.AppendString(good_bkpt_name)
error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, names_list, copy_bps)
self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
self.assertTrue(copy_bps.GetSize() == 1, "Found the matching breakpoint.")

View File

@ -0,0 +1,53 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to demonstrate the capability of the lldb command
// "breakpoint modify -i <count> breakpt-id" to set the number of times a
// breakpoint is skipped before stopping. Ignore count can also be set upon
// breakpoint creation by 'breakpoint set ... -i <count>'.
int a(int);
int b(int);
int c(int);
int a(int val)
{
if (val <= 1)
return b(val);
else if (val >= 3)
return c(val); // a(3) -> c(3) Find the call site of c(3).
return val;
}
int b(int val)
{
return c(val);
}
int c(int val)
{
return val + 3; // Find the line number of function "c" here.
}
int main (int argc, char const *argv[])
{
int A1 = a(1); // a(1) -> b(1) -> c(1)
printf("a(1) returns %d\n", A1);
int B2 = b(2); // b(2) -> c(2) Find the call site of b(2).
printf("b(2) returns %d\n", B2);
int A3 = a(3); // a(3) -> c(3) Find the call site of a(3).
printf("a(3) returns %d\n", A3);
int C1 = c(5); // Find the call site of c in main.
printf ("c(5) returns %d\n", C1);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More