diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/functionalities/breakpoint')
54 files changed, 2349 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/Makefile new file mode 100644 index 0000000..6067ee4 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS += -std=c99 + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestAddressBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestAddressBreakpoints.py new file mode 100644 index 0000000..9442a07 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestAddressBreakpoints.py @@ -0,0 +1,91 @@ +""" +Test address breakpoints set with shared library of SBAddress work correctly. +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class AddressBreakpointTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + 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 = os.path.join(os.getcwd(), "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) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/main.c new file mode 100644 index 0000000..6b77929 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/main.c @@ -0,0 +1,8 @@ +#include <stdio.h> + +int +main() +{ + printf ("Set a breakpoint here.\n"); + return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/Makefile new file mode 100644 index 0000000..a6376f9 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c a.c b.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py new file mode 100644 index 0000000..8cf7539 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py @@ -0,0 +1,206 @@ +""" +Test lldb breakpoint command add/list/delete. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class BreakpointCommandTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @classmethod + def classCleanup(cls): + """Cleanup the test byproduct of breakpoint_command_sequence(self).""" + cls.RemoveTempFile("output.txt") + cls.RemoveTempFile("output2.txt") + + @expectedFailureWindows("llvm.org/pr24528") + def test(self): + """Test a sequence of breakpoint command add, list, and delete.""" + self.build() + self.breakpoint_command_sequence() + self.breakpoint_command_script_parameters () + + 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 breakpoint_command_sequence(self): + """Test a sequence of breakpoint command add, list, and delete.""" + exe = os.path.join(os.getcwd(), "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) + + # 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 'here = open(\"output.txt\", \"w\"); here.write(\"lldb\\n\"); here.close()' 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, .+unresolved, hit count = 0" % self.line, + "2.1: .+at main.c:%d, .+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:", + "here = open", + "here.write", + "here.close()"]) + self.expect("breakpoint command list 3", "Breakpoint 3 command ok", + substrs = ["Breakpoint commands:", + "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) + + # Run the program. Remove 'output.txt' if it exists. + self.RemoveTempFile("output.txt") + self.RemoveTempFile("output2.txt") + self.runCmd("run", RUN_SUCCEEDED) + + # Check that the file 'output.txt' exists and contains the string "lldb". + + # The 'output.txt' file should now exist. + self.assertTrue(os.path.isfile("output.txt"), + "'output.txt' exists due to breakpoint command for breakpoint 2.") + self.assertTrue(os.path.isfile("output2.txt"), + "'output2.txt' exists due to breakpoint command for breakpoint 3.") + + # Read the output file produced by running the program. + with open('output.txt', 'r') as f: + output = f.read() + + self.expect(output, "File 'output.txt' and the content matches", exe=False, + startstr = "lldb") + + with open('output2.txt', 'r') as f: + output = f.read() + + self.expect(output, "File 'output2.txt' and the content matches", exe=False, + startstr = "lldb") + + + # 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 = os.path.join(os.getcwd(), "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 'here = open(\"output-2.txt\", \"w\"); here.write(str(frame) + \"\\n\"); here.write(str(bp_loc) + \"\\n\"); here.close()' 1") + + # Remove 'output-2.txt' if it already exists. + + if (os.path.exists('output-2.txt')): + os.remove ('output-2.txt') + + # Run program, hit breakpoint, and hopefully write out new version of 'output-2.txt' + self.runCmd ("run", RUN_SUCCEEDED) + + # Check that the file 'output.txt' exists and contains the string "lldb". + + # The 'output-2.txt' file should now exist. + self.assertTrue(os.path.isfile("output-2.txt"), + "'output-2.txt' exists due to breakpoint command for breakpoint 1.") + + # Read the output file produced by running the program. + with open('output-2.txt', 'r') as f: + output = f.read() + + self.expect (output, "File 'output-2.txt' and the content matches", exe=False, + startstr = "frame #0:", + patterns = ["1.* where = .*main .* resolved, hit count = 1" ]) + + # Now remove 'output-2.txt' + os.remove ('output-2.txt') diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py new file mode 100644 index 0000000..7a9cc74 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py @@ -0,0 +1,95 @@ +""" +Test that you can set breakpoint commands successfully with the Python API's: +""" + +from __future__ import print_function + + + +import os +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +import sys +from lldbsuite.test.lldbtest import * + +class PythonBreakpointCommandSettingTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + my_var = 10 + + @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 = os.path.join(os.getcwd(), "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()) + + PythonBreakpointCommandSettingTestCase.my_var = 10 + error = lldb.SBError() + error = body_bkpt.SetScriptCallbackBody("\ +import TestBreakpointCommandsFromPython\n\ +TestBreakpointCommandsFromPython.PythonBreakpointCommandSettingTestCase.my_var = 20\n\ +print('Hit breakpoint')") + 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") + + # We will use the function that touches a text file, so remove it first: + self.RemoveTempFile("output2.txt") + + # 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.assertTrue(PythonBreakpointCommandSettingTestCase.my_var == 20) + + # Check for the function version as well, which produced this file: + # Remember to clean up after ourselves... + self.assertTrue(os.path.isfile("output2.txt"), + "'output2.txt' exists due to breakpoint command for breakpoint function.") + self.RemoveTempFile("output2.txt") diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py new file mode 100644 index 0000000..1ea71cb --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestRegexpBreakCommand.py @@ -0,0 +1,51 @@ +""" +Test _regexp-break command which uses regular expression matching to dispatch to other built in breakpoint commands. +""" + +from __future__ import print_function + + + +import os, time +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 = os.path.join(os.getcwd(), "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(os.getcwd(), 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']) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/a.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/a.c new file mode 100644 index 0000000..870e4a6 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/a.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int +a_MyFunction () +{ + // Set a breakpoint here. + printf ("a is about to return 10.\n"); + return 10; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/b.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/b.c new file mode 100644 index 0000000..02b78e7 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/b.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int +b_MyFunction () +{ + // Set a breakpoint here. + printf ("b is about to return 20.\n"); + return 20; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/bktptcmd.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/bktptcmd.py new file mode 100644 index 0000000..4bbb032 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/bktptcmd.py @@ -0,0 +1,6 @@ +from __future__ import print_function + +def function(frame, bp_loc, dict): + there = open("output2.txt", "w"); + print("lldb", file=there) + there.close() diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/main.c new file mode 100644 index 0000000..62ec97f --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/main.c @@ -0,0 +1,13 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main (int argc, char const *argv[]) +{ + return 0; // Set break point at this line. +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/Makefile new file mode 100644 index 0000000..6067ee4 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS += -std=c99 + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py new file mode 100644 index 0000000..8c22c8f --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py @@ -0,0 +1,181 @@ +""" +Test breakpoint conditions with 'breakpoint modify -c <expr> id'. +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class BreakpointConditionsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfWindows # Requires EE to support COFF on Windows (http://llvm.org/pr22232) + def test_breakpoint_condition_and_run_command(self): + """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'.""" + self.build() + self.breakpoint_conditions() + + @skipIfWindows # Requires EE to support COFF on Windows (http://llvm.org/pr22232) + def test_breakpoint_condition_inline_and_run_command(self): + """Exercise breakpoint condition inline with 'breakpoint set'.""" + self.build() + self.breakpoint_conditions(inline=True) + + @skipIfWindows # Requires EE to support COFF on Windows (http://llvm.org/pr22232) + @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() + + 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 = os.path.join(os.getcwd(), "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") + self.runCmd("breakpoint disable") + + self.runCmd("breakpoint set -p Loop") + arch = self.getArchitecture() + if arch in ['x86_64', 'i386']: + self.runCmd("breakpoint modify -c ($eax&&i)") + elif arch in ['aarch64']: + self.runCmd("breakpoint modify -c ($x1&&i)") + elif arch in ['arm']: + self.runCmd("breakpoint modify -c ($r0&&i)") + elif re.match("mips",arch): + self.runCmd("breakpoint modify -c ($r2&&i)") + self.runCmd("run") + + self.expect("process status", PROCESS_STOPPED, + patterns = ['Process .* stopped']) + + self.runCmd("continue") + + self.expect("process status", PROCESS_EXITED, + patterns = ['Process .* exited']) + + def breakpoint_conditions_python(self): + """Use Python APIs to set breakpoint conditions.""" + exe = os.path.join(os.getcwd(), "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. + breakpoint.SetThreadIndex(1) # There's only one thread for the process. + 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) + + process.Continue() diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/main.c new file mode 100644 index 0000000..1aa8235 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/main.c @@ -0,0 +1,54 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#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; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/Makefile new file mode 100644 index 0000000..f89b52a --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/Makefile @@ -0,0 +1,9 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +ifneq (,$(findstring icc,$(CC))) + CXXFLAGS += -debug inline-debug-info +endif + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py new file mode 100644 index 0000000..b7edf2a --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py @@ -0,0 +1,51 @@ +""" +Test lldb breakpoint ids. +""" + +from __future__ import print_function + + + +import os, time +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 = os.path.join (os.getcwd(), "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."] ) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/main.cpp new file mode 100644 index 0000000..3deef22 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ids/main.cpp @@ -0,0 +1,65 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py new file mode 100644 index 0000000..8a83cb6 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py @@ -0,0 +1,136 @@ +""" +Test breakpoint ignore count features. +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class BreakpointIgnoreCountTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + 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']) + 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 = os.path.join(os.getcwd(), "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 = os.path.join(os.getcwd(), "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() diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/main.c new file mode 100644 index 0000000..b74b37b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/main.c @@ -0,0 +1,54 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#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; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile new file mode 100644 index 0000000..4f6b058 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := a.c +CXX_SOURCES := main.cpp b.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py new file mode 100644 index 0000000..94fc7bf --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py @@ -0,0 +1,85 @@ +""" +Test that the language option for breakpoints works correctly +parser. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil +import shutil +import subprocess + +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 = os.path.join(os.getcwd(), "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 = os.path.join(os.getcwd(), "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") + + diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c new file mode 100644 index 0000000..b90e2bd --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c @@ -0,0 +1,5 @@ +int +func_from_c () +{ + return 5; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp new file mode 100644 index 0000000..8937344 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp @@ -0,0 +1,5 @@ +int +func_from_cpp() +{ + return 10; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp new file mode 100644 index 0000000..b7d00a6 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp @@ -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; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/Makefile new file mode 100644 index 0000000..7934cd5 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/Makefile @@ -0,0 +1,9 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +ifneq (,$(findstring icc,$(CC))) + CFLAGS += -debug inline-debug-info +endif + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py new file mode 100644 index 0000000..5c4dc21 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py @@ -0,0 +1,88 @@ +""" +Test breakpoint commands for a breakpoint ID with multiple locations. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class BreakpointLocationsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureWindows("llvm.org/pr24528") + @expectedFailureAll(oslist=["linux"], compiler="clang", compiler_version=["=", "3.8"], archs=["i386"], debug_info="dwo") + def test(self): + """Test breakpoint enable/disable for a breakpoint ID with multiple locations.""" + self.build() + self.breakpoint_locations_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 breakpoint_locations_test(self): + """Test breakpoint enable/disable for a breakpoint ID with multiple locations.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint with 3 locations. + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=3) + + # 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 = 3" % self.line], + patterns = ["where = a.out`func_inlined .+unresolved, hit count = 0", + "where = a.out`main .+\[inlined\].+unresolved, hit count = 0"]) + + # 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 againt. 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"]) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/main.c new file mode 100644 index 0000000..7ec3ded --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/main.c @@ -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; +} + + diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/Makefile new file mode 100644 index 0000000..457c497 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp foo.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py new file mode 100644 index 0000000..29afec2 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py @@ -0,0 +1,93 @@ +""" +Test breakpoint command for different options. +""" + +from __future__ import print_function + + + +import os +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 = os.path.join(os.getcwd(), "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) + + # This should create a breakpoint 0 locations. + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, extra_options = "-m 0", 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 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, + "3: file = 'main.cpp', line = %d, exact_match = 1, locations = 0" % 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 = os.path.join(os.getcwd(), "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"]) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/foo.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/foo.cpp new file mode 100644 index 0000000..e5d0e09 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/foo.cpp @@ -0,0 +1,12 @@ + +namespace ns { + int func(void) + { + return 0; + } +} + +extern "C" int foo(void) +{ + return ns::func(); +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/main.cpp new file mode 100644 index 0000000..363b900 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_options/main.cpp @@ -0,0 +1,8 @@ +// Set break point at this line. + +extern "C" int foo(void); +int +main (int argc, char **argv) +{ + return foo(); +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/Makefile new file mode 100644 index 0000000..0ac34a1 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +EXE := CompDirSymLink + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py new file mode 100644 index 0000000..e1de38b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py @@ -0,0 +1,63 @@ +""" +Test breakpoint command with AT_comp_dir set to symbolic link. +""" +from __future__ import print_function + + + +import os +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil +import shutil + + +_EXE_NAME = 'CompDirSymLink' # Must match Makefile +_SRC_FILE = 'main.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(_SRC_FILE, '// Set break point at this line.') + self.src_path = os.path.join(os.getcwd(), _SRC_FILE) + + @skipIfHostWindows + 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)) + lldbutil.run_break_set_by_file_and_line(self, self.src_path, self.line) + + @skipUnlessHostLinux + def test_symlink_paths_set_procselfcwd(self): + pwd_symlink = '/proc/self/cwd' + self.doBuild(pwd_symlink) + self.runCmd("settings set %s %s" % (_COMP_DIR_SYM_LINK_PROP, pwd_symlink)) + lldbutil.run_break_set_by_file_and_line(self, self.src_path, self.line) + + @skipIfHostWindows + 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) + self.assertRaises(AssertionError, lldbutil.run_break_set_by_file_and_line, self, self.src_path, self.line) + + def create_src_symlink(self): + pwd_symlink = os.path.join(os.getcwd(), 'pwd_symlink') + if os.path.exists(pwd_symlink): + os.unlink(pwd_symlink) + os.symlink(os.getcwd(), pwd_symlink) + self.addTearDownHook(lambda: os.remove(pwd_symlink)) + return pwd_symlink + + def doBuild(self, pwd_symlink): + self.build(None, None, {'PWD': pwd_symlink}, True) + + exe = os.path.join(os.getcwd(), _EXE_NAME) + self.runCmd('file ' + exe, CURRENT_EXECUTABLE_SET) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/main.cpp new file mode 100644 index 0000000..fef06a0 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/main.cpp @@ -0,0 +1,13 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main (int argc, char const *argv[]) +{ + return 0; // Set break point at this line. +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile new file mode 100644 index 0000000..f89b52a --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile @@ -0,0 +1,9 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +ifneq (,$(findstring icc,$(CC))) + CXXFLAGS += -debug inline-debug-info +endif + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py new file mode 100644 index 0000000..af6df37 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py @@ -0,0 +1,59 @@ +""" +Test continue from a breakpoint when there is a breakpoint on the next instruction also. +""" + +from __future__ import print_function + + + +import unittest2 +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ConsecutiveBreakpoitsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll("llvm.org/pr23478", oslist = not_in(["macosx"])) + def test (self): + self.build () + self.consecutive_breakpoints_tests() + + def consecutive_breakpoints_tests(self): + exe = os.path.join (os.getcwd(), "a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateBySourceRegex("Set breakpoint here", lldb.SBFileSpec("main.cpp")) + 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) + + # We should be stopped at the first breakpoint + thread = process.GetThreadAtIndex(0) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint) + + # Set breakpoint to the next instruction + frame = thread.GetFrameAtIndex(0) + + address = frame.GetPCAddress() + instructions = target.ReadInstructions(address, 2) + self.assertTrue(len(instructions) == 2) + address = instructions[1].GetAddress() + + target.BreakpointCreateByAddress(address.GetLoadAddress(target)) + process.Continue() + + # We should be stopped at the second breakpoint + thread = process.GetThreadAtIndex(0) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint) + + # Run the process until termination + process.Continue() diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp new file mode 100644 index 0000000..c1943f0 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp @@ -0,0 +1,19 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int +main(int argc, char const *argv[]) +{ + int a = 0; + int b = 1; + a = b + 1; // Set breakpoint here + b = a + 1; + return 0; +} + diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/Makefile new file mode 100644 index 0000000..f89b52a --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/Makefile @@ -0,0 +1,9 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +ifneq (,$(findstring icc,$(CC))) + CXXFLAGS += -debug inline-debug-info +endif + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py new file mode 100644 index 0000000..dea206b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py @@ -0,0 +1,62 @@ +""" +Test lldb breakpoint ids. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class TestCPPBreakpointLocations(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureWindows("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.assertTrue (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 = os.path.join(os.getcwd(), "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) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp new file mode 100644 index 0000000..ef582aa --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp @@ -0,0 +1,77 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#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__); + } + }; +} + +namespace b { + class c { + public: + c () {} + ~c() {} + void func1() + { + puts (__PRETTY_FUNCTION__); + } + void func3() + { + puts (__PRETTY_FUNCTION__); + } + }; +} + +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; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/Makefile new file mode 100644 index 0000000..314f1cb --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py new file mode 100644 index 0000000..f7a1909 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py @@ -0,0 +1,48 @@ +""" +Test that you can set breakpoint and hit the C++ language exception breakpoint +""" + +from __future__ import print_function + + + +import os +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +import sys +from lldbsuite.test.lldbtest import * + +class TestCPPExceptionBreakpoint (TestBase): + + mydir = TestBase.compute_mydir(__file__) + my_var = 10 + + @add_test_categories(['pyapi']) + @expectedFailureWindows("llvm.org/pr24538") # clang-cl does not support throw or catch + 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 = os.path.join(os.getcwd(), "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.") diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/main.cpp new file mode 100644 index 0000000..76cb227 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/main.cpp @@ -0,0 +1,13 @@ +#include <exception> + +void +throws_int () +{ + throw 5; +} + +int +main () +{ + throws_int(); +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/Makefile new file mode 100644 index 0000000..7934cd5 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/Makefile @@ -0,0 +1,9 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +ifneq (,$(findstring icc,$(CC))) + CFLAGS += -debug inline-debug-info +endif + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/TestBreakpointsWithNoTargets.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/TestBreakpointsWithNoTargets.py new file mode 100644 index 0000000..f2693e6 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/TestBreakpointsWithNoTargets.py @@ -0,0 +1,67 @@ +""" +Test breakpoint commands set before we have a target +""" + +from __future__ import print_function + + + +import os, time +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 = os.path.join(os.getcwd(), "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."]) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/main.c new file mode 100644 index 0000000..e1f0323 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/dummy_target_breakpoints/main.c @@ -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. +} + + diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/Makefile new file mode 100644 index 0000000..5b73ae6 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := int.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py new file mode 100644 index 0000000..d04178b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py @@ -0,0 +1,57 @@ +""" +Test that inlined breakpoints (breakpoint set on a file/line included from +another source file) works correctly. +""" + +from __future__ import print_function + + + +import os, time +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 = os.path.join(os.getcwd(), "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]) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/basic_type.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/basic_type.cpp new file mode 100644 index 0000000..5881afe --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/basic_type.cpp @@ -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 + +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; + + +#include <stdint.h> +#include <stdio.h> + +void Puts(char const *msg) +{ + 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 + printf ("%s: a = '" T_PRINTF_FORMAT "'\n", T_CSTR, a); + printf ("%s*: %p => *a_ptr = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_ptr, *a_ptr); + printf ("%s&: @%p => a_ref = '" T_PRINTF_FORMAT "'\n", T_CSTR, &a_ref, a_ref); + + printf ("%s[2]: a_array_bounded[0] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_bounded[0]); + printf ("%s[2]: a_array_bounded[1] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_bounded[1]); + + printf ("%s[]: a_array_unbounded[0] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_unbounded[0]); + printf ("%s[]: a_array_unbounded[1] = '" T_PRINTF_FORMAT "'\n", T_CSTR, a_array_unbounded[1]); + + printf ("(a_class) a_class_instance.m_a = '" T_PRINTF_FORMAT "'\n", a_class_instance.get_a()); + printf ("(a_class) a_class_instance.m_b = '" T_PRINTF_FORMAT "'\n", a_class_instance.get_b()); + printf ("(a_class*) a_class_ptr = %p, a_class_ptr->m_a = '" T_PRINTF_FORMAT "'\n", a_class_ptr, a_class_ptr->get_a()); + printf ("(a_class*) a_class_ptr = %p, a_class_ptr->m_b = '" T_PRINTF_FORMAT "'\n", a_class_ptr, a_class_ptr->get_b()); + printf ("(a_class&) a_class_ref = %p, a_class_ref.m_a = '" T_PRINTF_FORMAT "'\n", &a_class_ref, a_class_ref.get_a()); + printf ("(a_class&) a_class_ref = %p, a_class_ref.m_b = '" T_PRINTF_FORMAT "'\n", &a_class_ref, a_class_ref.get_b()); + + printf ("(a_struct_t) a_struct.a = '" T_PRINTF_FORMAT "'\n", a_struct.a); + printf ("(a_struct_t) a_struct.b = '" T_PRINTF_FORMAT "'\n", a_struct.b); + printf ("(a_struct_t*) a_struct_ptr = %p, a_struct_ptr->a = '" T_PRINTF_FORMAT "'\n", a_struct_ptr, a_struct_ptr->a); + printf ("(a_struct_t*) a_struct_ptr = %p, a_struct_ptr->b = '" T_PRINTF_FORMAT "'\n", a_struct_ptr, a_struct_ptr->b); + printf ("(a_struct_t&) a_struct_ref = %p, a_struct_ref.a = '" T_PRINTF_FORMAT "'\n", &a_struct_ref, a_struct_ref.a); + printf ("(a_struct_t&) a_struct_ref = %p, a_struct_ref.b = '" T_PRINTF_FORMAT "'\n", &a_struct_ref, a_struct_ref.b); + + printf ("(a_union_zero_t) a_union_zero.a = '" T_PRINTF_FORMAT "'\n", a_union_zero.a); + 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); + 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); + + printf ("(a_union_nonzero_t) a_union_nonzero.u.a = '" T_PRINTF_FORMAT "'\n", a_union_nonzero.u.a); + 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); + 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); + + printf ("(a_struct_t[2]) a_struct_array_bounded[0].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[0].a); + printf ("(a_struct_t[2]) a_struct_array_bounded[0].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[0].b); + printf ("(a_struct_t[2]) a_struct_array_bounded[1].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[1].a); + printf ("(a_struct_t[2]) a_struct_array_bounded[1].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_bounded[1].b); + + printf ("(a_struct_t[]) a_struct_array_unbounded[0].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[0].a); + printf ("(a_struct_t[]) a_struct_array_unbounded[0].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[0].b); + printf ("(a_struct_t[]) a_struct_array_unbounded[1].a = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[1].a); + printf ("(a_struct_t[]) a_struct_array_unbounded[1].b = '" T_PRINTF_FORMAT "'\n", a_struct_array_unbounded[1].b); + + printf ("(a_union_zero_t[2]) a_union_zero_array_bounded[0].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_bounded[0].a); + printf ("(a_union_zero_t[2]) a_union_zero_array_bounded[1].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_bounded[1].a); + + printf ("(a_union_zero_t[]) a_union_zero_array_unbounded[0].a = '" T_PRINTF_FORMAT "'\n", a_union_zero_array_unbounded[0].a); + 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; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/int.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/int.cpp new file mode 100644 index 0000000..922398b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/inlined_breakpoints/int.cpp @@ -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" diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/Makefile new file mode 100644 index 0000000..ad3cb3f --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../make + +OBJC_SOURCES := main.m + +include $(LEVEL)/Makefile.rules + +LDFLAGS += -framework Foundation diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py new file mode 100644 index 0000000..648a0f5 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py @@ -0,0 +1,94 @@ +""" +Test that objective-c constant strings are generated correctly by the expression +parser. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil +import shutil +import subprocess + +@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 = os.path.join(os.getcwd(), "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() diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/main.m b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/main.m new file mode 100644 index 0000000..5356749 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/main.m @@ -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; +} |