| """ |
| Test setting a breakpoint by line and column. |
| """ |
| |
| import re |
| import lldb |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import lldbutil |
| |
| |
| class BreakpointByLineAndColumnTestCase(TestBase): |
| ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info |
| @skipIf(compiler="gcc", compiler_version=["<", "7.1"]) |
| def testBreakpointByLineAndColumn(self): |
| self.build() |
| src_file = lldb.SBFileSpec("main.cpp") |
| line = ( |
| line_number("main.cpp", "At the beginning of a function name (col:50)") + 1 |
| ) # Next line after comment |
| _, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self, src_file, line, 50) |
| self.expect("fr v did_call", substrs=["1"]) |
| in_then = False |
| for i in range(breakpoint.GetNumLocations()): |
| b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry() |
| self.assertEqual(b_loc.GetLine(), line) |
| in_then |= b_loc.GetColumn() == 50 |
| self.assertTrue(in_then) |
| |
| ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info |
| @skipIf(compiler="gcc", compiler_version=["<", "7.1"]) |
| def testBreakpointByLine(self): |
| self.build() |
| src_file = lldb.SBFileSpec("main.cpp") |
| line = ( |
| line_number("main.cpp", "At the beginning of a function name (col:50)") + 1 |
| ) # Next line after comment |
| _, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self, src_file, line) |
| self.expect("fr v did_call", substrs=["0"]) |
| in_condition = False |
| for i in range(breakpoint.GetNumLocations()): |
| b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry() |
| self.assertEqual(b_loc.GetLine(), line) |
| in_condition |= b_loc.GetColumn() < 30 |
| self.assertTrue(in_condition) |
| |
| @skipIfWindows |
| ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info |
| @skipIf(compiler="gcc", compiler_version=["<", "7.1"]) |
| def testBreakpointByLineAndColumnNearestCode(self): |
| self.build() |
| |
| patterns = [ |
| "In the middle of a function name (col:42)", |
| "In the middle of the lambda declaration argument (col:23)", |
| "Inside the lambda (col:26)", |
| ] |
| |
| source_loc = [] |
| |
| for pattern in patterns: |
| line = line_number("main.cpp", pattern) + 1 |
| column = int(re.search("\(col:([0-9]+)\)", pattern).group(1)) |
| source_loc.append({"line": line, "column": column}) |
| |
| target = self.createTestTarget() |
| |
| for loc in source_loc: |
| src_file = lldb.SBFileSpec("main.cpp") |
| line = loc["line"] |
| column = loc["column"] |
| indent = 0 |
| module_list = lldb.SBFileSpecList() |
| |
| valid_bpkt = target.BreakpointCreateByLocation( |
| src_file, line, column, indent, module_list, True |
| ) |
| self.assertTrue(valid_bpkt, VALID_BREAKPOINT) |
| self.assertEqual(valid_bpkt.GetNumLocations(), 1) |
| |
| process = target.LaunchSimple(None, None, self.get_process_working_directory()) |
| self.assertTrue(process, PROCESS_IS_VALID) |
| |
| nearest_column = [7, 17, 26] |
| |
| for idx, loc in enumerate(source_loc): |
| bpkt = target.GetBreakpointAtIndex(idx) |
| bpkt_loc = bpkt.GetLocationAtIndex(0) |
| self.assertEqual(bpkt_loc.GetHitCount(), 1) |
| self.assertSuccess(process.Continue()) |
| bpkt_loc_desc = lldb.SBStream() |
| self.assertTrue( |
| bpkt_loc.GetDescription(bpkt_loc_desc, lldb.eDescriptionLevelVerbose) |
| ) |
| self.assertIn( |
| "main.cpp:{}:{}".format(loc["line"], nearest_column[idx]), |
| bpkt_loc_desc.GetData(), |
| ) |
| bpkt_loc_addr = bpkt_loc.GetAddress() |
| self.assertTrue(bpkt_loc_addr) |
| |
| list = target.FindCompileUnits(lldb.SBFileSpec("main.cpp", False)) |
| # Executable has been built just from one source file 'main.cpp', |
| # so we may check only the first element of list. |
| compile_unit = list[0].GetCompileUnit() |
| |
| found = False |
| for line_entry in compile_unit: |
| if line_entry.GetStartAddress() == bpkt_loc_addr: |
| self.assertEqual(line_entry.GetFileSpec().GetFilename(), "main.cpp") |
| self.assertEqual(line_entry.GetLine(), loc["line"]) |
| self.assertEqual(line_entry.GetColumn(), nearest_column[idx]) |
| found = True |
| break |
| |
| self.assertTrue(found) |
| |
| line = line_number("main.cpp", "// This is a random comment.") |
| column = len("// This is a random comment.") |
| indent = 2 |
| invalid_bpkt = target.BreakpointCreateByLocation( |
| src_file, line, column, indent, module_list, False |
| ) |
| self.assertTrue(invalid_bpkt, VALID_BREAKPOINT) |
| self.assertEqual(invalid_bpkt.GetNumLocations(), 0) |