1""" 2Test setting a breakpoint by line and column. 3""" 4 5import re 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class BreakpointByLineAndColumnTestCase(TestBase): 13 ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info 14 @skipIf(compiler="gcc", compiler_version=["<", "7.1"]) 15 def testBreakpointByLineAndColumn(self): 16 self.build() 17 src_file = lldb.SBFileSpec("main.cpp") 18 line = ( 19 line_number("main.cpp", "At the beginning of a function name (col:50)") + 1 20 ) # Next line after comment 21 _, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self, src_file, line, 50) 22 self.expect("fr v did_call", substrs=["1"]) 23 in_then = False 24 for i in range(breakpoint.GetNumLocations()): 25 b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry() 26 self.assertEqual(b_loc.GetLine(), line) 27 in_then |= b_loc.GetColumn() == 50 28 self.assertTrue(in_then) 29 30 ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info 31 @skipIf(compiler="gcc", compiler_version=["<", "7.1"]) 32 def testBreakpointByLine(self): 33 self.build() 34 src_file = lldb.SBFileSpec("main.cpp") 35 line = ( 36 line_number("main.cpp", "At the beginning of a function name (col:50)") + 1 37 ) # Next line after comment 38 _, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self, src_file, line) 39 self.expect("fr v did_call", substrs=["0"]) 40 in_condition = False 41 for i in range(breakpoint.GetNumLocations()): 42 b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry() 43 self.assertEqual(b_loc.GetLine(), line) 44 in_condition |= b_loc.GetColumn() < 30 45 self.assertTrue(in_condition) 46 47 @skipIfWindows 48 ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info 49 @skipIf(compiler="gcc", compiler_version=["<", "7.1"]) 50 def testBreakpointByLineAndColumnNearestCode(self): 51 self.build() 52 53 patterns = [ 54 "In the middle of a function name (col:42)", 55 "In the middle of the lambda declaration argument (col:23)", 56 "Inside the lambda (col:26)", 57 ] 58 59 source_loc = [] 60 61 for pattern in patterns: 62 line = line_number("main.cpp", pattern) + 1 63 column = int(re.search("\(col:([0-9]+)\)", pattern).group(1)) 64 source_loc.append({"line": line, "column": column}) 65 66 target = self.createTestTarget() 67 68 for loc in source_loc: 69 src_file = lldb.SBFileSpec("main.cpp") 70 line = loc["line"] 71 column = loc["column"] 72 indent = 0 73 module_list = lldb.SBFileSpecList() 74 75 valid_bpkt = target.BreakpointCreateByLocation( 76 src_file, line, column, indent, module_list, True 77 ) 78 self.assertTrue(valid_bpkt, VALID_BREAKPOINT) 79 self.assertEqual(valid_bpkt.GetNumLocations(), 1) 80 81 process = target.LaunchSimple(None, None, self.get_process_working_directory()) 82 self.assertTrue(process, PROCESS_IS_VALID) 83 84 nearest_column = [7, 17, 26] 85 86 for idx, loc in enumerate(source_loc): 87 bpkt = target.GetBreakpointAtIndex(idx) 88 bpkt_loc = bpkt.GetLocationAtIndex(0) 89 self.assertEqual(bpkt_loc.GetHitCount(), 1) 90 self.assertSuccess(process.Continue()) 91 bpkt_loc_desc = lldb.SBStream() 92 self.assertTrue( 93 bpkt_loc.GetDescription(bpkt_loc_desc, lldb.eDescriptionLevelVerbose) 94 ) 95 self.assertIn( 96 "main.cpp:{}:{}".format(loc["line"], nearest_column[idx]), 97 bpkt_loc_desc.GetData(), 98 ) 99 bpkt_loc_addr = bpkt_loc.GetAddress() 100 self.assertTrue(bpkt_loc_addr) 101 102 list = target.FindCompileUnits(lldb.SBFileSpec("main.cpp", False)) 103 # Executable has been built just from one source file 'main.cpp', 104 # so we may check only the first element of list. 105 compile_unit = list[0].GetCompileUnit() 106 107 found = False 108 for line_entry in compile_unit: 109 if line_entry.GetStartAddress() == bpkt_loc_addr: 110 self.assertEqual(line_entry.GetFileSpec().GetFilename(), "main.cpp") 111 self.assertEqual(line_entry.GetLine(), loc["line"]) 112 self.assertEqual(line_entry.GetColumn(), nearest_column[idx]) 113 found = True 114 break 115 116 self.assertTrue(found) 117 118 line = line_number("main.cpp", "// This is a random comment.") 119 column = len("// This is a random comment.") 120 indent = 2 121 invalid_bpkt = target.BreakpointCreateByLocation( 122 src_file, line, column, indent, module_list, False 123 ) 124 self.assertTrue(invalid_bpkt, VALID_BREAKPOINT) 125 self.assertEqual(invalid_bpkt.GetNumLocations(), 0) 126