diff --git a/lldb/bindings/interface/SBTarget.i b/lldb/bindings/interface/SBTarget.i --- a/lldb/bindings/interface/SBTarget.i +++ b/lldb/bindings/interface/SBTarget.i @@ -579,6 +579,12 @@ uint32_t column, lldb::addr_t offset, SBFileSpecList &module_list); + lldb::SBBreakpoint + BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line, + uint32_t column, lldb::addr_t offset, + SBFileSpecList &module_list, + bool move_to_nearest_code); + lldb::SBBreakpoint BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL); diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -560,6 +560,12 @@ uint32_t column, lldb::addr_t offset, SBFileSpecList &module_list); + lldb::SBBreakpoint + BreakpointCreateByLocation(const lldb::SBFileSpec &file_spec, uint32_t line, + uint32_t column, lldb::addr_t offset, + SBFileSpecList &module_list, + bool move_to_nearest_code); + lldb::SBBreakpoint BreakpointCreateByName(const char *symbol_name, const char *module_name = nullptr); diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -787,6 +787,38 @@ return LLDB_RECORD_RESULT(sb_bp); } +SBBreakpoint SBTarget::BreakpointCreateByLocation( + const SBFileSpec &sb_file_spec, uint32_t line, uint32_t column, + lldb::addr_t offset, SBFileSpecList &sb_module_list, + bool move_to_nearest_code) { + LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByLocation, + (const lldb::SBFileSpec &, uint32_t, uint32_t, + lldb::addr_t, lldb::SBFileSpecList &, bool), + sb_file_spec, line, column, offset, sb_module_list, + move_to_nearest_code); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp && line != 0) { + std::lock_guard guard(target_sp->GetAPIMutex()); + + const LazyBool check_inlines = eLazyBoolCalculate; + const LazyBool skip_prologue = eLazyBoolCalculate; + const bool internal = false; + const bool hardware = false; + const FileSpecList *module_list = nullptr; + if (sb_module_list.GetSize() > 0) { + module_list = sb_module_list.get(); + } + sb_bp = target_sp->CreateBreakpoint( + module_list, *sb_file_spec, line, column, offset, check_inlines, + skip_prologue, internal, hardware, + move_to_nearest_code ? eLazyBoolYes : eLazyBoolNo); + } + + return LLDB_RECORD_RESULT(sb_bp); +} + SBBreakpoint SBTarget::BreakpointCreateByName(const char *symbol_name, const char *module_name) { LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName, @@ -2489,6 +2521,9 @@ BreakpointCreateByLocation, (const lldb::SBFileSpec &, uint32_t, uint32_t, lldb::addr_t, lldb::SBFileSpecList &)); + LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByLocation, + (const lldb::SBFileSpec &, uint32_t, uint32_t, + lldb::addr_t, lldb::SBFileSpecList &, bool)); LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName, (const char *, const char *)); LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName, diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py b/lldb/test/API/functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py --- a/lldb/test/API/functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py +++ b/lldb/test/API/functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py @@ -42,3 +42,30 @@ self.assertEqual(b_loc.GetLine(), 11) in_condition |= b_loc.GetColumn() < 30 self.assertTrue(in_condition) + + ## 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() + exe = self.getBuildArtifact("a.out") + + main_c = lldb.SBFileSpec("main.c") + line = line_number("main.c", "// Line 20.") + column = len("// Line 20") # should stop at the period. + indent = 2 + module_list = lldb.SBFileSpecList() + + # Create a target from the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + valid_bpt = target.BreakpointCreateByLocation(main_c, line, column, + indent, module_list, True) + self.assertTrue(valid_bpt, VALID_BREAKPOINT) + self.assertEqual(valid_bpt.GetNumLocations(), 1) + + invalid_bpt = target.BreakpointCreateByLocation(main_c, line, column, + indent, module_list, False) + self.assertTrue(invalid_bpt, VALID_BREAKPOINT) + self.assertEqual(invalid_bpt.GetNumLocations(), 0) +