199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest lldb breakpoint command add/list/delete. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht 699451b44SJordan Rupprechtimport lldb 799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 9*4d9e7b14SDmitry Vasilyevfrom lldbsuite.test import lldbutil, lldbplatformutil 10dc9e6c52SJeffrey Tanimport json 11c0124084SGreg Claytonimport os 1299451b44SJordan Rupprechtimport side_effect 1399451b44SJordan Rupprecht 1499451b44SJordan Rupprecht 1599451b44SJordan Rupprechtclass BreakpointCommandTestCase(TestBase): 1699451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1799451b44SJordan Rupprecht 1899451b44SJordan Rupprecht @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528") 190a68443bSWalter Erquinigo def test_breakpoint_command_sequence(self): 2099451b44SJordan Rupprecht """Test a sequence of breakpoint command add, list, and delete.""" 2199451b44SJordan Rupprecht self.build() 2299451b44SJordan Rupprecht self.breakpoint_command_sequence() 2399451b44SJordan Rupprecht 2499451b44SJordan Rupprecht @skipIf(oslist=["windows"], bugnumber="llvm.org/pr44431") 2599451b44SJordan Rupprecht def test_script_parameters(self): 2699451b44SJordan Rupprecht """Test a sequence of breakpoint command add, list, and delete.""" 2799451b44SJordan Rupprecht self.build() 2899451b44SJordan Rupprecht self.breakpoint_command_script_parameters() 2999451b44SJordan Rupprecht 3099451b44SJordan Rupprecht def test_commands_on_creation(self): 3199451b44SJordan Rupprecht self.build() 3299451b44SJordan Rupprecht self.breakpoint_commands_on_creation() 3399451b44SJordan Rupprecht 34c0124084SGreg Clayton @skipIf(oslist=["windows"]) 35c0124084SGreg Clayton @no_debug_info_test 36c0124084SGreg Clayton def test_breakpoints_with_relative_path_line_tables(self): 37c0124084SGreg Clayton """ 38c0124084SGreg Clayton Test that we can set breakpoints using a full or partial path when 39c0124084SGreg Clayton line tables in the debug information has relative paths where the 40c0124084SGreg Clayton relative path is either fully contained in the specified path, or if 41c0124084SGreg Clayton the specified path also a relative path that is shorter than the 42c0124084SGreg Clayton path in the debug info. 43c0124084SGreg Clayton 44c0124084SGreg Clayton The "relative.yaml" contains a line table that is: 45c0124084SGreg Clayton 46c0124084SGreg Clayton Line table for a/b/c/main.cpp in `a.out 47c0124084SGreg Clayton 0x0000000100003f94: a/b/c/main.cpp:1 48c0124084SGreg Clayton 0x0000000100003fb0: a/b/c/main.cpp:2:3 49c0124084SGreg Clayton 0x0000000100003fb8: a/b/c/main.cpp:2:3 50c0124084SGreg Clayton 51c0124084SGreg Clayton So the line table contains relative paths. We should be able to set 52c0124084SGreg Clayton breakpoints with any source path that matches this path which 53c0124084SGreg Clayton includes paths that are longer than "a/b/c/main.cpp", but also any 54c0124084SGreg Clayton relative path that is shorter than this while all specified relative 55c0124084SGreg Clayton path components still match. 56c0124084SGreg Clayton """ 57c0124084SGreg Clayton src_dir = self.getSourceDir() 58c0124084SGreg Clayton yaml_path = os.path.join(src_dir, "relative.yaml") 59c0124084SGreg Clayton yaml_base, ext = os.path.splitext(yaml_path) 60c0124084SGreg Clayton obj_path = self.getBuildArtifact("a.out") 61c0124084SGreg Clayton self.yaml2obj(yaml_path, obj_path) 62c0124084SGreg Clayton 63c0124084SGreg Clayton # Create a target with the object file we just created from YAML 64c0124084SGreg Clayton target = self.dbg.CreateTarget(obj_path) 65c0124084SGreg Clayton # We now have debug information with line table paths that start are 66c0124084SGreg Clayton # "./a/b/c/main.cpp". 67c0124084SGreg Clayton 68c0124084SGreg Clayton # Make sure that all of the following paths create a breakpoint 69c0124084SGreg Clayton # successfully. We have paths that are longer than our path, and also 70c0124084SGreg Clayton # that are shorter where all relative directories still match. 71c0124084SGreg Clayton valid_paths = [ 72c0124084SGreg Clayton "/x/a/b/c/main.cpp", 73c0124084SGreg Clayton "/x/y/a/b/c/main.cpp", 74c0124084SGreg Clayton "./x/y/a/b/c/main.cpp", 75c0124084SGreg Clayton "x/y/a/b/c/main.cpp", 76c0124084SGreg Clayton "./y/a/b/c/main.cpp", 77c0124084SGreg Clayton "y/a/b/c/main.cpp", 78c0124084SGreg Clayton "./a/b/c/main.cpp", 79c0124084SGreg Clayton "a/b/c/main.cpp", 80c0124084SGreg Clayton "./b/c/main.cpp", 81c0124084SGreg Clayton "b/c/main.cpp", 82c0124084SGreg Clayton "./c/main.cpp", 83c0124084SGreg Clayton "c/main.cpp", 84c0124084SGreg Clayton "./main.cpp", 85c0124084SGreg Clayton "main.cpp", 86c0124084SGreg Clayton ] 87c0124084SGreg Clayton for path in valid_paths: 88c0124084SGreg Clayton bkpt = target.BreakpointCreateByLocation(path, 2) 899c246882SJordan Rupprecht self.assertGreater( 909c246882SJordan Rupprecht bkpt.GetNumLocations(), 919c246882SJordan Rupprecht 0, 92c0124084SGreg Clayton 'Couldn\'t resolve breakpoint using full path "%s" in executate "%s" with ' 932238dcc3SJonas Devlieghere "debug info that has relative path with matching suffix" 942238dcc3SJonas Devlieghere % (path, self.getBuildArtifact("a.out")), 952238dcc3SJonas Devlieghere ) 96c0124084SGreg Clayton invalid_paths = [ 97c0124084SGreg Clayton "/x/b/c/main.cpp", 98c0124084SGreg Clayton "/x/c/main.cpp", 99c0124084SGreg Clayton "/x/main.cpp", 100c0124084SGreg Clayton "./x/y/a/d/c/main.cpp", 101c0124084SGreg Clayton ] 102dc9e6c52SJeffrey Tan # Reset source map. 103dc9e6c52SJeffrey Tan self.runCmd("settings clear target.source-map") 104c0124084SGreg Clayton for path in invalid_paths: 105c0124084SGreg Clayton bkpt = target.BreakpointCreateByLocation(path, 2) 1062238dcc3SJonas Devlieghere self.assertEqual( 1072238dcc3SJonas Devlieghere bkpt.GetNumLocations(), 1082238dcc3SJonas Devlieghere 0, 109c0124084SGreg Clayton 'Incorrectly resolved a breakpoint using full path "%s" with ' 1102238dcc3SJonas Devlieghere "debug info that has relative path with matching suffix" % (path), 1112238dcc3SJonas Devlieghere ) 112c0124084SGreg Clayton 113dd00c4dbSGreg Clayton @no_debug_info_test 114dd00c4dbSGreg Clayton def test_breakpoints_with_bad_aranges(self): 115dd00c4dbSGreg Clayton """ 116dd00c4dbSGreg Clayton Test that we can set breakpoints in a file that has an invalid 117dd00c4dbSGreg Clayton .debug_aranges. Older versions of LLDB would find a line entry 118dd00c4dbSGreg Clayton in the line table and then would use the start address of the line 119dd00c4dbSGreg Clayton entry to do an address lookup on the entry from the line table. If 120dd00c4dbSGreg Clayton this address to symbol context lookup would fail, due to a bad 121dd00c4dbSGreg Clayton .debug_aranges, it would cause the breakpoint to not get resolved. 122dd00c4dbSGreg Clayton Verify that even in these conditions we are able to resolve a 123dd00c4dbSGreg Clayton breakpoint. 124dd00c4dbSGreg Clayton 125dd00c4dbSGreg Clayton The "bad_aranges.yaml" contains a line table that is: 126dd00c4dbSGreg Clayton 127dd00c4dbSGreg Clayton Line table for /tmp/ab/main.cpp in `a.out 128dd00c4dbSGreg Clayton 0x0000000100003f94: /tmp/ab/main.cpp:1 129dd00c4dbSGreg Clayton 0x0000000100003fb0: /tmp/ab/main.cpp:2:3 130dd00c4dbSGreg Clayton 0x0000000100003fb8: /tmp/ab/main.cpp:2:3 131dd00c4dbSGreg Clayton 132dd00c4dbSGreg Clayton The .debug_aranges has one range for this compile unit that is 133dd00c4dbSGreg Clayton invalid: [0x0000000200003f94-0x0000000200003fb8). This will cause 134dd00c4dbSGreg Clayton the resolving of the addresses to fail. 135dd00c4dbSGreg Clayton """ 136dd00c4dbSGreg Clayton src_dir = self.getSourceDir() 137dd00c4dbSGreg Clayton yaml_path = os.path.join(src_dir, "bad_aranges.yaml") 138dd00c4dbSGreg Clayton yaml_base, ext = os.path.splitext(yaml_path) 139dd00c4dbSGreg Clayton obj_path = self.getBuildArtifact("a.out") 140dd00c4dbSGreg Clayton self.yaml2obj(yaml_path, obj_path) 141dd00c4dbSGreg Clayton 142dd00c4dbSGreg Clayton # Create a target with the object file we just created from YAML 143dd00c4dbSGreg Clayton target = self.dbg.CreateTarget(obj_path) 1442238dcc3SJonas Devlieghere src_path = "/tmp/ab/main.cpp" 145dd00c4dbSGreg Clayton bkpt = target.BreakpointCreateByLocation(src_path, 2) 1469c246882SJordan Rupprecht self.assertGreater( 1479c246882SJordan Rupprecht bkpt.GetNumLocations(), 1489c246882SJordan Rupprecht 0, 149dd00c4dbSGreg Clayton 'Couldn\'t resolve breakpoint using "%s" in executate "%s" with ' 1502238dcc3SJonas Devlieghere "debug info that has a bad .debug_aranges section" 1512238dcc3SJonas Devlieghere % (src_path, self.getBuildArtifact("a.out")), 1522238dcc3SJonas Devlieghere ) 153c0124084SGreg Clayton 15499451b44SJordan Rupprecht def setUp(self): 15599451b44SJordan Rupprecht # Call super's setUp(). 15699451b44SJordan Rupprecht TestBase.setUp(self) 15799451b44SJordan Rupprecht # Find the line number to break inside main(). 1582238dcc3SJonas Devlieghere self.line = line_number("main.c", "// Set break point at this line.") 15999451b44SJordan Rupprecht # disable "There is a running process, kill it and restart?" prompt 16099451b44SJordan Rupprecht self.runCmd("settings set auto-confirm true") 1612238dcc3SJonas Devlieghere self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm")) 16299451b44SJordan Rupprecht 16399451b44SJordan Rupprecht def test_delete_all_breakpoints(self): 16499451b44SJordan Rupprecht """Test that deleting all breakpoints works.""" 16599451b44SJordan Rupprecht self.build() 16699451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 16799451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 16899451b44SJordan Rupprecht 16999451b44SJordan Rupprecht lldbutil.run_break_set_by_symbol(self, "main") 17099451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 1712238dcc3SJonas Devlieghere self, "main.c", self.line, num_expected_locations=1, loc_exact=True 1722238dcc3SJonas Devlieghere ) 17399451b44SJordan Rupprecht 17499451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 17599451b44SJordan Rupprecht 17699451b44SJordan Rupprecht self.runCmd("breakpoint delete") 17799451b44SJordan Rupprecht self.runCmd("process continue") 1782238dcc3SJonas Devlieghere self.expect( 1792238dcc3SJonas Devlieghere "process status", 1802238dcc3SJonas Devlieghere PROCESS_STOPPED, 1812238dcc3SJonas Devlieghere patterns=["Process .* exited with status = 0"], 1822238dcc3SJonas Devlieghere ) 18399451b44SJordan Rupprecht 18499451b44SJordan Rupprecht def breakpoint_command_sequence(self): 18599451b44SJordan Rupprecht """Test a sequence of breakpoint command add, list, and delete.""" 18699451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 18799451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 18899451b44SJordan Rupprecht 18999451b44SJordan Rupprecht # Add three breakpoints on the same line. The first time we don't specify the file, 19099451b44SJordan Rupprecht # since the default file is the one containing main: 19199451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 1922238dcc3SJonas Devlieghere self, None, self.line, num_expected_locations=1, loc_exact=True 1932238dcc3SJonas Devlieghere ) 19499451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 1952238dcc3SJonas Devlieghere self, "main.c", self.line, num_expected_locations=1, loc_exact=True 1962238dcc3SJonas Devlieghere ) 19799451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 1982238dcc3SJonas Devlieghere self, "main.c", self.line, num_expected_locations=1, loc_exact=True 1992238dcc3SJonas Devlieghere ) 20099451b44SJordan Rupprecht # Breakpoint 4 - set at the same location as breakpoint 1 to test 20199451b44SJordan Rupprecht # setting breakpoint commands on two breakpoints at a time 20299451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2032238dcc3SJonas Devlieghere self, None, self.line, num_expected_locations=1, loc_exact=True 2042238dcc3SJonas Devlieghere ) 20599451b44SJordan Rupprecht # Make sure relative path source breakpoints work as expected. We test 20699451b44SJordan Rupprecht # with partial paths with and without "./" prefixes. 20799451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2082238dcc3SJonas Devlieghere self, "./main.c", self.line, num_expected_locations=1, loc_exact=True 2092238dcc3SJonas Devlieghere ) 21099451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2112238dcc3SJonas Devlieghere self, 2122238dcc3SJonas Devlieghere "breakpoint_command/main.c", 2132238dcc3SJonas Devlieghere self.line, 2142238dcc3SJonas Devlieghere num_expected_locations=1, 2152238dcc3SJonas Devlieghere loc_exact=True, 2162238dcc3SJonas Devlieghere ) 21799451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2182238dcc3SJonas Devlieghere self, 2192238dcc3SJonas Devlieghere "./breakpoint_command/main.c", 2202238dcc3SJonas Devlieghere self.line, 2212238dcc3SJonas Devlieghere num_expected_locations=1, 2222238dcc3SJonas Devlieghere loc_exact=True, 2232238dcc3SJonas Devlieghere ) 22499451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2252238dcc3SJonas Devlieghere self, 2262238dcc3SJonas Devlieghere "breakpoint/breakpoint_command/main.c", 2272238dcc3SJonas Devlieghere self.line, 2282238dcc3SJonas Devlieghere num_expected_locations=1, 2292238dcc3SJonas Devlieghere loc_exact=True, 2302238dcc3SJonas Devlieghere ) 23199451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2322238dcc3SJonas Devlieghere self, 2332238dcc3SJonas Devlieghere "./breakpoint/breakpoint_command/main.c", 2342238dcc3SJonas Devlieghere self.line, 2352238dcc3SJonas Devlieghere num_expected_locations=1, 2362238dcc3SJonas Devlieghere loc_exact=True, 2372238dcc3SJonas Devlieghere ) 23899451b44SJordan Rupprecht # Test relative breakpoints with incorrect paths and make sure we get 23999451b44SJordan Rupprecht # no breakpoint locations 24099451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2412238dcc3SJonas Devlieghere self, "invalid/main.c", self.line, num_expected_locations=0, loc_exact=True 2422238dcc3SJonas Devlieghere ) 24399451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2442238dcc3SJonas Devlieghere self, 2452238dcc3SJonas Devlieghere "./invalid/main.c", 2462238dcc3SJonas Devlieghere self.line, 2472238dcc3SJonas Devlieghere num_expected_locations=0, 2482238dcc3SJonas Devlieghere loc_exact=True, 2492238dcc3SJonas Devlieghere ) 25099451b44SJordan Rupprecht # Now add callbacks for the breakpoints just created. 25199451b44SJordan Rupprecht self.runCmd( 2522238dcc3SJonas Devlieghere "breakpoint command add -s command -o 'frame variable --show-types --scope' 1 4" 2532238dcc3SJonas Devlieghere ) 25499451b44SJordan Rupprecht self.runCmd( 2552238dcc3SJonas Devlieghere "breakpoint command add -s python -o 'import side_effect; side_effect.one_liner = \"one liner was here\"' 2" 2562238dcc3SJonas Devlieghere ) 25799451b44SJordan Rupprecht 25899451b44SJordan Rupprecht import side_effect 2592238dcc3SJonas Devlieghere 26099451b44SJordan Rupprecht self.runCmd("command script import --allow-reload ./bktptcmd.py") 26199451b44SJordan Rupprecht 2622238dcc3SJonas Devlieghere self.runCmd("breakpoint command add --python-function bktptcmd.function 3") 26399451b44SJordan Rupprecht 26499451b44SJordan Rupprecht # Check that the breakpoint commands are correctly set. 26599451b44SJordan Rupprecht 26699451b44SJordan Rupprecht # The breakpoint list now only contains breakpoint 1. 26799451b44SJordan Rupprecht self.expect( 2682238dcc3SJonas Devlieghere "breakpoint list", 2692238dcc3SJonas Devlieghere "Breakpoints 1 & 2 created", 2702238dcc3SJonas Devlieghere substrs=[ 2712238dcc3SJonas Devlieghere "2: file = 'main.c', line = %d, exact_match = 0, locations = 1" 2722238dcc3SJonas Devlieghere % self.line 2732238dcc3SJonas Devlieghere ], 2742238dcc3SJonas Devlieghere patterns=[ 2752238dcc3SJonas Devlieghere "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" 2762238dcc3SJonas Devlieghere % self.line 2772238dcc3SJonas Devlieghere ], 2782238dcc3SJonas Devlieghere ) 27999451b44SJordan Rupprecht 28099451b44SJordan Rupprecht self.expect( 28199451b44SJordan Rupprecht "breakpoint list -f", 28299451b44SJordan Rupprecht "Breakpoints 1 & 2 created", 28399451b44SJordan Rupprecht substrs=[ 2842238dcc3SJonas Devlieghere "2: file = 'main.c', line = %d, exact_match = 0, locations = 1" 2852238dcc3SJonas Devlieghere % self.line 2862238dcc3SJonas Devlieghere ], 28799451b44SJordan Rupprecht patterns=[ 2882238dcc3SJonas Devlieghere "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" 2892238dcc3SJonas Devlieghere % self.line, 2902238dcc3SJonas Devlieghere "1.1: .+at main.c:%d:?[0-9]*, .+unresolved, hit count = 0" % self.line, 2912238dcc3SJonas Devlieghere "2.1: .+at main.c:%d:?[0-9]*, .+unresolved, hit count = 0" % self.line, 2922238dcc3SJonas Devlieghere ], 2932238dcc3SJonas Devlieghere ) 29499451b44SJordan Rupprecht 2952238dcc3SJonas Devlieghere self.expect( 2962238dcc3SJonas Devlieghere "breakpoint command list 1", 2972238dcc3SJonas Devlieghere "Breakpoint 1 command ok", 2982238dcc3SJonas Devlieghere substrs=["Breakpoint commands:", "frame variable --show-types --scope"], 2992238dcc3SJonas Devlieghere ) 3002238dcc3SJonas Devlieghere self.expect( 3012238dcc3SJonas Devlieghere "breakpoint command list 2", 3022238dcc3SJonas Devlieghere "Breakpoint 2 command ok", 3032238dcc3SJonas Devlieghere substrs=[ 3042238dcc3SJonas Devlieghere "Breakpoint commands (Python):", 30599451b44SJordan Rupprecht "import side_effect", 3062238dcc3SJonas Devlieghere "side_effect.one_liner", 3072238dcc3SJonas Devlieghere ], 3082238dcc3SJonas Devlieghere ) 3092238dcc3SJonas Devlieghere self.expect( 3102238dcc3SJonas Devlieghere "breakpoint command list 3", 3112238dcc3SJonas Devlieghere "Breakpoint 3 command ok", 3122238dcc3SJonas Devlieghere substrs=[ 3132238dcc3SJonas Devlieghere "Breakpoint commands (Python):", 3142238dcc3SJonas Devlieghere "bktptcmd.function(frame, bp_loc, internal_dict)", 3152238dcc3SJonas Devlieghere ], 3162238dcc3SJonas Devlieghere ) 31799451b44SJordan Rupprecht 3182238dcc3SJonas Devlieghere self.expect( 3192238dcc3SJonas Devlieghere "breakpoint command list 4", 3202238dcc3SJonas Devlieghere "Breakpoint 4 command ok", 3212238dcc3SJonas Devlieghere substrs=["Breakpoint commands:", "frame variable --show-types --scope"], 3222238dcc3SJonas Devlieghere ) 32399451b44SJordan Rupprecht 32499451b44SJordan Rupprecht self.runCmd("breakpoint delete 4") 32599451b44SJordan Rupprecht 32699451b44SJordan Rupprecht # Next lets try some other breakpoint kinds. First break with a regular expression 32799451b44SJordan Rupprecht # and then specify only one file. The first time we should get two locations, 32899451b44SJordan Rupprecht # the second time only one: 32999451b44SJordan Rupprecht 33099451b44SJordan Rupprecht lldbutil.run_break_set_by_regexp( 3312238dcc3SJonas Devlieghere self, r"._MyFunction", num_expected_locations=2 3322238dcc3SJonas Devlieghere ) 33399451b44SJordan Rupprecht 33499451b44SJordan Rupprecht lldbutil.run_break_set_by_regexp( 3352238dcc3SJonas Devlieghere self, r"._MyFunction", extra_options="-f a.c", num_expected_locations=1 3362238dcc3SJonas Devlieghere ) 33799451b44SJordan Rupprecht 33899451b44SJordan Rupprecht lldbutil.run_break_set_by_regexp( 33999451b44SJordan Rupprecht self, 34099451b44SJordan Rupprecht r"._MyFunction", 34199451b44SJordan Rupprecht extra_options="-f a.c -f b.c", 3422238dcc3SJonas Devlieghere num_expected_locations=2, 3432238dcc3SJonas Devlieghere ) 34499451b44SJordan Rupprecht 34599451b44SJordan Rupprecht # Now try a source regex breakpoint: 34699451b44SJordan Rupprecht lldbutil.run_break_set_by_source_regexp( 34799451b44SJordan Rupprecht self, 34899451b44SJordan Rupprecht r"is about to return [12]0", 34999451b44SJordan Rupprecht extra_options="-f a.c -f b.c", 3502238dcc3SJonas Devlieghere num_expected_locations=2, 3512238dcc3SJonas Devlieghere ) 35299451b44SJordan Rupprecht 35399451b44SJordan Rupprecht lldbutil.run_break_set_by_source_regexp( 35499451b44SJordan Rupprecht self, 35599451b44SJordan Rupprecht r"is about to return [12]0", 35699451b44SJordan Rupprecht extra_options="-f a.c", 3572238dcc3SJonas Devlieghere num_expected_locations=1, 3582238dcc3SJonas Devlieghere ) 35999451b44SJordan Rupprecht 36099451b44SJordan Rupprecht # Reset our canary variables and run the program. 36199451b44SJordan Rupprecht side_effect.one_liner = None 36299451b44SJordan Rupprecht side_effect.bktptcmd = None 36399451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 36499451b44SJordan Rupprecht 36599451b44SJordan Rupprecht # Check the value of canary variables. 36680fcecb1SJonas Devlieghere self.assertEqual("one liner was here", side_effect.one_liner) 36780fcecb1SJonas Devlieghere self.assertEqual("function was here", side_effect.bktptcmd) 36899451b44SJordan Rupprecht 36999451b44SJordan Rupprecht # Finish the program. 37099451b44SJordan Rupprecht self.runCmd("process continue") 37199451b44SJordan Rupprecht 37299451b44SJordan Rupprecht # Remove the breakpoint command associated with breakpoint 1. 37399451b44SJordan Rupprecht self.runCmd("breakpoint command delete 1") 37499451b44SJordan Rupprecht 37599451b44SJordan Rupprecht # Remove breakpoint 2. 37699451b44SJordan Rupprecht self.runCmd("breakpoint delete 2") 37799451b44SJordan Rupprecht 37899451b44SJordan Rupprecht self.expect( 37999451b44SJordan Rupprecht "breakpoint command list 1", 3802238dcc3SJonas Devlieghere startstr="Breakpoint 1 does not have an associated command.", 3812238dcc3SJonas Devlieghere ) 38299451b44SJordan Rupprecht self.expect( 38399451b44SJordan Rupprecht "breakpoint command list 2", 38499451b44SJordan Rupprecht error=True, 3852238dcc3SJonas Devlieghere startstr="error: '2' is not a currently valid breakpoint ID.", 3862238dcc3SJonas Devlieghere ) 38799451b44SJordan Rupprecht 38899451b44SJordan Rupprecht # The breakpoint list now only contains breakpoint 1. 38999451b44SJordan Rupprecht self.expect( 39099451b44SJordan Rupprecht "breakpoint list -f", 39199451b44SJordan Rupprecht "Breakpoint 1 exists", 39299451b44SJordan Rupprecht patterns=[ 3932238dcc3SJonas Devlieghere "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" 3942238dcc3SJonas Devlieghere % self.line, 3952238dcc3SJonas Devlieghere "hit count = 1", 3962238dcc3SJonas Devlieghere ], 3972238dcc3SJonas Devlieghere ) 39899451b44SJordan Rupprecht 39999451b44SJordan Rupprecht # Not breakpoint 2. 40099451b44SJordan Rupprecht self.expect( 40199451b44SJordan Rupprecht "breakpoint list -f", 40299451b44SJordan Rupprecht "No more breakpoint 2", 40399451b44SJordan Rupprecht matching=False, 40499451b44SJordan Rupprecht substrs=[ 4052238dcc3SJonas Devlieghere "2: file = 'main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" 4062238dcc3SJonas Devlieghere % self.line 4072238dcc3SJonas Devlieghere ], 4082238dcc3SJonas Devlieghere ) 40999451b44SJordan Rupprecht 41099451b44SJordan Rupprecht # Run the program again, with breakpoint 1 remaining. 41199451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 41299451b44SJordan Rupprecht 41399451b44SJordan Rupprecht # We should be stopped again due to breakpoint 1. 41499451b44SJordan Rupprecht 41599451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint. 4162238dcc3SJonas Devlieghere self.expect( 4172238dcc3SJonas Devlieghere "thread list", 4182238dcc3SJonas Devlieghere STOPPED_DUE_TO_BREAKPOINT, 4192238dcc3SJonas Devlieghere substrs=["stopped", "stop reason = breakpoint"], 4202238dcc3SJonas Devlieghere ) 42199451b44SJordan Rupprecht 42297495874SFelipe de Azevedo Piovezan # The breakpoint should have a hit count of 1, since we reset counts 42397495874SFelipe de Azevedo Piovezan # for each run. 42497495874SFelipe de Azevedo Piovezan lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1) 42599451b44SJordan Rupprecht 42699451b44SJordan Rupprecht def breakpoint_command_script_parameters(self): 42799451b44SJordan Rupprecht """Test that the frame and breakpoint location are being properly passed to the script breakpoint command function.""" 42899451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 42999451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 43099451b44SJordan Rupprecht 43199451b44SJordan Rupprecht # Add a breakpoint. 43299451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 4332238dcc3SJonas Devlieghere self, "main.c", self.line, num_expected_locations=1, loc_exact=True 4342238dcc3SJonas Devlieghere ) 43599451b44SJordan Rupprecht 43699451b44SJordan Rupprecht # Now add callbacks for the breakpoints just created. 4372238dcc3SJonas Devlieghere self.runCmd( 4382238dcc3SJonas Devlieghere "breakpoint command add -s python -o 'import side_effect; side_effect.frame = str(frame); side_effect.bp_loc = str(bp_loc)' 1" 4392238dcc3SJonas Devlieghere ) 44099451b44SJordan Rupprecht 44199451b44SJordan Rupprecht # Reset canary variables and run. 44299451b44SJordan Rupprecht side_effect.frame = None 44399451b44SJordan Rupprecht side_effect.bp_loc = None 44499451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 44599451b44SJordan Rupprecht 44699451b44SJordan Rupprecht self.expect(side_effect.frame, exe=False, startstr="frame #0:") 4472238dcc3SJonas Devlieghere self.expect( 4482238dcc3SJonas Devlieghere side_effect.bp_loc, 4492238dcc3SJonas Devlieghere exe=False, 4502238dcc3SJonas Devlieghere patterns=["1.* where = .*main .* resolved,( hardware,)? hit count = 1"], 4512238dcc3SJonas Devlieghere ) 45299451b44SJordan Rupprecht 45399451b44SJordan Rupprecht def breakpoint_commands_on_creation(self): 45499451b44SJordan Rupprecht """Test that setting breakpoint commands when creating the breakpoint works""" 45554c26872SRaphael Isemann target = self.createTestTarget() 45699451b44SJordan Rupprecht 45799451b44SJordan Rupprecht # Add a breakpoint. 45899451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 4592238dcc3SJonas Devlieghere self, 4602238dcc3SJonas Devlieghere "main.c", 4612238dcc3SJonas Devlieghere self.line, 4622238dcc3SJonas Devlieghere num_expected_locations=1, 4632238dcc3SJonas Devlieghere loc_exact=True, 4642238dcc3SJonas Devlieghere extra_options='-C bt -C "thread list" -C continue', 4652238dcc3SJonas Devlieghere ) 46699451b44SJordan Rupprecht 46799451b44SJordan Rupprecht bkpt = target.FindBreakpointByID(1) 46899451b44SJordan Rupprecht self.assertTrue(bkpt.IsValid(), "Couldn't find breakpoint 1") 46999451b44SJordan Rupprecht com_list = lldb.SBStringList() 47099451b44SJordan Rupprecht bkpt.GetCommandLineCommands(com_list) 47199451b44SJordan Rupprecht self.assertEqual(com_list.GetSize(), 3, "Got the wrong number of commands") 47299451b44SJordan Rupprecht self.assertEqual(com_list.GetStringAtIndex(0), "bt", "First bt") 4732238dcc3SJonas Devlieghere self.assertEqual( 4742238dcc3SJonas Devlieghere com_list.GetStringAtIndex(1), "thread list", "Next thread list" 4752238dcc3SJonas Devlieghere ) 47699451b44SJordan Rupprecht self.assertEqual(com_list.GetStringAtIndex(2), "continue", "Last continue") 4773726ac41SJim Ingham 478d92f7f79SJim Ingham def test_add_commands_by_breakpoint_name(self): 479d92f7f79SJim Ingham """Make sure that when you specify a breakpoint name to "break command add" 480d92f7f79SJim Ingham it gets added to all the breakpoints marked with that name.""" 481d92f7f79SJim Ingham self.build() 482d92f7f79SJim Ingham target = self.createTestTarget() 483d92f7f79SJim Ingham 484d92f7f79SJim Ingham bp_ids = [] 485d92f7f79SJim Ingham bp_names = ["main", "not_here", "main"] 486d92f7f79SJim Ingham for bp_name in bp_names: 487d92f7f79SJim Ingham bp = target.BreakpointCreateByName(bp_name) 488d92f7f79SJim Ingham bp.AddName("MyBKPTS") 489d92f7f79SJim Ingham bp_ids.append(bp.GetID()) 490d92f7f79SJim Ingham # First do it with a script one-liner: 491d92f7f79SJim Ingham self.runCmd("breakpoint command add -s py -o 'print(\"some command\")' MyBKPTS") 492d92f7f79SJim Ingham for id in bp_ids: 4932238dcc3SJonas Devlieghere self.expect( 4942238dcc3SJonas Devlieghere "breakpoint command list {0}".format(id), patterns=["some command"] 4952238dcc3SJonas Devlieghere ) 496d92f7f79SJim Ingham # Now do the same thing with a python function: 497d92f7f79SJim Ingham import side_effect 4982238dcc3SJonas Devlieghere 499d92f7f79SJim Ingham self.runCmd("command script import --allow-reload ./bktptcmd.py") 500d92f7f79SJim Ingham 5012238dcc3SJonas Devlieghere self.runCmd( 5022238dcc3SJonas Devlieghere "breakpoint command add --python-function bktptcmd.function MyBKPTS" 5032238dcc3SJonas Devlieghere ) 504d92f7f79SJim Ingham for id in bp_ids: 5052238dcc3SJonas Devlieghere self.expect( 5062238dcc3SJonas Devlieghere "breakpoint command list {0}".format(id), patterns=["bktptcmd.function"] 5072238dcc3SJonas Devlieghere ) 508d92f7f79SJim Ingham 5093726ac41SJim Ingham def test_breakpoint_delete_disabled(self): 5103726ac41SJim Ingham """Test 'break delete --disabled' works""" 5113726ac41SJim Ingham self.build() 51254c26872SRaphael Isemann target = self.createTestTarget() 5133726ac41SJim Ingham 5143726ac41SJim Ingham bp_1 = target.BreakpointCreateByName("main") 5153726ac41SJim Ingham bp_2 = target.BreakpointCreateByName("not_here") 5163726ac41SJim Ingham bp_3 = target.BreakpointCreateByName("main") 5173726ac41SJim Ingham bp_3.AddName("DeleteMeNot") 5183726ac41SJim Ingham 5193726ac41SJim Ingham bp_1.SetEnabled(False) 5203726ac41SJim Ingham bp_3.SetEnabled(False) 5213726ac41SJim Ingham 5223726ac41SJim Ingham bp_id_1 = bp_1.GetID() 5233726ac41SJim Ingham bp_id_2 = bp_2.GetID() 5243726ac41SJim Ingham bp_id_3 = bp_3.GetID() 5253726ac41SJim Ingham 5263726ac41SJim Ingham self.runCmd("breakpoint delete --disabled DeleteMeNot") 5273726ac41SJim Ingham 5283726ac41SJim Ingham bp_1 = target.FindBreakpointByID(bp_id_1) 5293726ac41SJim Ingham self.assertFalse(bp_1.IsValid(), "Didn't delete disabled breakpoint 1") 5303726ac41SJim Ingham 5313726ac41SJim Ingham bp_2 = target.FindBreakpointByID(bp_id_2) 5323726ac41SJim Ingham self.assertTrue(bp_2.IsValid(), "Deleted enabled breakpoint 2") 5333726ac41SJim Ingham 5343726ac41SJim Ingham bp_3 = target.FindBreakpointByID(bp_id_3) 5352238dcc3SJonas Devlieghere self.assertTrue( 5362238dcc3SJonas Devlieghere bp_3.IsValid(), "DeleteMeNot didn't protect disabled breakpoint 3" 5372238dcc3SJonas Devlieghere ) 5380018c712SJim Ingham 5390018c712SJim Ingham # Reset the first breakpoint, disable it, and do this again with no protected name: 5400018c712SJim Ingham bp_1 = target.BreakpointCreateByName("main") 5410018c712SJim Ingham 5420018c712SJim Ingham bp_1.SetEnabled(False) 5430018c712SJim Ingham 5440018c712SJim Ingham bp_id_1 = bp_1.GetID() 5450018c712SJim Ingham 5460018c712SJim Ingham self.runCmd("breakpoint delete --disabled") 5470018c712SJim Ingham 5480018c712SJim Ingham bp_1 = target.FindBreakpointByID(bp_id_1) 5490018c712SJim Ingham self.assertFalse(bp_1.IsValid(), "Didn't delete disabled breakpoint 1") 5500018c712SJim Ingham 5510018c712SJim Ingham bp_2 = target.FindBreakpointByID(bp_id_2) 5520018c712SJim Ingham self.assertTrue(bp_2.IsValid(), "Deleted enabled breakpoint 2") 5530018c712SJim Ingham 5540018c712SJim Ingham bp_3 = target.FindBreakpointByID(bp_id_3) 5550018c712SJim Ingham self.assertFalse(bp_3.IsValid(), "Didn't delete disabled breakpoint 3") 556dc9e6c52SJeffrey Tan 557dc9e6c52SJeffrey Tan def get_source_map_json(self): 558dc9e6c52SJeffrey Tan stream = lldb.SBStream() 559dc9e6c52SJeffrey Tan self.dbg.GetSetting("target.source-map").GetAsJSON(stream) 560dc9e6c52SJeffrey Tan return json.loads(stream.GetData()) 561dc9e6c52SJeffrey Tan 562dc9e6c52SJeffrey Tan def verify_source_map_entry_pair(self, entry, original, replacement): 56380fcecb1SJonas Devlieghere self.assertEqual( 5642238dcc3SJonas Devlieghere entry[0], original, "source map entry 'original' does not match" 5652238dcc3SJonas Devlieghere ) 56680fcecb1SJonas Devlieghere self.assertEqual( 5672238dcc3SJonas Devlieghere entry[1], replacement, "source map entry 'replacement' does not match" 5682238dcc3SJonas Devlieghere ) 569dc9e6c52SJeffrey Tan 570c5073ed5SJeffrey Tan def verify_source_map_deduce_statistics(self, target, expected_count): 571c5073ed5SJeffrey Tan stream = lldb.SBStream() 572c5073ed5SJeffrey Tan res = target.GetStatistics().GetAsJSON(stream) 573c5073ed5SJeffrey Tan self.assertTrue(res.Success()) 574c5073ed5SJeffrey Tan debug_stats = json.loads(stream.GetData()) 5751eeeab82SJordan Rupprecht self.assertIn( 5761eeeab82SJordan Rupprecht "targets", 5771eeeab82SJordan Rupprecht debug_stats, 5782238dcc3SJonas Devlieghere 'Make sure the "targets" key in in target.GetStatistics()', 5792238dcc3SJonas Devlieghere ) 5802238dcc3SJonas Devlieghere target_stats = debug_stats["targets"][0] 581c5073ed5SJeffrey Tan self.assertNotEqual(target_stats, None) 5822238dcc3SJonas Devlieghere self.assertEqual(target_stats["sourceMapDeduceCount"], expected_count) 583c5073ed5SJeffrey Tan 584dc9e6c52SJeffrey Tan @no_debug_info_test 585dc9e6c52SJeffrey Tan def test_breakpoints_auto_source_map_relative(self): 586dc9e6c52SJeffrey Tan """ 587dc9e6c52SJeffrey Tan Test that with target.auto-source-map-relative settings. 588dc9e6c52SJeffrey Tan 589dc9e6c52SJeffrey Tan The "relative.yaml" contains a line table that is: 590dc9e6c52SJeffrey Tan 591dc9e6c52SJeffrey Tan Line table for a/b/c/main.cpp in `a.out 592dc9e6c52SJeffrey Tan 0x0000000100003f94: a/b/c/main.cpp:1 593dc9e6c52SJeffrey Tan 0x0000000100003fb0: a/b/c/main.cpp:2:3 594dc9e6c52SJeffrey Tan 0x0000000100003fb8: a/b/c/main.cpp:2:3 595dc9e6c52SJeffrey Tan """ 596dc9e6c52SJeffrey Tan src_dir = self.getSourceDir() 597dc9e6c52SJeffrey Tan yaml_path = os.path.join(src_dir, "relative.yaml") 598dc9e6c52SJeffrey Tan yaml_base, ext = os.path.splitext(yaml_path) 599dc9e6c52SJeffrey Tan obj_path = self.getBuildArtifact("a.out") 600dc9e6c52SJeffrey Tan self.yaml2obj(yaml_path, obj_path) 601dc9e6c52SJeffrey Tan 602dc9e6c52SJeffrey Tan # Create a target with the object file we just created from YAML 603dc9e6c52SJeffrey Tan target = self.dbg.CreateTarget(obj_path) 604dc9e6c52SJeffrey Tan # We now have debug information with line table paths that start are 605dc9e6c52SJeffrey Tan # "./a/b/c/main.cpp". 606dc9e6c52SJeffrey Tan 607dc9e6c52SJeffrey Tan source_map_json = self.get_source_map_json() 60880fcecb1SJonas Devlieghere self.assertEqual( 6092238dcc3SJonas Devlieghere len(source_map_json), 0, "source map should be empty initially" 6102238dcc3SJonas Devlieghere ) 611c5073ed5SJeffrey Tan self.verify_source_map_deduce_statistics(target, 0) 612dc9e6c52SJeffrey Tan 613dc9e6c52SJeffrey Tan # Verify auto deduced source map when file path in debug info 614*4d9e7b14SDmitry Vasilyev # is a suffix of request breakpoint file path. 615*4d9e7b14SDmitry Vasilyev # Note the path must be absolute. 616*4d9e7b14SDmitry Vasilyev path = ( 617*4d9e7b14SDmitry Vasilyev "/x/y/a/b/c/main.cpp" 618*4d9e7b14SDmitry Vasilyev if lldbplatformutil.getHostPlatform() != "windows" 619*4d9e7b14SDmitry Vasilyev else r"C:\x\y\a\b\c\main.cpp" 620*4d9e7b14SDmitry Vasilyev ) 621dc9e6c52SJeffrey Tan bp = target.BreakpointCreateByLocation(path, 2) 6229c246882SJordan Rupprecht self.assertGreater( 6239c246882SJordan Rupprecht bp.GetNumLocations(), 6249c246882SJordan Rupprecht 0, 625dc9e6c52SJeffrey Tan 'Couldn\'t resolve breakpoint using full path "%s" in executate "%s" with ' 6262238dcc3SJonas Devlieghere "debug info that has relative path with matching suffix" 6272238dcc3SJonas Devlieghere % (path, self.getBuildArtifact("a.out")), 6282238dcc3SJonas Devlieghere ) 629dc9e6c52SJeffrey Tan 630dc9e6c52SJeffrey Tan source_map_json = self.get_source_map_json() 63180fcecb1SJonas Devlieghere self.assertEqual(len(source_map_json), 1, "source map should not be empty") 632*4d9e7b14SDmitry Vasilyev self.verify_source_map_entry_pair( 633*4d9e7b14SDmitry Vasilyev source_map_json[0], 634*4d9e7b14SDmitry Vasilyev ".", 635*4d9e7b14SDmitry Vasilyev "/x/y" if lldbplatformutil.getHostPlatform() != "windows" else r"C:\x\y", 636*4d9e7b14SDmitry Vasilyev ) 637c5073ed5SJeffrey Tan self.verify_source_map_deduce_statistics(target, 1) 638dc9e6c52SJeffrey Tan 639dc9e6c52SJeffrey Tan # Reset source map. 640dc9e6c52SJeffrey Tan self.runCmd("settings clear target.source-map") 641dc9e6c52SJeffrey Tan 642dc9e6c52SJeffrey Tan # Verify source map will not auto deduced when file path of request breakpoint 643dc9e6c52SJeffrey Tan # equals the file path in debug info. 644dc9e6c52SJeffrey Tan path = "a/b/c/main.cpp" 645dc9e6c52SJeffrey Tan bp = target.BreakpointCreateByLocation(path, 2) 6469c246882SJordan Rupprecht self.assertGreater( 6479c246882SJordan Rupprecht bp.GetNumLocations(), 6489c246882SJordan Rupprecht 0, 649dc9e6c52SJeffrey Tan 'Couldn\'t resolve breakpoint using full path "%s" in executate "%s" with ' 6502238dcc3SJonas Devlieghere "debug info that has relative path with matching suffix" 6512238dcc3SJonas Devlieghere % (path, self.getBuildArtifact("a.out")), 6522238dcc3SJonas Devlieghere ) 653dc9e6c52SJeffrey Tan 654dc9e6c52SJeffrey Tan source_map_json = self.get_source_map_json() 65580fcecb1SJonas Devlieghere self.assertEqual(len(source_map_json), 0, "source map should not be deduced") 65683263aecSJeffrey Tan 65783263aecSJeffrey Tan def test_breakpoint_statistics_hitcount(self): 65883263aecSJeffrey Tan """Test breakpoints statistics have hitCount field.""" 65983263aecSJeffrey Tan self.build() 66083263aecSJeffrey Tan target = self.createTestTarget() 66183263aecSJeffrey Tan 66283263aecSJeffrey Tan lldbutil.run_break_set_by_file_and_line( 6632238dcc3SJonas Devlieghere self, "main.c", self.line, num_expected_locations=1, loc_exact=True 6642238dcc3SJonas Devlieghere ) 66583263aecSJeffrey Tan 66683263aecSJeffrey Tan stream = lldb.SBStream() 66783263aecSJeffrey Tan res = target.GetStatistics().GetAsJSON(stream) 66883263aecSJeffrey Tan self.assertTrue(res.Success()) 66983263aecSJeffrey Tan debug_stats = json.loads(stream.GetData()) 6701eeeab82SJordan Rupprecht self.assertIn( 6711eeeab82SJordan Rupprecht "targets", 6721eeeab82SJordan Rupprecht debug_stats, 6732238dcc3SJonas Devlieghere 'Make sure the "targets" key in in target.GetStatistics()', 6742238dcc3SJonas Devlieghere ) 6752238dcc3SJonas Devlieghere target_stats = debug_stats["targets"][0] 67683263aecSJeffrey Tan self.assertNotEqual(target_stats, None) 67783263aecSJeffrey Tan 6782238dcc3SJonas Devlieghere breakpoints_stats = target_stats["breakpoints"] 67983263aecSJeffrey Tan self.assertNotEqual(breakpoints_stats, None) 68083263aecSJeffrey Tan for breakpoint_stats in breakpoints_stats: 68183263aecSJeffrey Tan self.assertIn("hitCount", breakpoint_stats) 68260b90b52SZequan Wu 683d3993ac1SZequan Wu @skipIf(oslist=no_match(["linux"])) 68460b90b52SZequan Wu def test_break_at__dl_debug_state(self): 68560b90b52SZequan Wu """ 68660b90b52SZequan Wu Test lldb is able to stop at _dl_debug_state if it is set before the 68760b90b52SZequan Wu process is launched. 68860b90b52SZequan Wu """ 68960b90b52SZequan Wu self.build() 69060b90b52SZequan Wu exe = self.getBuildArtifact("a.out") 69160b90b52SZequan Wu self.runCmd("target create %s" % exe) 69260b90b52SZequan Wu bpid = lldbutil.run_break_set_by_symbol( 693d3993ac1SZequan Wu self, "_dl_debug_state", num_expected_locations=-2 69460b90b52SZequan Wu ) 69560b90b52SZequan Wu self.runCmd("run") 69660b90b52SZequan Wu self.assertIsNotNone( 69760b90b52SZequan Wu lldbutil.get_one_thread_stopped_at_breakpoint_id(self.process(), bpid) 69860b90b52SZequan Wu ) 699