diff --git a/lldb/bindings/interface/SBBreakpoint.i b/lldb/bindings/interface/SBBreakpoint.i --- a/lldb/bindings/interface/SBBreakpoint.i +++ b/lldb/bindings/interface/SBBreakpoint.i @@ -234,6 +234,8 @@ SBError AddLocation(SBAddress &address); + SBStructuredData SBBreakpoint::SerializeToStructuredData(); + static bool EventIsBreakpointEvent (const lldb::SBEvent &event); diff --git a/lldb/include/lldb/API/SBBreakpoint.h b/lldb/include/lldb/API/SBBreakpoint.h --- a/lldb/include/lldb/API/SBBreakpoint.h +++ b/lldb/include/lldb/API/SBBreakpoint.h @@ -140,7 +140,9 @@ // Can only be called from a ScriptedBreakpointResolver... SBError AddLocation(SBAddress &address); - + + SBStructuredData SerializeToStructuredData(); + private: friend class SBBreakpointList; friend class SBBreakpointLocation; diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp --- a/lldb/source/API/SBBreakpoint.cpp +++ b/lldb/source/API/SBBreakpoint.cpp @@ -575,7 +575,22 @@ return LLDB_RECORD_RESULT(error); } -void SBBreakpoint ::SetCallback(SBBreakpointHitCallback callback, void *baton) { +SBStructuredData SBBreakpoint::SerializeToStructuredData() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBStructuredData, SBBreakpoint, + SerializeToStructuredData); + + SBStructuredData data; + BreakpointSP bkpt_sp = GetSP(); + + if (!bkpt_sp) + return LLDB_RECORD_RESULT(data); + + StructuredData::ObjectSP bkpt_dict = bkpt_sp->SerializeToStructuredData(); + data.m_impl_up->SetObjectSP(bkpt_dict); + return LLDB_RECORD_RESULT(data); +} + +void SBBreakpoint::SetCallback(SBBreakpointHitCallback callback, void *baton) { LLDB_RECORD_DUMMY(void, SBBreakpoint, SetCallback, (lldb::SBBreakpointHitCallback, void *), callback, baton); @@ -1017,6 +1032,8 @@ (lldb::SBStream &, bool)); LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddLocation, (lldb::SBAddress &)); + LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBBreakpoint, + SerializeToStructuredData, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetScriptCallbackFunction, (const char *)); LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackFunction, diff --git a/lldb/test/API/functionalities/breakpoint/serialize/TestBreakpointSerialization.py b/lldb/test/API/functionalities/breakpoint/serialize/TestBreakpointSerialization.py --- a/lldb/test/API/functionalities/breakpoint/serialize/TestBreakpointSerialization.py +++ b/lldb/test/API/functionalities/breakpoint/serialize/TestBreakpointSerialization.py @@ -3,6 +3,7 @@ """ import os +import json import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -56,6 +57,41 @@ self.setup_targets_and_cleanup() self.do_check_extra_args() + def test_structured_data_serialization(self): + target = self.dbg.GetDummyTarget() + self.assertTrue(target.IsValid(), VALID_TARGET) + + interpreter = self.dbg.GetCommandInterpreter() + result = lldb.SBCommandReturnObject() + interpreter.HandleCommand("br set -f foo -l 42", result) + result = lldb.SBCommandReturnObject() + interpreter.HandleCommand("br set -c 'argc == 1' -n main", result) + + bkp1 = target.GetBreakpointAtIndex(0) + self.assertTrue(bkp1.IsValid(), VALID_BREAKPOINT) + stream = lldb.SBStream() + sd = bkp1.SerializeToStructuredData() + sd.GetAsJSON(stream) + serialized_data = json.loads(stream.GetData()) + self.assertEqual(serialized_data["Breakpoint"]["BKPTResolver"]["Options"]["FileName"], "foo") + self.assertEqual(serialized_data["Breakpoint"]["BKPTResolver"]["Options"]["LineNumber"], 42) + + bkp2 = target.GetBreakpointAtIndex(1) + self.assertTrue(bkp2.IsValid(), VALID_BREAKPOINT) + stream = lldb.SBStream() + sd = bkp2.SerializeToStructuredData() + sd.GetAsJSON(stream) + serialized_data = json.loads(stream.GetData()) + self.assertIn("main", serialized_data["Breakpoint"]["BKPTResolver"]["Options"]["SymbolNames"]) + self.assertEqual(serialized_data["Breakpoint"]["BKPTOptions"]["ConditionText"],"argc == 1") + + invalid_bkp = lldb.SBBreakpoint() + self.assertFalse(invalid_bkp.IsValid(), "Breakpoint should not be valid.") + stream = lldb.SBStream() + sd = invalid_bkp.SerializeToStructuredData() + sd.GetAsJSON(stream) + self.assertFalse(stream.GetData(), "Invalid breakpoint should have an empty structured data") + def setup_targets_and_cleanup(self): def cleanup (): self.RemoveTempFile(self.bkpts_file_path)