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