forked from OSchip/llvm-project
[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:
parent
3729b17cff
commit
d9442afba1
|
@ -0,0 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
CFLAGS_EXTRAS += -std=c99
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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)
|
|
@ -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.")
|
|
@ -0,0 +1,8 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
printf ("Set a breakpoint here.\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
CFLAGS_EXTRAS += -std=c99
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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")
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
CFLAGS_EXTRAS += -std=c99 -gcolumn-info
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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)
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c a.c b.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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")
|
|
@ -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)
|
|
@ -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'])
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int
|
||||
a_MyFunction ()
|
||||
{
|
||||
// Set a breakpoint here.
|
||||
printf ("a is about to return 10.\n");
|
||||
return 10;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int
|
||||
b_MyFunction ()
|
||||
{
|
||||
// Set a breakpoint here.
|
||||
printf ("b is about to return 20.\n");
|
||||
return 20;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
from __future__ import print_function
|
||||
import side_effect
|
||||
|
||||
def function(frame, bp_loc, dict):
|
||||
side_effect.bktptcmd = "function was here"
|
|
@ -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.
|
||||
}
|
|
@ -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.
|
||||
"""
|
|
@ -0,0 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
CFLAGS_EXTRAS += -std=c99
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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()
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
ifneq (,$(findstring icc,$(CC)))
|
||||
CXXFLAGS += -debug inline-debug-info
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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."])
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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()
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
@ -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()
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := a.c
|
||||
CXX_SOURCES := main.cpp b.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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")
|
|
@ -0,0 +1,5 @@
|
|||
int
|
||||
func_from_c ()
|
||||
{
|
||||
return 5;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
int
|
||||
func_from_cpp()
|
||||
{
|
||||
return 10;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
ifneq (,$(findstring icc,$(CC)))
|
||||
CFLAGS += -debug inline-debug-info
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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"])
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp foo.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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"])
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
namespace ns {
|
||||
int func(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int foo(void)
|
||||
{
|
||||
return ns::func();
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
extern "C" int foo(void);
|
||||
int main (int argc, char **argv) { // Set break point at this line.
|
||||
return foo();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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)))
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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)
|
|
@ -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.
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
ifneq (,$(findstring icc,$(CC)))
|
||||
CXXFLAGS += -debug inline-debug-info
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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()
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
ifneq (,$(findstring icc,$(CC)))
|
||||
CXXFLAGS += -debug inline-debug-info
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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")
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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.")
|
|
@ -0,0 +1,13 @@
|
|||
#include <exception>
|
||||
|
||||
void
|
||||
throws_int ()
|
||||
{
|
||||
throw 5;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
throws_int();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
ifneq (,$(findstring icc,$(CC)))
|
||||
CFLAGS += -debug inline-debug-info
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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."])
|
|
@ -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.
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
DYLIB_NAME := foo
|
||||
DYLIB_CXX_SOURCES := foo.cpp
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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))
|
|
@ -0,0 +1,7 @@
|
|||
#include "foo.h"
|
||||
|
||||
Foo::Foo() : x(42) {
|
||||
bool some_code = x == 42; // !BR_foo
|
||||
}
|
||||
|
||||
Foo FooObj;
|
|
@ -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
|
|
@ -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; }
|
|
@ -0,0 +1,6 @@
|
|||
LEVEL = ../../../../make
|
||||
|
||||
ENABLE_THREADS := YES
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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'])
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := int.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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])
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
|
@ -0,0 +1,7 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
DYLIB_NAME := foo
|
||||
DYLIB_CXX_SOURCES := foo.cpp
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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)
|
|
@ -0,0 +1,3 @@
|
|||
#include "foo.h"
|
||||
|
||||
int call_foo1() { return foo1(); }
|
|
@ -0,0 +1,5 @@
|
|||
inline int foo1() { return 1; } // !BR1
|
||||
|
||||
inline int foo2() { return 2; } // !BR2
|
||||
|
||||
LLDB_TEST_API extern int call_foo1();
|
|
@ -0,0 +1,9 @@
|
|||
#include "foo.h"
|
||||
|
||||
int call_foo2() { return foo2(); }
|
||||
// BR_Between
|
||||
int
|
||||
main() // !BR_main
|
||||
{
|
||||
return call_foo1() + call_foo2();
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
OBJC_SOURCES := main.m
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
||||
LDFLAGS += -framework Foundation
|
|
@ -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()
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
ifneq (,$(findstring icc,$(CC)))
|
||||
CFLAGS += -debug inline-debug-info
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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())
|
|
@ -0,0 +1,9 @@
|
|||
int break_on_me() {
|
||||
int i = 10;
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int main() {
|
||||
return break_on_me();
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
CFLAGS_EXTRAS += -std=c99
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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")
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -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.")
|
|
@ -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
Loading…
Reference in New Issue