From 18032327d2a09f86c84a73676d16f875d25b50af Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Thu, 21 Aug 2025 16:40:01 -0700 Subject: [PATCH 1/5] [lldb/API] Add setters to SBStructuredData (#154445) This patch adds setters to the SBStruturedData class to be able to initialize said object from the client side directly. Signed-off-by: Med Ismail Bennani (cherry picked from commit 05b1ec3724e1dbb88050ad2ae4c72e9832668ec9) (cherry picked from commit ef05e83323c6da6c09d28be074cbb0990ce62c74) --- lldb/include/lldb/API/SBStructuredData.h | 29 ++++++++++++ lldb/include/lldb/Core/StructuredDataImpl.h | 35 ++++++++++++++ lldb/include/lldb/Utility/StructuredData.h | 26 +++++++++- lldb/source/API/SBStructuredData.cpp | 44 +++++++++++++++++ .../sbstructureddata/TestStructuredDataAPI.py | 47 ++++++++++++++++++- 5 files changed, 179 insertions(+), 2 deletions(-) diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h index f96e169f236ed..dfd8ec0e180ce 100644 --- a/lldb/include/lldb/API/SBStructuredData.h +++ b/lldb/include/lldb/API/SBStructuredData.h @@ -109,6 +109,35 @@ class SBStructuredData { /// Return the generic pointer if this data structure is a generic type. lldb::SBScriptObject GetGenericValue() const; + /// Set the value corresponding to a key. If this data structure + /// is not a dictionary type, reset the type to be dictionary and overwrite + /// the previous data. + void SetValueForKey(const char *key, SBStructuredData &value); + + /// Change the type to unsigned interger and overwrite the previous data with + /// the new value. + void SetUnsignedIntegerValue(uint64_t value); + + /// Change the type to signed interger and overwrite the previous data with + /// the new value. + void SetSignedIntegerValue(int64_t value); + + /// Change the type to float and overwrite the previous data with the new + /// value. + void SetFloatValue(double value); + + /// Change the type to boolean and overwrite the previous data with the new + /// value. + void SetBooleanValue(bool value); + + /// Change the type to string and overwrite the previous data with the new + /// value. + void SetStringValue(const char *value); + + /// Change the type to generic and overwrite the previous data with the new + /// value. + void SetGenericValue(SBScriptObject value); + protected: friend class SBAttachInfo; friend class SBCommandReturnObject; diff --git a/lldb/include/lldb/Core/StructuredDataImpl.h b/lldb/include/lldb/Core/StructuredDataImpl.h index fd0a7b94d3a6c..b88962bc774dc 100644 --- a/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/lldb/include/lldb/Core/StructuredDataImpl.h @@ -81,6 +81,41 @@ class StructuredDataImpl { void SetObjectSP(const StructuredData::ObjectSP &obj) { m_data_sp = obj; } + void SetValueForKey(llvm::StringRef key, + const StructuredData::ObjectSP &value) { + if (!m_data_sp || + m_data_sp->GetType() != lldb::eStructuredDataTypeDictionary) { + m_data_sp = StructuredData::FromKeyValue(key, value); + } else if (StructuredData::Dictionary *dict = + m_data_sp->GetAsDictionary()) { + dict->AddItem(key, value); + } + } + + void SetUnsignedIntegerValue(uint64_t value) { + m_data_sp = StructuredData::FromInteger(value); + } + + void SetSignedIntegerValue(int64_t value) { + m_data_sp = StructuredData::FromInteger(value); + } + + void SetFloatValue(double value) { + m_data_sp = StructuredData::FromFloat(value); + } + + void SetBooleanValue(bool value) { + m_data_sp = StructuredData::FromBoolean(value); + } + + void SetStringValue(std::string value) { + m_data_sp = StructuredData::FromString(std::move(value)); + } + + void SetGenericValue(void *value) { + m_data_sp = StructuredData::FromGeneric(value); + } + lldb::StructuredDataType GetType() const { return (m_data_sp ? m_data_sp->GetType() : lldb::eStructuredDataTypeInvalid); diff --git a/lldb/include/lldb/Utility/StructuredData.h b/lldb/include/lldb/Utility/StructuredData.h index 5e63ef92fac3e..59a2fd60b3989 100644 --- a/lldb/include/lldb/Utility/StructuredData.h +++ b/lldb/include/lldb/Utility/StructuredData.h @@ -432,7 +432,7 @@ class StructuredData { } return success; } - + template bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const { ObjectSP value_sp = GetValueForKey(key); @@ -574,6 +574,30 @@ class StructuredData { void *m_object; }; + template static ObjectSP FromInteger(T value) { + return std::make_shared>(value); + } + + static StructuredData::ObjectSP FromFloat(double value) { + return std::make_shared(value); + } + static StructuredData::ObjectSP FromBoolean(bool value) { + return std::make_shared(value); + } + static StructuredData::ObjectSP FromString(std::string value) { + return std::make_shared(value); + } + static StructuredData::ObjectSP FromGeneric(void *value) { + return std::make_shared(value); + } + + static StructuredData::ObjectSP + FromKeyValue(llvm::StringRef key, const StructuredData::ObjectSP &value_sp) { + auto dict_sp = std::make_shared(); + dict_sp->AddItem(key, value_sp); + return dict_sp; + } + static ObjectSP ParseJSON(llvm::StringRef json_text); static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error); static bool IsRecordType(const ObjectSP object_sp); diff --git a/lldb/source/API/SBStructuredData.cpp b/lldb/source/API/SBStructuredData.cpp index b891a34bd7c76..8e2c18ed42b47 100644 --- a/lldb/source/API/SBStructuredData.cpp +++ b/lldb/source/API/SBStructuredData.cpp @@ -232,3 +232,47 @@ lldb::SBScriptObject SBStructuredData::GetGenericValue() const { return {m_impl_up->GetGenericValue(), eScriptLanguageDefault}; } + +void SBStructuredData::SetValueForKey(const char *key, + SBStructuredData &value) { + LLDB_INSTRUMENT_VA(this, key, value); + + if (StructuredData::ObjectSP obj_sp = value.m_impl_up->GetObjectSP()) + m_impl_up->SetValueForKey(key, obj_sp); +} + +void SBStructuredData::SetUnsignedIntegerValue(uint64_t value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetUnsignedIntegerValue(value); +} + +void SBStructuredData::SetSignedIntegerValue(int64_t value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetSignedIntegerValue(value); +} + +void SBStructuredData::SetFloatValue(double value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetFloatValue(value); +} + +void SBStructuredData::SetBooleanValue(bool value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetBooleanValue(value); +} + +void SBStructuredData::SetStringValue(const char *value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetStringValue(value); +} + +void SBStructuredData::SetGenericValue(SBScriptObject value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetGenericValue(value.GetPointer()); +} diff --git a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py index 21256d6c6e743..99f88d3da794a 100644 --- a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py +++ b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py @@ -10,7 +10,6 @@ import json - class TestStructuredDataAPI(TestBase): NO_DEBUG_INFO_TESTCASE = True @@ -130,6 +129,52 @@ class MyRandomClass: self.assertSuccess(example.SetFromJSON("null")) self.assertEqual(example.GetType(), lldb.eStructuredDataTypeNull) + example = lldb.SBStructuredData() + example.SetUnsignedIntegerValue(1) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeInteger) + self.assertEqual(example.GetIntegerValue(), 1) + + example.SetSignedIntegerValue(-42) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeSignedInteger) + self.assertEqual(example.GetSignedIntegerValue(), -42) + + example.SetFloatValue(4.19) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeFloat) + self.assertEqual(example.GetFloatValue(), 4.19) + + example.SetStringValue("Bonjour, 123!") + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeString) + self.assertEqual(example.GetStringValue(42), "Bonjour, 123!") + + value = lldb.SBStructuredData() + example.SetValueForKey("Hello", value) + self.assertEqual(example.GetSize(), 0) + + nested_obj = lldb.SBStructuredData() + nested_obj.SetStringValue("World") + example.SetValueForKey("Hello", nested_obj) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeDictionary) + nested_obj = None + nested_obj = example.GetValueForKey("Hello") + self.assertTrue(nested_obj.IsValid()) + self.assertEqual(nested_obj.GetType(), lldb.eStructuredDataTypeString) + self.assertEqual(nested_obj.GetStringValue(42), "World") + + example.SetBooleanValue(True) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeBoolean) + self.assertTrue(example.GetBooleanValue()) + + rnd_obj = MyRandomClass() + stp = lldb.SBScriptObject(rnd_obj, lldb.eScriptLanguagePython) + self.assertEqual(stp.ptr, rnd_obj) + + example.SetGenericValue(stp) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeGeneric) + + my_random_class = example.GetGenericValue() + self.assertTrue(my_random_class) + self.assertEqual(my_random_class.payload, MyRandomClass.payload) + example_arr = [1, 2.3, "4", {"5": False}] arr_str = json.dumps(example_arr) s.Clear() From cf5a10cebccc77ae4e2ce7495ee52529b959c018 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Thu, 21 Aug 2025 23:16:45 -0700 Subject: [PATCH 2/5] [lldb/crashlog] Avoid StopAtEntry when launch crashlog in interactive mode (#154651) In 88f409194, we changed the way the crashlog scripted process was launched since the previous approach required to parse the file twice, by stopping at entry, setting the crashlog object in the middle of the scripted process launch and resuming it. Since then, we've introduced SBScriptObject which allows to pass any arbitrary python object accross the SBAPI boundary to another scripted affordance. This patch make sure of that to include the parse crashlog object into the scripted process launch info dictionary, which eliviates the need to stop at entry. Signed-off-by: Med Ismail Bennani Signed-off-by: Med Ismail Bennani (cherry picked from commit 595148ab7680cf579bcbe405c5a49dcb791d46ab) (cherry picked from commit e4ed3f5991451aa6d58697a8595188fed1f949ea) --- lldb/examples/python/crashlog.py | 11 ++++++---- .../python/crashlog_scripted_process.py | 20 +++++++++++++------ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/lldb/examples/python/crashlog.py b/lldb/examples/python/crashlog.py index bb20f3a25c1c1..b466be6a62428 100755 --- a/lldb/examples/python/crashlog.py +++ b/lldb/examples/python/crashlog.py @@ -1540,13 +1540,19 @@ def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result): } ) ) + + crashlog_sd = lldb.SBStructuredData() + crashlog_sd.SetGenericValue( + lldb.SBScriptObject(crashlog, lldb.eScriptLanguagePython) + ) + structured_data.SetValueForKey("crashlog", crashlog_sd) + launch_info = lldb.SBLaunchInfo(None) launch_info.SetProcessPluginName("ScriptedProcess") launch_info.SetScriptedProcessClassName( "crashlog_scripted_process.CrashLogScriptedProcess" ) launch_info.SetScriptedProcessDictionary(structured_data) - launch_info.SetLaunchFlags(lldb.eLaunchFlagStopAtEntry) error = lldb.SBError() process = target.Launch(launch_info, error) @@ -1554,9 +1560,6 @@ def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result): if not process or error.Fail(): raise InteractiveCrashLogException("couldn't launch Scripted Process", error) - process.GetScriptedImplementation().set_crashlog(crashlog) - process.Continue() - if not options.skip_status: @contextlib.contextmanager diff --git a/lldb/examples/python/crashlog_scripted_process.py b/lldb/examples/python/crashlog_scripted_process.py index f54a8df0479e7..6c6eec8d12b96 100644 --- a/lldb/examples/python/crashlog_scripted_process.py +++ b/lldb/examples/python/crashlog_scripted_process.py @@ -10,8 +10,7 @@ class CrashLogScriptedProcess(ScriptedProcess): - def set_crashlog(self, crashlog): - self.crashlog = crashlog + def parse_crashlog(self): if self.crashlog.process_id: if type(self.crashlog.process_id) is int: self.pid = self.crashlog.process_id @@ -29,8 +28,6 @@ def set_crashlog(self, crashlog): if hasattr(self.crashlog, "asb"): self.extended_thread_info = self.crashlog.asb - crashlog.load_images(self.options, self.loaded_images) - for thread in self.crashlog.threads: if ( hasattr(thread, "app_specific_backtrace") @@ -92,10 +89,21 @@ def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData no_parallel_image_loading.GetBooleanValue() ) + self.crashlog = None + crashlog = args.GetValueForKey("crashlog") + if crashlog and crashlog.IsValid(): + if crashlog.GetType() == lldb.eStructuredDataTypeGeneric: + self.crashlog = crashlog.GetGenericValue() + + if not self.crashlog: + # Return error + return + self.pid = super().get_process_id() self.crashed_thread_idx = 0 self.exception = None self.extended_thread_info = None + self.parse_crashlog() def read_memory_at_address( self, addr: int, size: int, error: lldb.SBError @@ -104,8 +112,8 @@ def read_memory_at_address( return lldb.SBData() def get_loaded_images(self): - # TODO: Iterate over corefile_target modules and build a data structure - # from it. + if len(self.loaded_images) == 0: + self.crashlog.load_images(self.options, self.loaded_images) return self.loaded_images def should_stop(self) -> bool: From 54837b16f4b4b11d1b074d86dea239bac6a63cc5 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Wed, 3 Sep 2025 15:58:14 -0700 Subject: [PATCH 3/5] [lldb] Mark scripted frames as synthetic instead of artificial (#153117) This patch changes the way frames created from scripted affordances like Scripted Threads are displayed. Currently, they're marked artificial which is used usually for compiler generated frames. This patch changes that behaviour by introducing a new synthetic StackFrame kind and moves 'artificial' to be a distinct StackFrame attribut. On top of making these frames less confusing, this allows us to know when a frame was created from a scripted affordance. rdar://155949703 Signed-off-by: Med Ismail Bennani (cherry picked from commit 6c10ab8a3c7b212a73b4ad6673bad02cc34a28c4) (cherry picked from commit 9a81ba247c56c0f8e52fea1f8e55a1f95234f968) --- lldb/include/lldb/API/SBFrame.h | 2 ++ lldb/include/lldb/Core/FormatEntity.h | 1 + lldb/include/lldb/Target/StackFrame.h | 17 +++++++--- lldb/source/API/SBFrame.cpp | 16 ++++++++++ lldb/source/Core/CoreProperties.td | 4 +-- lldb/source/Core/FormatEntity.cpp | 14 ++++++++ .../Process/scripted/ScriptedThread.cpp | 4 ++- lldb/source/Target/StackFrame.cpp | 14 ++++---- lldb/source/Target/StackFrameList.cpp | 6 ++-- .../scripted_process/TestScriptedProcess.py | 2 +- .../app_specific_backtrace_crashlog.test | 32 +++++++++---------- .../interactive_crashlog_arm64_register.test | 30 ++++++++--------- .../Crashlog/interactive_crashlog_json.test | 30 ++++++++--------- .../Crashlog/interactive_crashlog_legacy.test | 30 ++++++++--------- .../last_exception_backtrace_crashlog.test | 32 +++++++++---------- .../skipped_status_interactive_crashlog.test | 30 ++++++++--------- lldb/unittests/Core/FormatEntityTest.cpp | 1 + 17 files changed, 156 insertions(+), 109 deletions(-) diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h index 2f8282b079148..acd9f3ae3a2bb 100644 --- a/lldb/include/lldb/API/SBFrame.h +++ b/lldb/include/lldb/API/SBFrame.h @@ -107,6 +107,8 @@ class LLDB_API SBFrame { bool IsArtificial() const; + bool IsSynthetic() const; + /// Return whether a frame recognizer decided this frame should not /// be displayes in backtraces etc. bool IsHidden() const; diff --git a/lldb/include/lldb/Core/FormatEntity.h b/lldb/include/lldb/Core/FormatEntity.h index d602edffb4c88..40916dc48a70b 100644 --- a/lldb/include/lldb/Core/FormatEntity.h +++ b/lldb/include/lldb/Core/FormatEntity.h @@ -80,6 +80,7 @@ struct Entry { FrameRegisterFlags, FrameRegisterByName, FrameIsArtificial, + FrameKind, ScriptFrame, FunctionID, FunctionDidChange, diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h index 9501a9e5dc395..d87a1eb9e4ed7 100644 --- a/lldb/include/lldb/Target/StackFrame.h +++ b/lldb/include/lldb/Target/StackFrame.h @@ -60,10 +60,9 @@ class StackFrame : public ExecutionContextScope, /// local variables. History, - /// An artificial stack frame (e.g. a synthesized result of inferring - /// missing tail call frames from a backtrace) with limited support for - /// local variables. - Artificial + /// An synthetic stack frame (e.g. a synthesized result from script + /// resource) possibly without support for local variables or register. + Synthetic }; /// Construct a StackFrame object without supplying a RegisterContextSP. @@ -109,7 +108,8 @@ class StackFrame : public ExecutionContextScope, StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind, - bool behaves_like_zeroth_frame, const SymbolContext *sc_ptr); + bool artificial, bool behaves_like_zeroth_frame, + const SymbolContext *sc_ptr); StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, @@ -400,6 +400,9 @@ class StackFrame : public ExecutionContextScope, /// true if this is an inlined frame. bool IsInlined(); + /// Query whether this frame is synthetic. + bool IsSynthetic() const; + /// Query whether this frame is part of a historical backtrace. bool IsHistorical() const; @@ -575,6 +578,10 @@ class StackFrame : public ExecutionContextScope, /// Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS. bool m_cfa_is_valid; Kind m_stack_frame_kind; + /// Is this an artificial stack frame (e.g. a synthesized result of inferring + /// missing tail call frames from a backtrace) with limited support for + /// local variables. Orthogonal to `StackFrame::Kind`. + bool m_artificial; /// Whether this frame behaves like the zeroth frame, in the sense /// that its pc value might not immediately follow a call (and thus might diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 0581989c47bf1..3c67deebc1bbf 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -1126,6 +1126,22 @@ bool SBFrame::IsArtificial() const { return false; } +bool SBFrame::IsSynthetic() const { + LLDB_INSTRUMENT_VA(this); + + llvm::Expected exe_ctx = + GetStoppedExecutionContext(m_opaque_sp); + if (!exe_ctx) { + LLDB_LOG_ERROR(GetLog(LLDBLog::API), exe_ctx.takeError(), "{0}"); + return false; + } + + if (StackFrame *frame = exe_ctx->GetFramePtr()) + return frame->IsSynthetic(); + + return false; +} + bool SBFrame::IsHidden() const { LLDB_INSTRUMENT_VA(this); diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index 2ebff3d4e28a1..48f254434701e 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -115,7 +115,7 @@ let Definition = "debugger" in { Desc<"The default disassembly format string to use when disassembling instruction sequences.">; def FrameFormat: Property<"frame-format", "FormatEntity">, Global, - DefaultStringValue<"frame #${frame.index}: ${ansi.fg.cyan}${frame.pc}${ansi.normal}{ ${module.file.basename}{`${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}{${function.is-optimized} [opt]}{${function.is-inlined} [inlined]}{${frame.is-artificial} [artificial]}\\\\n">, + DefaultStringValue<"frame #${frame.index}: ${ansi.fg.cyan}${frame.pc}${ansi.normal}{ ${module.file.basename}{`${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}${frame.kind}{${function.is-optimized} [opt]}{${function.is-inlined} [inlined]}{${frame.is-artificial} [artificial]}\\\\n">, Desc<"The default frame format string to use when displaying stack frame information for threads.">; def NotiftVoid: Property<"notify-void", "Boolean">, Global, @@ -289,7 +289,7 @@ let Definition = "debugger" in { Desc<"If true, LLDB will automatically escape non-printable and escape characters when formatting strings.">; def FrameFormatUnique: Property<"frame-format-unique", "FormatEntity">, Global, - DefaultStringValue<"frame #${frame.index}: ${ansi.fg.cyan}${frame.pc}${ansi.normal}{ ${module.file.basename}{`${function.name-without-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}{${function.is-optimized} [opt]}{${function.is-inlined} [inlined]}{${frame.is-artificial} [artificial]}\\\\n">, + DefaultStringValue<"frame #${frame.index}: ${ansi.fg.cyan}${frame.pc}${ansi.normal}{ ${module.file.basename}{`${function.name-without-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}${frame.kind}{${function.is-optimized} [opt]}{${function.is-inlined} [inlined]}{${frame.is-artificial} [artificial]}\\\\n">, Desc<"The default frame format string to use when displaying stack frame information for threads from thread backtrace unique.">; def ShowAutosuggestion: Property<"show-autosuggestion", "Boolean">, Global, diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp index 22e86fb361a11..5935143bbf6bc 100644 --- a/lldb/source/Core/FormatEntity.cpp +++ b/lldb/source/Core/FormatEntity.cpp @@ -108,6 +108,7 @@ constexpr Definition g_frame_child_entries[] = { Entry::DefinitionWithChildren("reg", EntryType::FrameRegisterByName, g_string_entry), Definition("is-artificial", EntryType::FrameIsArtificial), + Definition("kind", EntryType::FrameKind), }; constexpr Definition g_function_child_entries[] = { @@ -380,6 +381,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) { ENUM_TO_CSTR(FrameRegisterFlags); ENUM_TO_CSTR(FrameRegisterByName); ENUM_TO_CSTR(FrameIsArtificial); + ENUM_TO_CSTR(FrameKind); ENUM_TO_CSTR(ScriptFrame); ENUM_TO_CSTR(FunctionID); ENUM_TO_CSTR(FunctionDidChange); @@ -1755,6 +1757,18 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, return false; } + case Entry::Type::FrameKind: { + if (exe_ctx) + if (StackFrame *frame = exe_ctx->GetFramePtr()) { + if (frame->IsSynthetic()) + s.PutCString(" [synthetic]"); + else if (frame->IsHistorical()) + s.PutCString(" [history]"); + return true; + } + return false; + } + case Entry::Type::ScriptFrame: if (exe_ctx) { StackFrame *frame = exe_ctx->GetFramePtr(); diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index d0d1508e85172..45ad83e4ed671 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -200,13 +200,15 @@ bool ScriptedThread::LoadArtificialStackFrames() { lldb::addr_t cfa = LLDB_INVALID_ADDRESS; bool cfa_is_valid = false; + const bool artificial = false; const bool behaves_like_zeroth_frame = false; SymbolContext sc; symbol_addr.CalculateSymbolContext(&sc); StackFrameSP synth_frame_sp = std::make_shared( this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, - StackFrame::Kind::Artificial, behaves_like_zeroth_frame, &sc); + StackFrame::Kind::Synthetic, artificial, behaves_like_zeroth_frame, + &sc); if (!frames->SetFrameAtIndex(static_cast(idx), synth_frame_sp)) return ScriptedInterface::ErrorWithMessage( diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index a8b4ae5944f0a..2719da2ae4c55 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -58,14 +58,14 @@ using namespace lldb_private; StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, addr_t cfa, bool cfa_is_valid, addr_t pc, StackFrame::Kind kind, - bool behaves_like_zeroth_frame, + bool artificial, bool behaves_like_zeroth_frame, const SymbolContext *sc_ptr) : m_thread_wp(thread_sp), m_frame_index(frame_idx), m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(), m_id(pc, cfa, nullptr, thread_sp->GetProcess().get()), m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid), - m_stack_frame_kind(kind), + m_stack_frame_kind(kind), m_artificial(artificial), m_behaves_like_zeroth_frame(behaves_like_zeroth_frame), m_variable_list_sp(), m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(), m_mutex() { @@ -93,7 +93,7 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, m_id(pc, cfa, nullptr, thread_sp->GetProcess().get()), m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(), m_frame_base_error(), m_cfa_is_valid(true), - m_stack_frame_kind(StackFrame::Kind::Regular), + m_stack_frame_kind(StackFrame::Kind::Regular), m_artificial(false), m_behaves_like_zeroth_frame(behaves_like_zeroth_frame), m_variable_list_sp(), m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(), m_mutex() { @@ -121,7 +121,7 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, nullptr, thread_sp->GetProcess().get()), m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(), m_frame_base_error(), m_cfa_is_valid(true), - m_stack_frame_kind(StackFrame::Kind::Regular), + m_stack_frame_kind(StackFrame::Kind::Regular), m_artificial(false), m_behaves_like_zeroth_frame(behaves_like_zeroth_frame), m_variable_list_sp(), m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(), m_mutex() { @@ -1305,10 +1305,12 @@ bool StackFrame::IsHistorical() const { return m_stack_frame_kind == StackFrame::Kind::History; } -bool StackFrame::IsArtificial() const { - return m_stack_frame_kind == StackFrame::Kind::Artificial; +bool StackFrame::IsSynthetic() const { + return m_stack_frame_kind == StackFrame::Kind::Synthetic; } +bool StackFrame::IsArtificial() const { return m_artificial; } + bool StackFrame::IsHidden() { if (auto recognized_frame_sp = GetRecognizedFrame()) return recognized_frame_sp->ShouldHide(); diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp index d60c5b8012fb5..28c27f5763cdb 100644 --- a/lldb/source/Target/StackFrameList.cpp +++ b/lldb/source/Target/StackFrameList.cpp @@ -334,13 +334,14 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { addr_t pc = calleeInfo.address; // If the callee address refers to the call instruction, we do not want to // subtract 1 from this value. + const bool artificial = true; const bool behaves_like_zeroth_frame = calleeInfo.address_type == CallEdge::AddrType::Call; SymbolContext sc; callee->CalculateSymbolContext(&sc); auto synth_frame = std::make_shared( m_thread.shared_from_this(), frame_idx, concrete_frame_idx, cfa, - cfa_is_valid, pc, StackFrame::Kind::Artificial, + cfa_is_valid, pc, StackFrame::Kind::Regular, artificial, behaves_like_zeroth_frame, &sc); m_frames.push_back(synth_frame); LLDB_LOG(log, "Pushed frame {0} at {1:x}", callee->GetDisplayName(), pc); @@ -483,7 +484,8 @@ bool StackFrameList::FetchFramesUpTo(uint32_t end_idx, const bool cfa_is_valid = true; unwind_frame_sp = std::make_shared( m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid, - pc, StackFrame::Kind::Regular, behaves_like_zeroth_frame, nullptr); + pc, StackFrame::Kind::Regular, false, behaves_like_zeroth_frame, + nullptr); // Create synthetic tail call frames between the previous frame and the // newly-found frame. The new frame's index may change after this call, diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index 9519c576689d0..5916e62c44f2e 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -284,6 +284,6 @@ def cleanup(): break self.assertEqual(idx, int(reg.value, 16)) - self.assertTrue(frame.IsArtificial(), "Frame is not artificial") + self.assertTrue(frame.IsSynthetic(), "Frame is not synthetic") pc = frame.GetPCAddress().GetLoadAddress(target_0) self.assertEqual(pc, 0x0100001B00) diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test index 9c0510c34ccae..f680158fdf735 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test @@ -11,7 +11,7 @@ # CHECK: (lldb) process status --verbose # CHECK-NEXT: Process 96535 stopped # CHECK-NEXT: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0) -# CHECK-NEXT: frame #0: 0x00000001a08c7224{{.*}}[artificial] +# CHECK-NEXT: frame #0: 0x00000001a08c7224{{.*}}[synthetic] # CHECK: Extended Crash Information: # CHECK: Application Specific Information: # CHECK-NEXT: CoreFoundation: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** __boundsFail: index 10 beyond bounds [0 .. 3]' @@ -21,21 +21,21 @@ # CHECK: (lldb) thread backtrace --extended true # CHECK: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0) -# CHECK-NEXT: * frame #0: 0x00000001a08c7224{{.*}}[artificial] -# CHECK-NEXT: frame #1: 0x00000001a08fdceb{{.*}}[artificial] -# CHECK-NEXT: frame #2: 0x00000001a08372c7{{.*}}[artificial] -# CHECK-NEXT: frame #3: 0x00000001a08b7b17{{.*}}[artificial] -# CHECK-NEXT: frame #4: 0x00000001a08a7a0b{{.*}}[artificial] -# CHECK-NEXT: frame #5: 0x00000001a05ab763{{.*}}[artificial] -# CHECK-NEXT: frame #6: 0x00000001a08b6eb3{{.*}}[artificial] -# CHECK-NEXT: frame #7: 0x00000001a08b9c2b{{.*}}[artificial] -# CHECK-NEXT: frame #8: 0x00000001a08b9bd7{{.*}}[artificial] -# CHECK-NEXT: frame #9: 0x00000001a05a3007{{.*}}[artificial] -# CHECK-NEXT: frame #10: 0x00000001a0b3dcc3{{.*}}[artificial] -# CHECK-NEXT: frame #11: 0x00000001a0b46af3{{.*}}[artificial] -# CHECK-NEXT: frame #12: 0x00000001a09a12a3{{.*}}[artificial] -# CHECK-NEXT: frame #13: 0x00000001047e3ecf asi`main{{.*}}[artificial] -# CHECK-NEXT: frame #14: 0x00000001a05d3e4f{{.*}}[artificial] +# CHECK-NEXT: * frame #0: 0x00000001a08c7224{{.*}}[synthetic] +# CHECK-NEXT: frame #1: 0x00000001a08fdceb{{.*}}[synthetic] +# CHECK-NEXT: frame #2: 0x00000001a08372c7{{.*}}[synthetic] +# CHECK-NEXT: frame #3: 0x00000001a08b7b17{{.*}}[synthetic] +# CHECK-NEXT: frame #4: 0x00000001a08a7a0b{{.*}}[synthetic] +# CHECK-NEXT: frame #5: 0x00000001a05ab763{{.*}}[synthetic] +# CHECK-NEXT: frame #6: 0x00000001a08b6eb3{{.*}}[synthetic] +# CHECK-NEXT: frame #7: 0x00000001a08b9c2b{{.*}}[synthetic] +# CHECK-NEXT: frame #8: 0x00000001a08b9bd7{{.*}}[synthetic] +# CHECK-NEXT: frame #9: 0x00000001a05a3007{{.*}}[synthetic] +# CHECK-NEXT: frame #10: 0x00000001a0b3dcc3{{.*}}[synthetic] +# CHECK-NEXT: frame #11: 0x00000001a0b46af3{{.*}}[synthetic] +# CHECK-NEXT: frame #12: 0x00000001a09a12a3{{.*}}[synthetic] +# CHECK-NEXT: frame #13: 0x00000001047e3ecf asi`main{{.*}}[synthetic] +# CHECK-NEXT: frame #14: 0x00000001a05d3e4f{{.*}}[synthetic] # CHECK: thread #4294967295: tid = 0x0001, 0x00000001a0a58418{{.*}}, queue = 'Application Specific Backtrace' # CHECK-NEXT: frame #0: 0x00000001a0a58418{{.*}} diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_arm64_register.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_arm64_register.test index 3f572c3300c0f..9da21d9aab78d 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_arm64_register.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_arm64_register.test @@ -15,9 +15,9 @@ # CHECK: (lldb) thread backtrace # CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] # CHECK: (lldb) thread list # CHECK-NEXT: Process 22511 stopped @@ -27,20 +27,20 @@ # CHECK: (lldb) bt all # CHECK: thread #1, queue = 'com.apple.main-thread' -# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [artificial] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [synthetic] # CHECK-NEXT: thread #2 -# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK-NEXT:* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK: (lldb) register read # CHECK: General Purpose Registers: diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_json.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_json.test index 684be2846f78d..2509f2e88d9b2 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_json.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_json.test @@ -15,9 +15,9 @@ # CHECK: (lldb) thread backtrace # CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] # CHECK: (lldb) thread list # CHECK-NEXT: Process 22511 stopped @@ -27,17 +27,17 @@ # CHECK: (lldb) bt all # CHECK: thread #1, queue = 'com.apple.main-thread' -# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [artificial] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [synthetic] # CHECK-NEXT: thread #2 -# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK-NEXT:* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test index 271a4c2aa90f4..74ced35fcfae0 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test @@ -15,9 +15,9 @@ # CHECK: (lldb) thread backtrace # CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] # CHECK: (lldb) thread list # CHECK-NEXT: Process 22511 stopped @@ -27,17 +27,17 @@ # CHECK: (lldb) bt all # CHECK: thread #1 -# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [artificial] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [synthetic] # CHECK-NEXT: thread #2 -# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK-NEXT:* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/last_exception_backtrace_crashlog.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/last_exception_backtrace_crashlog.test index a17b7ac18a620..53c0732deb549 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/last_exception_backtrace_crashlog.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/last_exception_backtrace_crashlog.test @@ -11,7 +11,7 @@ # CHECK: (lldb) process status --verbose # CHECK-NEXT: Process 96535 stopped # CHECK-NEXT: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0) -# CHECK-NEXT: frame #0: 0x00000001a08c7224{{.*}}[artificial] +# CHECK-NEXT: frame #0: 0x00000001a08c7224{{.*}}[synthetic] # CHECK: Extended Crash Information: # CHECK: Application Specific Information: # CHECK-NEXT: CoreFoundation: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** __boundsFail: index 10 beyond bounds [0 .. 3]' @@ -21,21 +21,21 @@ # CHECK: (lldb) thread backtrace --extended true # CHECK: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0) -# CHECK-NEXT: * frame #0: 0x00000001a08c7224{{.*}}[artificial] -# CHECK-NEXT: frame #1: 0x00000001a08fdceb{{.*}}[artificial] -# CHECK-NEXT: frame #2: 0x00000001a08372c7{{.*}}[artificial] -# CHECK-NEXT: frame #3: 0x00000001a08b7b17{{.*}}[artificial] -# CHECK-NEXT: frame #4: 0x00000001a08a7a0b{{.*}}[artificial] -# CHECK-NEXT: frame #5: 0x00000001a05ab763{{.*}}[artificial] -# CHECK-NEXT: frame #6: 0x00000001a08b6eb3{{.*}}[artificial] -# CHECK-NEXT: frame #7: 0x00000001a08b9c2b{{.*}}[artificial] -# CHECK-NEXT: frame #8: 0x00000001a08b9bd7{{.*}}[artificial] -# CHECK-NEXT: frame #9: 0x00000001a05a3007{{.*}}[artificial] -# CHECK-NEXT: frame #10: 0x00000001a0b3dcc3{{.*}}[artificial] -# CHECK-NEXT: frame #11: 0x00000001a0b46af3{{.*}}[artificial] -# CHECK-NEXT: frame #12: 0x00000001a09a12a3{{.*}}[artificial] -# CHECK-NEXT: frame #13: 0x00000001047e3ecf asi`main{{.*}}[artificial] -# CHECK-NEXT: frame #14: 0x00000001a05d3e4f{{.*}}[artificial] +# CHECK-NEXT: * frame #0: 0x00000001a08c7224{{.*}}[synthetic] +# CHECK-NEXT: frame #1: 0x00000001a08fdceb{{.*}}[synthetic] +# CHECK-NEXT: frame #2: 0x00000001a08372c7{{.*}}[synthetic] +# CHECK-NEXT: frame #3: 0x00000001a08b7b17{{.*}}[synthetic] +# CHECK-NEXT: frame #4: 0x00000001a08a7a0b{{.*}}[synthetic] +# CHECK-NEXT: frame #5: 0x00000001a05ab763{{.*}}[synthetic] +# CHECK-NEXT: frame #6: 0x00000001a08b6eb3{{.*}}[synthetic] +# CHECK-NEXT: frame #7: 0x00000001a08b9c2b{{.*}}[synthetic] +# CHECK-NEXT: frame #8: 0x00000001a08b9bd7{{.*}}[synthetic] +# CHECK-NEXT: frame #9: 0x00000001a05a3007{{.*}}[synthetic] +# CHECK-NEXT: frame #10: 0x00000001a0b3dcc3{{.*}}[synthetic] +# CHECK-NEXT: frame #11: 0x00000001a0b46af3{{.*}}[synthetic] +# CHECK-NEXT: frame #12: 0x00000001a09a12a3{{.*}}[synthetic] +# CHECK-NEXT: frame #13: 0x00000001047e3ecf asi`main{{.*}}[synthetic] +# CHECK-NEXT: frame #14: 0x00000001a05d3e4f{{.*}}[synthetic] # CHECK: thread #4294967295: tid = 0x0001, 0x00000001a0a5840c{{.*}}, queue = 'Application Specific Backtrace' # CHECK-NEXT: frame #0: 0x00000001a0a5840c{{.*}} diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test index 52a185b8cf760..138cd2bdffc44 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test @@ -15,9 +15,9 @@ process status thread backtrace # CHECK: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] thread list # CHECK: Process 22511 stopped @@ -27,20 +27,20 @@ thread list bt all # CHECK: thread #1, queue = 'com.apple.main-thread' -# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [artificial] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [synthetic] # CHECK-NEXT: thread #2 -# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK-NEXT:* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] image list # CHECK: 11111111-2222-3333-4444-555555555555 {{.*}}bogus.dylib diff --git a/lldb/unittests/Core/FormatEntityTest.cpp b/lldb/unittests/Core/FormatEntityTest.cpp index e056b6fe7de52..309294a501883 100644 --- a/lldb/unittests/Core/FormatEntityTest.cpp +++ b/lldb/unittests/Core/FormatEntityTest.cpp @@ -117,6 +117,7 @@ constexpr llvm::StringRef lookupStrings[] = { "${frame.no-debug}", "${frame.reg.*}", "${frame.is-artificial}", + "${frame.kind}", "${function.id}", "${function.name}", "${function.name-without-args}", From b4cec9fb4195270e78a521d14248edd81da5d686 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Thu, 4 Sep 2025 16:01:33 -0700 Subject: [PATCH 4/5] [lldb] Introduce ScriptedFrame affordance (#149622) This patch introduces a new scripting affordance in lldb: `ScriptedFrame`. This allows user to produce mock stackframes in scripted threads and scripted processes from a python script. With this change, StackFrame can be synthetized from different sources: - Either from a dictionary containing a load address, and a frame index, which is the legacy way. - Or by creating a ScriptedFrame python object. One particularity of synthezising stackframes from the ScriptedFrame python object, is that these frame have an optional PC, meaning that they don't have a report a valid PC and they can act as shells that just contain static information, like the frame function name, the list of variables or registers, etc. It can also provide a symbol context. rdar://157260006 (cherry picked from commit 84b56202fbe150e06f92c855107489e08cc17bcd) Signed-off-by: Med Ismail Bennani (cherry picked from commit 1e6108d477e87e5a97266c4159222435c6055588) --- .../python/templates/scripted_process.py | 136 +++++++++++++ lldb/include/lldb/API/SBSymbolContext.h | 1 + .../Interfaces/ScriptedFrameInterface.h | 55 +++++ .../Interfaces/ScriptedThreadInterface.h | 10 + .../lldb/Interpreter/ScriptInterpreter.h | 5 + lldb/include/lldb/Target/StackFrame.h | 34 ++-- lldb/include/lldb/lldb-forward.h | 3 + lldb/source/Core/FormatEntity.cpp | 2 +- .../Plugins/Process/scripted/CMakeLists.txt | 1 + .../Process/scripted/ScriptedFrame.cpp | 191 ++++++++++++++++++ .../Plugins/Process/scripted/ScriptedFrame.h | 63 ++++++ .../Process/scripted/ScriptedThread.cpp | 82 +++++++- .../Plugins/Process/scripted/ScriptedThread.h | 5 +- .../Python/Interfaces/CMakeLists.txt | 1 + .../ScriptInterpreterPythonInterfaces.h | 1 + .../ScriptedFramePythonInterface.cpp | 157 ++++++++++++++ .../Interfaces/ScriptedFramePythonInterface.h | 59 ++++++ .../Interfaces/ScriptedPythonInterface.cpp | 3 +- .../ScriptedThreadPythonInterface.cpp | 17 ++ .../ScriptedThreadPythonInterface.h | 5 + .../Python/ScriptInterpreterPython.cpp | 5 + .../Python/ScriptInterpreterPythonImpl.h | 2 + .../dummy_scripted_process.py | 65 +++++- 23 files changed, 871 insertions(+), 32 deletions(-) create mode 100644 lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h create mode 100644 lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp create mode 100644 lldb/source/Plugins/Process/scripted/ScriptedFrame.h create mode 100644 lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp create mode 100644 lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h diff --git a/lldb/examples/python/templates/scripted_process.py b/lldb/examples/python/templates/scripted_process.py index b6360b8519077..49059d533f38a 100644 --- a/lldb/examples/python/templates/scripted_process.py +++ b/lldb/examples/python/templates/scripted_process.py @@ -383,6 +383,142 @@ def get_extended_info(self): """ return self.extended_info + def get_scripted_frame_plugin(self): + """Get scripted frame plugin name. + + Returns: + str: Name of the scripted frame plugin. + """ + return None + + +class ScriptedFrame(metaclass=ABCMeta): + """ + The base class for a scripted frame. + + Most of the base class methods are `@abstractmethod` that need to be + overwritten by the inheriting class. + """ + + @abstractmethod + def __init__(self, thread, args): + """Construct a scripted frame. + + Args: + thread (ScriptedThread): The thread owning this frame. + args (lldb.SBStructuredData): A Dictionary holding arbitrary + key/value pairs used by the scripted frame. + """ + self.target = None + self.originating_thread = None + self.thread = None + self.args = None + self.id = None + self.name = None + self.register_info = None + self.register_ctx = {} + self.variables = [] + + if ( + isinstance(thread, ScriptedThread) + or isinstance(thread, lldb.SBThread) + and thread.IsValid() + ): + self.target = thread.target + self.process = thread.process + self.originating_thread = thread + self.thread = self.process.GetThreadByIndexID(thread.tid) + self.get_register_info() + + @abstractmethod + def get_id(self): + """Get the scripted frame identifier. + + Returns: + int: The identifier of the scripted frame in the scripted thread. + """ + pass + + def get_pc(self): + """Get the scripted frame address. + + Returns: + int: The optional address of the scripted frame in the scripted thread. + """ + return None + + def get_symbol_context(self): + """Get the scripted frame symbol context. + + Returns: + lldb.SBSymbolContext: The symbol context of the scripted frame in the scripted thread. + """ + return None + + def is_inlined(self): + """Check if the scripted frame is inlined. + + Returns: + bool: True if scripted frame is inlined. False otherwise. + """ + return False + + def is_artificial(self): + """Check if the scripted frame is artificial. + + Returns: + bool: True if scripted frame is artificial. False otherwise. + """ + return True + + def is_hidden(self): + """Check if the scripted frame is hidden. + + Returns: + bool: True if scripted frame is hidden. False otherwise. + """ + return False + + def get_function_name(self): + """Get the scripted frame function name. + + Returns: + str: The function name of the scripted frame. + """ + return self.name + + def get_display_function_name(self): + """Get the scripted frame display function name. + + Returns: + str: The display function name of the scripted frame. + """ + return self.get_function_name() + + def get_variables(self, filters): + """Get the scripted thread state type. + + Args: + filter (lldb.SBVariablesOptions): The filter used to resolve the variables + Returns: + lldb.SBValueList: The SBValueList containing the SBValue for each resolved variable. + Returns None by default. + """ + return None + + def get_register_info(self): + if self.register_info is None: + self.register_info = self.originating_thread.get_register_info() + return self.register_info + + @abstractmethod + def get_register_context(self): + """Get the scripted thread register context + + Returns: + str: A byte representing all register's value. + """ + pass class PassthroughScriptedProcess(ScriptedProcess): driving_target = None diff --git a/lldb/include/lldb/API/SBSymbolContext.h b/lldb/include/lldb/API/SBSymbolContext.h index 128b0b65b7860..19f29c629d094 100644 --- a/lldb/include/lldb/API/SBSymbolContext.h +++ b/lldb/include/lldb/API/SBSymbolContext.h @@ -66,6 +66,7 @@ class LLDB_API SBSymbolContext { friend class SBTarget; friend class SBSymbolContextList; + friend class lldb_private::ScriptInterpreter; friend class lldb_private::python::SWIGBridge; SBSymbolContext(const lldb_private::SymbolContext &sc_ptr); diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h new file mode 100644 index 0000000000000..8ef4b37d6ba12 --- /dev/null +++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H +#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H + +#include "ScriptedInterface.h" +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/lldb-private.h" +#include +#include + +namespace lldb_private { +class ScriptedFrameInterface : virtual public ScriptedInterface { +public: + virtual llvm::Expected + CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp, + StructuredData::Generic *script_obj = nullptr) = 0; + + virtual lldb::user_id_t GetID() { return LLDB_INVALID_FRAME_ID; } + + virtual lldb::addr_t GetPC() { return LLDB_INVALID_ADDRESS; } + + virtual std::optional GetSymbolContext() { + return std::nullopt; + } + + virtual std::optional GetFunctionName() { return std::nullopt; } + + virtual std::optional GetDisplayFunctionName() { + return std::nullopt; + } + + virtual bool IsInlined() { return false; } + + virtual bool IsArtificial() { return false; } + + virtual bool IsHidden() { return false; } + + virtual StructuredData::DictionarySP GetRegisterInfo() { return {}; } + + virtual std::optional GetRegisterContext() { + return std::nullopt; + } +}; +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h index a7cfc690b67dc..bc58f344d36f8 100644 --- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h +++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h @@ -44,6 +44,16 @@ class ScriptedThreadInterface : virtual public ScriptedInterface { } virtual StructuredData::ArraySP GetExtendedInfo() { return {}; } + + virtual std::optional GetScriptedFramePluginName() { + return std::nullopt; + } + +protected: + friend class ScriptedFrame; + virtual lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() { + return {}; + } }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index dffb9b82abf3d..024bbc90a9a39 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -26,6 +26,7 @@ #include "lldb/Host/PseudoTerminal.h" #include "lldb/Host/StreamFile.h" #include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h" +#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h" #include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h" #include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h" #include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h" @@ -531,6 +532,10 @@ class ScriptInterpreter : public PluginInterface { return {}; } + virtual lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() { + return {}; + } + virtual lldb::ScriptedThreadPlanInterfaceSP CreateScriptedThreadPlanInterface() { return {}; diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h index d87a1eb9e4ed7..f82f1090ce1ef 100644 --- a/lldb/include/lldb/Target/StackFrame.h +++ b/lldb/include/lldb/Target/StackFrame.h @@ -398,7 +398,7 @@ class StackFrame : public ExecutionContextScope, /// /// \return /// true if this is an inlined frame. - bool IsInlined(); + virtual bool IsInlined(); /// Query whether this frame is synthetic. bool IsSynthetic() const; @@ -409,12 +409,12 @@ class StackFrame : public ExecutionContextScope, /// Query whether this frame is artificial (e.g a synthesized result of /// inferring missing tail call frames from a backtrace). Artificial frames /// may have limited support for inspecting variables. - bool IsArtificial() const; + virtual bool IsArtificial() const; /// Query whether this frame should be hidden from backtraces. Frame /// recognizers can customize this behavior and hide distracting /// system implementation details this way. - bool IsHidden(); + virtual bool IsHidden(); /// Query whether this frame is a Swift Thunk. LLDB_DEPRECATED("Use IsHidden() instead.") @@ -429,13 +429,13 @@ class StackFrame : public ExecutionContextScope, /// /// /// \return /// A C-String containing the function demangled name. Can be null. - const char *GetFunctionName(); + virtual const char *GetFunctionName(); /// Get the frame's demangled display name. /// /// /// \return /// A C-String containing the function demangled display name. Can be null. - const char *GetDisplayFunctionName(); + virtual const char *GetDisplayFunctionName(); /// Query this frame to find what frame it is in this Thread's /// StackFrameList. @@ -547,18 +547,7 @@ class StackFrame : public ExecutionContextScope, bool HasCachedData() const; -private: - /// Private methods, called from GetValueForVariableExpressionPath. - /// See that method for documentation of parameters and return value. - lldb::ValueObjectSP LegacyGetValueForVariableExpressionPath( - llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, - uint32_t options, lldb::VariableSP &var_sp, Status &error); - - lldb::ValueObjectSP DILGetValueForVariableExpressionPath( - llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, - uint32_t options, lldb::VariableSP &var_sp, Status &error); - - /// For StackFrame only. + /// For StackFrame and derived classes only. /// \{ lldb::ThreadWP m_thread_wp; uint32_t m_frame_index; @@ -595,6 +584,17 @@ class StackFrame : public ExecutionContextScope, StreamString m_disassembly; std::recursive_mutex m_mutex; +private: + /// Private methods, called from GetValueForVariableExpressionPath. + /// See that method for documentation of parameters and return value. + lldb::ValueObjectSP LegacyGetValueForVariableExpressionPath( + llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, + uint32_t options, lldb::VariableSP &var_sp, Status &error); + + lldb::ValueObjectSP DILGetValueForVariableExpressionPath( + llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, + uint32_t options, lldb::VariableSP &var_sp, Status &error); + StackFrame(const StackFrame &) = delete; const StackFrame &operator=(const StackFrame &) = delete; }; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 483dce98ea427..af5656b3dcad1 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -187,6 +187,7 @@ class SaveCoreOptions; class Scalar; class ScriptInterpreter; class ScriptInterpreterLocker; +class ScriptedFrameInterface; class ScriptedMetadata; class ScriptedBreakpointInterface; class ScriptedPlatformInterface; @@ -408,6 +409,8 @@ typedef std::shared_ptr typedef std::shared_ptr ScriptSummaryFormatSP; typedef std::shared_ptr ScriptInterpreterSP; +typedef std::shared_ptr + ScriptedFrameInterfaceSP; typedef std::shared_ptr ScriptedMetadataSP; typedef std::unique_ptr ScriptedPlatformInterfaceUP; diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp index 5935143bbf6bc..b3274db6a3f51 100644 --- a/lldb/source/Core/FormatEntity.cpp +++ b/lldb/source/Core/FormatEntity.cpp @@ -1689,7 +1689,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, StackFrame *frame = exe_ctx->GetFramePtr(); if (frame) { const Address &pc_addr = frame->GetFrameCodeAddress(); - if (pc_addr.IsValid()) { + if (pc_addr.IsValid() || frame->IsSynthetic()) { if (DumpAddressAndContent(s, sc, exe_ctx, pc_addr, false)) return true; } diff --git a/lldb/source/Plugins/Process/scripted/CMakeLists.txt b/lldb/source/Plugins/Process/scripted/CMakeLists.txt index 590166591a41e..1516ad3132e3b 100644 --- a/lldb/source/Plugins/Process/scripted/CMakeLists.txt +++ b/lldb/source/Plugins/Process/scripted/CMakeLists.txt @@ -1,6 +1,7 @@ add_lldb_library(lldbPluginScriptedProcess PLUGIN ScriptedProcess.cpp ScriptedThread.cpp + ScriptedFrame.cpp LINK_COMPONENTS BinaryFormat diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp new file mode 100644 index 0000000000000..6519df9185df0 --- /dev/null +++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp @@ -0,0 +1,191 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ScriptedFrame.h" + +#include "lldb/Utility/DataBufferHeap.h" + +using namespace lldb; +using namespace lldb_private; + +void ScriptedFrame::CheckInterpreterAndScriptObject() const { + lldbassert(m_script_object_sp && "Invalid Script Object."); + lldbassert(GetInterface() && "Invalid Scripted Frame Interface."); +} + +llvm::Expected> +ScriptedFrame::Create(ScriptedThread &thread, + StructuredData::DictionarySP args_sp, + StructuredData::Generic *script_object) { + if (!thread.IsValid()) + return llvm::createStringError("Invalid scripted thread."); + + thread.CheckInterpreterAndScriptObject(); + + auto scripted_frame_interface = + thread.GetInterface()->CreateScriptedFrameInterface(); + if (!scripted_frame_interface) + return llvm::createStringError("failed to create scripted frame interface"); + + llvm::StringRef frame_class_name; + if (!script_object) { + std::optional class_name = + thread.GetInterface()->GetScriptedFramePluginName(); + if (!class_name || class_name->empty()) + return llvm::createStringError( + "failed to get scripted thread class name"); + frame_class_name = *class_name; + } + + ExecutionContext exe_ctx(thread); + auto obj_or_err = scripted_frame_interface->CreatePluginObject( + frame_class_name, exe_ctx, args_sp, script_object); + + if (!obj_or_err) + return llvm::createStringError( + "failed to create script object: %s", + llvm::toString(obj_or_err.takeError()).c_str()); + + StructuredData::GenericSP owned_script_object_sp = *obj_or_err; + + if (!owned_script_object_sp->IsValid()) + return llvm::createStringError("created script object is invalid"); + + lldb::user_id_t frame_id = scripted_frame_interface->GetID(); + + lldb::addr_t pc = scripted_frame_interface->GetPC(); + SymbolContext sc; + Address symbol_addr; + if (pc != LLDB_INVALID_ADDRESS) { + symbol_addr.SetLoadAddress(pc, &thread.GetProcess()->GetTarget()); + symbol_addr.CalculateSymbolContext(&sc); + } + + std::optional maybe_sym_ctx = + scripted_frame_interface->GetSymbolContext(); + if (maybe_sym_ctx) { + sc = *maybe_sym_ctx; + } + + StructuredData::DictionarySP reg_info = + scripted_frame_interface->GetRegisterInfo(); + + if (!reg_info) + return llvm::createStringError( + "failed to get scripted thread registers info"); + + std::shared_ptr register_info_sp = + DynamicRegisterInfo::Create( + *reg_info, thread.GetProcess()->GetTarget().GetArchitecture()); + + lldb::RegisterContextSP reg_ctx_sp; + + std::optional reg_data = + scripted_frame_interface->GetRegisterContext(); + if (reg_data) { + DataBufferSP data_sp( + std::make_shared(reg_data->c_str(), reg_data->size())); + + if (!data_sp->GetByteSize()) + return llvm::createStringError("failed to copy raw registers data"); + + std::shared_ptr reg_ctx_memory = + std::make_shared( + thread, frame_id, *register_info_sp, LLDB_INVALID_ADDRESS); + if (!reg_ctx_memory) + return llvm::createStringError("failed to create a register context."); + + reg_ctx_memory->SetAllRegisterData(data_sp); + reg_ctx_sp = reg_ctx_memory; + } + + return std::make_shared( + thread, scripted_frame_interface, frame_id, pc, sc, reg_ctx_sp, + register_info_sp, owned_script_object_sp); +} + +ScriptedFrame::ScriptedFrame(ScriptedThread &thread, + ScriptedFrameInterfaceSP interface_sp, + lldb::user_id_t id, lldb::addr_t pc, + SymbolContext &sym_ctx, + lldb::RegisterContextSP reg_ctx_sp, + std::shared_ptr reg_info_sp, + StructuredData::GenericSP script_object_sp) + : StackFrame(thread.shared_from_this(), /*frame_idx=*/id, + /*concrete_frame_idx=*/id, /*reg_context_sp=*/reg_ctx_sp, + /*cfa=*/0, /*pc=*/pc, + /*behaves_like_zeroth_frame=*/!id, /*symbol_ctx=*/&sym_ctx), + m_scripted_frame_interface_sp(interface_sp), + m_script_object_sp(script_object_sp), m_register_info_sp(reg_info_sp) {} + +ScriptedFrame::~ScriptedFrame() {} + +const char *ScriptedFrame::GetFunctionName() { + CheckInterpreterAndScriptObject(); + std::optional function_name = GetInterface()->GetFunctionName(); + if (!function_name) + return nullptr; + return ConstString(function_name->c_str()).AsCString(); +} + +const char *ScriptedFrame::GetDisplayFunctionName() { + CheckInterpreterAndScriptObject(); + std::optional function_name = + GetInterface()->GetDisplayFunctionName(); + if (!function_name) + return nullptr; + return ConstString(function_name->c_str()).AsCString(); +} + +bool ScriptedFrame::IsInlined() { return GetInterface()->IsInlined(); } + +bool ScriptedFrame::IsArtificial() const { + return GetInterface()->IsArtificial(); +} + +bool ScriptedFrame::IsHidden() { return GetInterface()->IsHidden(); } + +lldb::ScriptedFrameInterfaceSP ScriptedFrame::GetInterface() const { + return m_scripted_frame_interface_sp; +} + +std::shared_ptr ScriptedFrame::GetDynamicRegisterInfo() { + CheckInterpreterAndScriptObject(); + + if (!m_register_info_sp) { + StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo(); + + Status error; + if (!reg_info) + return ScriptedInterface::ErrorWithMessage< + std::shared_ptr>( + LLVM_PRETTY_FUNCTION, "Failed to get scripted frame registers info.", + error, LLDBLog::Thread); + + ThreadSP thread_sp = m_thread_wp.lock(); + if (!thread_sp || !thread_sp->IsValid()) + return ScriptedInterface::ErrorWithMessage< + std::shared_ptr>( + LLVM_PRETTY_FUNCTION, + "Failed to get scripted frame registers info: invalid thread.", error, + LLDBLog::Thread); + + ProcessSP process_sp = thread_sp->GetProcess(); + if (!process_sp || !process_sp->IsValid()) + return ScriptedInterface::ErrorWithMessage< + std::shared_ptr>( + LLVM_PRETTY_FUNCTION, + "Failed to get scripted frame registers info: invalid process.", + error, LLDBLog::Thread); + + m_register_info_sp = DynamicRegisterInfo::Create( + *reg_info, process_sp->GetTarget().GetArchitecture()); + } + + return m_register_info_sp; +} diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.h b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h new file mode 100644 index 0000000000000..6e01e2fd7653e --- /dev/null +++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_SCRIPTED_FRAME_H +#define LLDB_SOURCE_PLUGINS_SCRIPTED_FRAME_H + +#include "Plugins/Process/Utility/RegisterContextMemory.h" +#include "ScriptedThread.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target/DynamicRegisterInfo.h" +#include "lldb/Target/StackFrame.h" +#include + +namespace lldb_private { +class ScriptedThread; +} + +namespace lldb_private { + +class ScriptedFrame : public lldb_private::StackFrame { + +public: + ScriptedFrame(ScriptedThread &thread, + lldb::ScriptedFrameInterfaceSP interface_sp, + lldb::user_id_t frame_idx, lldb::addr_t pc, + SymbolContext &sym_ctx, lldb::RegisterContextSP reg_ctx_sp, + std::shared_ptr reg_info_sp, + StructuredData::GenericSP script_object_sp = nullptr); + + ~ScriptedFrame() override; + + static llvm::Expected> + Create(ScriptedThread &thread, StructuredData::DictionarySP args_sp, + StructuredData::Generic *script_object = nullptr); + + bool IsInlined() override; + bool IsArtificial() const override; + bool IsHidden() override; + const char *GetFunctionName() override; + const char *GetDisplayFunctionName() override; + +private: + void CheckInterpreterAndScriptObject() const; + lldb::ScriptedFrameInterfaceSP GetInterface() const; + + ScriptedFrame(const ScriptedFrame &) = delete; + const ScriptedFrame &operator=(const ScriptedFrame &) = delete; + + std::shared_ptr GetDynamicRegisterInfo(); + + lldb::ScriptedFrameInterfaceSP m_scripted_frame_interface_sp; + lldb_private::StructuredData::GenericSP m_script_object_sp; + std::shared_ptr m_register_info_sp; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_SCRIPTED_FRAME_H diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index 45ad83e4ed671..491efac5aadef 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ScriptedThread.h" +#include "ScriptedFrame.h" #include "Plugins/Process/Utility/RegisterContextThreadMemory.h" #include "Plugins/Process/Utility/StopInfoMachException.h" @@ -173,27 +174,31 @@ bool ScriptedThread::LoadArtificialStackFrames() { .str(), error, LLDBLog::Thread); - StackFrameListSP frames = GetStackFrameList(); - - for (size_t idx = 0; idx < arr_size; idx++) { + auto create_frame_from_dict = + [this, arr_sp](size_t idx) -> llvm::Expected { + Status error; std::optional maybe_dict = arr_sp->GetItemAtIndexAsDictionary(idx); - if (!maybe_dict) - return ScriptedInterface::ErrorWithMessage( + if (!maybe_dict) { + ScriptedInterface::ErrorWithMessage( LLVM_PRETTY_FUNCTION, llvm::Twine( "Couldn't get artificial stackframe dictionary at index (" + llvm::Twine(idx) + llvm::Twine(") from stackframe array.")) .str(), error, LLDBLog::Thread); + return error.ToError(); + } StructuredData::Dictionary *dict = *maybe_dict; lldb::addr_t pc; - if (!dict->GetValueForKeyAsInteger("pc", pc)) - return ScriptedInterface::ErrorWithMessage( + if (!dict->GetValueForKeyAsInteger("pc", pc)) { + ScriptedInterface::ErrorWithMessage( LLVM_PRETTY_FUNCTION, "Couldn't find value for key 'pc' in stackframe dictionary.", error, LLDBLog::Thread); + return error.ToError(); + } Address symbol_addr; symbol_addr.SetLoadAddress(pc, &this->GetProcess()->GetTarget()); @@ -205,10 +210,65 @@ bool ScriptedThread::LoadArtificialStackFrames() { SymbolContext sc; symbol_addr.CalculateSymbolContext(&sc); - StackFrameSP synth_frame_sp = std::make_shared( - this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, - StackFrame::Kind::Synthetic, artificial, behaves_like_zeroth_frame, - &sc); + return std::make_shared(this->shared_from_this(), idx, idx, cfa, + cfa_is_valid, pc, + StackFrame::Kind::Synthetic, artificial, + behaves_like_zeroth_frame, &sc); + }; + + auto create_frame_from_script_object = + [this, arr_sp](size_t idx) -> llvm::Expected { + Status error; + StructuredData::ObjectSP object_sp = arr_sp->GetItemAtIndex(idx); + if (!object_sp || !object_sp->GetAsGeneric()) { + ScriptedInterface::ErrorWithMessage( + LLVM_PRETTY_FUNCTION, + llvm::Twine("Couldn't get artificial stackframe object at index (" + + llvm::Twine(idx) + + llvm::Twine(") from stackframe array.")) + .str(), + error, LLDBLog::Thread); + return error.ToError(); + } + + auto frame_or_error = + ScriptedFrame::Create(*this, nullptr, object_sp->GetAsGeneric()); + + if (!frame_or_error) { + ScriptedInterface::ErrorWithMessage( + LLVM_PRETTY_FUNCTION, toString(frame_or_error.takeError()), error); + return error.ToError(); + } + + StackFrameSP frame_sp = frame_or_error.get(); + lldbassert(frame_sp && "Couldn't initialize scripted frame."); + + return frame_sp; + }; + + StackFrameListSP frames = GetStackFrameList(); + + for (size_t idx = 0; idx < arr_size; idx++) { + StackFrameSP synth_frame_sp = nullptr; + + auto frame_from_dict_or_err = create_frame_from_dict(idx); + if (!frame_from_dict_or_err) { + auto frame_from_script_obj_or_err = create_frame_from_script_object(idx); + + if (!frame_from_script_obj_or_err) { + return ScriptedInterface::ErrorWithMessage( + LLVM_PRETTY_FUNCTION, + llvm::Twine("Couldn't add artificial frame (" + llvm::Twine(idx) + + llvm::Twine(") to ScriptedThread StackFrameList.")) + .str(), + error, LLDBLog::Thread); + } else { + llvm::consumeError(frame_from_dict_or_err.takeError()); + synth_frame_sp = *frame_from_script_obj_or_err; + } + } else { + synth_frame_sp = *frame_from_dict_or_err; + } if (!frames->SetFrameAtIndex(static_cast(idx), synth_frame_sp)) return ScriptedInterface::ErrorWithMessage( diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/lldb/source/Plugins/Process/scripted/ScriptedThread.h index cd224d60ceef8..ee5ace4059673 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.h @@ -15,11 +15,12 @@ #include "Plugins/Process/Utility/RegisterContextMemory.h" #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Target//DynamicRegisterInfo.h" +#include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Target/Thread.h" namespace lldb_private { class ScriptedProcess; +class ScriptedFrame; } namespace lldb_private { @@ -61,6 +62,8 @@ class ScriptedThread : public lldb_private::Thread { StructuredData::ObjectSP FetchThreadExtendedInfo() override; private: + friend class ScriptedFrame; + void CheckInterpreterAndScriptObject() const; lldb::ScriptedThreadInterfaceSP GetInterface() const; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt index 04370940423ae..09103573b89c5 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt @@ -22,6 +22,7 @@ endif() add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces PLUGIN OperatingSystemPythonInterface.cpp ScriptInterpreterPythonInterfaces.cpp + ScriptedFramePythonInterface.cpp ScriptedPlatformPythonInterface.cpp ScriptedProcessPythonInterface.cpp ScriptedPythonInterface.cpp diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h index 02dc06507caf2..3814f46615078 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h @@ -17,6 +17,7 @@ #include "OperatingSystemPythonInterface.h" #include "ScriptedBreakpointPythonInterface.h" +#include "ScriptedFramePythonInterface.h" #include "ScriptedPlatformPythonInterface.h" #include "ScriptedProcessPythonInterface.h" #include "ScriptedStopHookPythonInterface.h" diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp new file mode 100644 index 0000000000000..20ca7a2c01356 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp @@ -0,0 +1,157 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/Config.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/Log.h" +#include "lldb/lldb-enumerations.h" + +#if LLDB_ENABLE_PYTHON + +// LLDB Python header must be included first +#include "../lldb-python.h" + +#include "../SWIGPythonBridge.h" +#include "../ScriptInterpreterPythonImpl.h" +#include "ScriptedFramePythonInterface.h" +#include + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::python; +using Locker = ScriptInterpreterPythonImpl::Locker; + +ScriptedFramePythonInterface::ScriptedFramePythonInterface( + ScriptInterpreterPythonImpl &interpreter) + : ScriptedFrameInterface(), ScriptedPythonInterface(interpreter) {} + +llvm::Expected +ScriptedFramePythonInterface::CreatePluginObject( + const llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) { + ExecutionContextRefSP exe_ctx_ref_sp = + std::make_shared(exe_ctx); + StructuredDataImpl sd_impl(args_sp); + return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj, + exe_ctx_ref_sp, sd_impl); +} + +lldb::user_id_t ScriptedFramePythonInterface::GetID() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_id", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, + error)) + return LLDB_INVALID_FRAME_ID; + + return obj->GetUnsignedIntegerValue(LLDB_INVALID_FRAME_ID); +} + +lldb::addr_t ScriptedFramePythonInterface::GetPC() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_pc", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, + error)) + return LLDB_INVALID_ADDRESS; + + return obj->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS); +} + +std::optional ScriptedFramePythonInterface::GetSymbolContext() { + Status error; + auto sym_ctx = Dispatch("get_symbol_context", error); + + if (error.Fail()) { + return ErrorWithMessage(LLVM_PRETTY_FUNCTION, + error.AsCString(), error); + } + + return sym_ctx; +} + +std::optional ScriptedFramePythonInterface::GetFunctionName() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_function_name", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, + error)) + return {}; + + return obj->GetStringValue().str(); +} + +std::optional +ScriptedFramePythonInterface::GetDisplayFunctionName() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_display_function_name", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, + error)) + return {}; + + return obj->GetStringValue().str(); +} + +bool ScriptedFramePythonInterface::IsInlined() { + Status error; + StructuredData::ObjectSP obj = Dispatch("is_inlined", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, + error)) + return false; + + return obj->GetBooleanValue(); +} + +bool ScriptedFramePythonInterface::IsArtificial() { + Status error; + StructuredData::ObjectSP obj = Dispatch("is_artificial", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, + error)) + return false; + + return obj->GetBooleanValue(); +} + +bool ScriptedFramePythonInterface::IsHidden() { + Status error; + StructuredData::ObjectSP obj = Dispatch("is_hidden", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, + error)) + return false; + + return obj->GetBooleanValue(); +} + +StructuredData::DictionarySP ScriptedFramePythonInterface::GetRegisterInfo() { + Status error; + StructuredData::DictionarySP dict = + Dispatch("get_register_info", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, + error)) + return {}; + + return dict; +} + +std::optional ScriptedFramePythonInterface::GetRegisterContext() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_register_context", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, + error)) + return {}; + + return obj->GetAsString()->GetValue().str(); +} + +#endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h new file mode 100644 index 0000000000000..3aff237ae65d5 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDFRAMEPYTHONINTERFACE_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDFRAMEPYTHONINTERFACE_H + +#include "lldb/Host/Config.h" + +#if LLDB_ENABLE_PYTHON + +#include "ScriptedPythonInterface.h" +#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h" +#include + +namespace lldb_private { +class ScriptedFramePythonInterface : public ScriptedFrameInterface, + public ScriptedPythonInterface { +public: + ScriptedFramePythonInterface(ScriptInterpreterPythonImpl &interpreter); + + llvm::Expected + CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp, + StructuredData::Generic *script_obj = nullptr) override; + + llvm::SmallVector + GetAbstractMethodRequirements() const override { + return llvm::SmallVector({{"get_id"}}); + } + + lldb::user_id_t GetID() override; + + lldb::addr_t GetPC() override; + + std::optional GetSymbolContext() override; + + std::optional GetFunctionName() override; + + std::optional GetDisplayFunctionName() override; + + bool IsInlined() override; + + bool IsArtificial() override; + + bool IsHidden() override; + + StructuredData::DictionarySP GetRegisterInfo() override; + + std::optional GetRegisterContext() override; +}; +} // namespace lldb_private + +#endif // LLDB_ENABLE_PYTHON +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDFRAMEPYTHONINTERFACE_H diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp index b49d1d82fe535..8083ccae04026 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp @@ -167,7 +167,8 @@ ScriptedPythonInterface::ExtractValueFromPythonObject< if (!sb_mem_reg_info) { error = Status::FromErrorStringWithFormat( - "Couldn't cast lldb::SBMemoryRegionInfo to lldb::MemoryRegionInfoSP."); + "Couldn't cast lldb::SBMemoryRegionInfo to " + "lldb_private::MemoryRegionInfo."); return {}; } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp index 8af89d761764b..fd4d231a747fe 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp @@ -144,4 +144,21 @@ StructuredData::ArraySP ScriptedThreadPythonInterface::GetExtendedInfo() { return arr; } +std::optional +ScriptedThreadPythonInterface::GetScriptedFramePluginName() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_scripted_frame_plugin", error); + + if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, + error)) + return {}; + + return obj->GetStringValue().str(); +} + +lldb::ScriptedFrameInterfaceSP +ScriptedThreadPythonInterface::CreateScriptedFrameInterface() { + return m_interpreter.CreateScriptedFrameInterface(); +} + #endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h index 1fb23b39c7076..043557a827461 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h @@ -51,6 +51,11 @@ class ScriptedThreadPythonInterface : public ScriptedThreadInterface, std::optional GetRegisterContext() override; StructuredData::ArraySP GetExtendedInfo() override; + + std::optional GetScriptedFramePluginName() override; + +protected: + lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() override; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 305b5f025c02d..b9c6707202243 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -1560,6 +1560,11 @@ ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() { return std::make_shared(*this); } +ScriptedFrameInterfaceSP +ScriptInterpreterPythonImpl::CreateScriptedFrameInterface() { + return std::make_shared(*this); +} + ScriptedThreadPlanInterfaceSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlanInterface() { return std::make_shared(*this); diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index 4698b82acb1d1..a83fa54ab588a 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -99,6 +99,8 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override; + lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() override; + lldb::ScriptedThreadPlanInterfaceSP CreateScriptedThreadPlanInterface() override; diff --git a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py index 2721d961bcb9d..835267221ddb4 100644 --- a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py +++ b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py @@ -5,6 +5,7 @@ import lldb from lldb.plugins.scripted_process import ScriptedProcess from lldb.plugins.scripted_process import ScriptedThread +from lldb.plugins.scripted_process import ScriptedFrame class DummyStopHook: @@ -22,7 +23,7 @@ class DummyScriptedProcess(ScriptedProcess): def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData): super().__init__(exe_ctx, args) - self.threads[0] = DummyScriptedThread(self, None) + self.threads[0] = DummyScriptedThread(self, args) self.memory = {} addr = 0x500000000 debugger = self.target.GetDebugger() @@ -69,6 +70,9 @@ class DummyScriptedThread(ScriptedThread): def __init__(self, process, args): super().__init__(process, args) self.frames.append({"pc": 0x0100001B00}) + self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "baz123")) + self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "bar")) + self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "foo")) def get_thread_id(self) -> int: return 0x19 @@ -109,6 +113,65 @@ def get_register_context(self) -> str: ) +class DummyScriptedFrame(ScriptedFrame): + def __init__(self, thread, args, id, name, sym_ctx=None): + super().__init__(thread, args) + self.id = id + self.name = name + self.sym_ctx = sym_ctx + + def get_id(self): + return self.id + + def get_function_name(self): + return self.name + + def get_register_context(self) -> str: + return struct.pack( + "21Q", + 0x10001, + 0x10002, + 0x10003, + 0x10004, + 0x10005, + 0x10006, + 0x10007, + 0x10008, + 0x10009, + 0x100010, + 0x100011, + 0x100012, + 0x100013, + 0x100014, + 0x100015, + 0x100016, + 0x100017, + 0x100018, + 0x100019, + 0x100020, + 0x100021, + ) + + def get_symbol_context(self): + def get_symbol_context_for_function(func_name): + module = self.target.FindModule(self.target.GetExecutable()) + if not module.IsValid(): + return None + + sym_ctx_list = module.FindFunctions(func_name) + if not sym_ctx_list.IsValid() or sym_ctx_list.GetSize() == 0: + return None + + return sym_ctx_list.GetContextAtIndex(0) + + return ( + self.sym_ctx if self.sym_ctx else get_symbol_context_for_function(self.name) + ) + + def get_scripted_frame_plugin(self): + return DummyScriptedFrame.__module__ + "." + DummyScriptedFrame.__name__ + + def __lldb_init_module(debugger, dict): # This is used when loading the script in an interactive debug session to # automatically, register the stop-hook and launch the scripted process. From 7f1cc27fbc3a266f8dec7ae32ca7121e67cb4bd1 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Fri, 3 Oct 2025 01:42:31 -0700 Subject: [PATCH 5/5] [lldb] Regenerate python static bindings Signed-off-by: Med Ismail Bennani --- .../python/static-binding/LLDBWrapPython.cpp | 520 ++++++++++++++---- lldb/bindings/python/static-binding/lldb.py | 54 ++ 2 files changed, 477 insertions(+), 97 deletions(-) diff --git a/lldb/bindings/python/static-binding/LLDBWrapPython.cpp b/lldb/bindings/python/static-binding/LLDBWrapPython.cpp index 5501525fedee0..e160393375326 100644 --- a/lldb/bindings/python/static-binding/LLDBWrapPython.cpp +++ b/lldb/bindings/python/static-binding/LLDBWrapPython.cpp @@ -3369,103 +3369,104 @@ SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) { #define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptInterpreter_t swig_types[161] #define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t swig_types[162] #define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedBreakpointInterface_t swig_types[163] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedMetadata_t swig_types[164] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedStopHookInterface_t swig_types[165] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t swig_types[166] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedThreadInterface_t swig_types[167] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedThreadPlanInterface_t swig_types[168] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SearchFilter_t swig_types[169] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SectionLoadList_t swig_types[170] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Section_t swig_types[171] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrameList_t swig_types[172] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrameRecognizer_t swig_types[173] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrame_t swig_types[174] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StopInfo_t swig_types[175] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StreamFile_t swig_types[176] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Stream_t swig_types[177] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StringSummaryFormat_t swig_types[178] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StructuredDataPlugin_t swig_types[179] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SupportFile_t swig_types[180] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolContextSpecifier_t swig_types[181] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolFileType_t swig_types[182] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SyntheticChildrenFrontEnd_t swig_types[183] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SyntheticChildren_t swig_types[184] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Target_t swig_types[185] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadCollection_t swig_types[186] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPlanTracer_t swig_types[187] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPlan_t swig_types[188] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPostMortemTrace_t swig_types[189] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Thread_t swig_types[190] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TraceCursor_t swig_types[191] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Trace_t swig_types[192] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeCategoryImpl_t swig_types[193] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeEnumMemberImpl_t swig_types[194] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeFilterImpl_t swig_types[195] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeFormatImpl_t swig_types[196] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeImpl_t swig_types[197] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeMemberFunctionImpl_t swig_types[198] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeNameSpecifierImpl_t swig_types[199] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSummaryImpl_t swig_types[200] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSummaryOptions_t swig_types[201] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSystemClang_t swig_types[202] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSystem_t swig_types[203] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Type_t swig_types[204] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnixSignals_t swig_types[205] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnwindAssembly_t swig_types[206] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnwindPlan_t swig_types[207] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UserExpression_t swig_types[208] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueObjectList_t swig_types[209] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueObject_t swig_types[210] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Value_t swig_types[211] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__VariableList_t swig_types[212] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Variable_t swig_types[213] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__WatchpointResource_t swig_types[214] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Watchpoint_t swig_types[215] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__WritableDataBuffer_t swig_types[216] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__AddressRange_t swig_types[217] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__DynamicCheckerFunctions_t swig_types[218] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__DynamicLoader_t swig_types[219] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__File_t swig_types[220] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__JITLoaderList_t swig_types[221] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__MemoryRegionInfo_t swig_types[222] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__OperatingSystem_t swig_types[223] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ProtocolServer_t swig_types[224] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ScriptedPlatformInterface_t swig_types[225] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ScriptedProcessInterface_t swig_types[226] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SectionList_t swig_types[227] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SourceManager_t swig_types[228] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StackFrameRecognizerManager_t swig_types[229] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__Stream_t swig_types[230] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StructuredDataImpl_t swig_types[231] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SymbolVendor_t swig_types[232] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SystemRuntime_t swig_types[233] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__TraceExporter_t swig_types[234] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BreakpointLocation_t swig_types[235] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Breakpoint_t swig_types[236] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BroadcasterManager_t swig_types[237] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Debugger_t swig_types[238] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Listener_t swig_types[239] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Module_t swig_types[240] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ObjectFileJITDelegate_t swig_types[241] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__OptionValue_t swig_types[242] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Process_t swig_types[243] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Queue_t swig_types[244] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Section_t swig_types[245] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__StackFrame_t swig_types[246] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__StructuredDataPlugin_t swig_types[247] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Target_t swig_types[248] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ThreadPlan_t swig_types[249] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Thread_t swig_types[250] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__TypeSystem_t swig_types[251] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Type_t swig_types[252] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__UnixSignals_t swig_types[253] -#define SWIGTYPE_p_unsigned_char swig_types[254] -#define SWIGTYPE_p_unsigned_int swig_types[255] -#define SWIGTYPE_p_unsigned_long_long swig_types[256] -#define SWIGTYPE_p_unsigned_short swig_types[257] -#define SWIGTYPE_p_void swig_types[258] -static swig_type_info *swig_types[260]; -static swig_module_info swig_module = {swig_types, 259, 0, 0, 0, 0}; +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedFrameInterface_t swig_types[164] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedMetadata_t swig_types[165] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedStopHookInterface_t swig_types[166] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t swig_types[167] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedThreadInterface_t swig_types[168] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedThreadPlanInterface_t swig_types[169] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SearchFilter_t swig_types[170] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SectionLoadList_t swig_types[171] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Section_t swig_types[172] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrameList_t swig_types[173] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrameRecognizer_t swig_types[174] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrame_t swig_types[175] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StopInfo_t swig_types[176] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StreamFile_t swig_types[177] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Stream_t swig_types[178] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StringSummaryFormat_t swig_types[179] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StructuredDataPlugin_t swig_types[180] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SupportFile_t swig_types[181] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolContextSpecifier_t swig_types[182] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolFileType_t swig_types[183] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SyntheticChildrenFrontEnd_t swig_types[184] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SyntheticChildren_t swig_types[185] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Target_t swig_types[186] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadCollection_t swig_types[187] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPlanTracer_t swig_types[188] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPlan_t swig_types[189] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPostMortemTrace_t swig_types[190] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Thread_t swig_types[191] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TraceCursor_t swig_types[192] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Trace_t swig_types[193] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeCategoryImpl_t swig_types[194] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeEnumMemberImpl_t swig_types[195] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeFilterImpl_t swig_types[196] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeFormatImpl_t swig_types[197] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeImpl_t swig_types[198] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeMemberFunctionImpl_t swig_types[199] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeNameSpecifierImpl_t swig_types[200] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSummaryImpl_t swig_types[201] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSummaryOptions_t swig_types[202] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSystemClang_t swig_types[203] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSystem_t swig_types[204] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Type_t swig_types[205] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnixSignals_t swig_types[206] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnwindAssembly_t swig_types[207] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnwindPlan_t swig_types[208] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UserExpression_t swig_types[209] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueObjectList_t swig_types[210] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueObject_t swig_types[211] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Value_t swig_types[212] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__VariableList_t swig_types[213] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Variable_t swig_types[214] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__WatchpointResource_t swig_types[215] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Watchpoint_t swig_types[216] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__WritableDataBuffer_t swig_types[217] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__AddressRange_t swig_types[218] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__DynamicCheckerFunctions_t swig_types[219] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__DynamicLoader_t swig_types[220] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__File_t swig_types[221] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__JITLoaderList_t swig_types[222] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__MemoryRegionInfo_t swig_types[223] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__OperatingSystem_t swig_types[224] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ProtocolServer_t swig_types[225] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ScriptedPlatformInterface_t swig_types[226] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ScriptedProcessInterface_t swig_types[227] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SectionList_t swig_types[228] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SourceManager_t swig_types[229] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StackFrameRecognizerManager_t swig_types[230] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__Stream_t swig_types[231] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StructuredDataImpl_t swig_types[232] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SymbolVendor_t swig_types[233] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SystemRuntime_t swig_types[234] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__TraceExporter_t swig_types[235] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BreakpointLocation_t swig_types[236] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Breakpoint_t swig_types[237] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BroadcasterManager_t swig_types[238] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Debugger_t swig_types[239] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Listener_t swig_types[240] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Module_t swig_types[241] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ObjectFileJITDelegate_t swig_types[242] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__OptionValue_t swig_types[243] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Process_t swig_types[244] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Queue_t swig_types[245] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Section_t swig_types[246] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__StackFrame_t swig_types[247] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__StructuredDataPlugin_t swig_types[248] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Target_t swig_types[249] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ThreadPlan_t swig_types[250] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Thread_t swig_types[251] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__TypeSystem_t swig_types[252] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Type_t swig_types[253] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__UnixSignals_t swig_types[254] +#define SWIGTYPE_p_unsigned_char swig_types[255] +#define SWIGTYPE_p_unsigned_int swig_types[256] +#define SWIGTYPE_p_unsigned_long_long swig_types[257] +#define SWIGTYPE_p_unsigned_short swig_types[258] +#define SWIGTYPE_p_void swig_types[259] +static swig_type_info *swig_types[261]; +static swig_module_info swig_module = {swig_types, 260, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -37865,6 +37866,34 @@ SWIGINTERN PyObject *_wrap_SBFrame_IsArtificial(PyObject *self, PyObject *args) } +SWIGINTERN PyObject *_wrap_SBFrame_IsSynthetic(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + lldb::SBFrame *arg1 = (lldb::SBFrame *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + (void)self; + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBFrame, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBFrame_IsSynthetic" "', argument " "1"" of type '" "lldb::SBFrame const *""'"); + } + arg1 = reinterpret_cast< lldb::SBFrame * >(argp1); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + result = (bool)((lldb::SBFrame const *)arg1)->IsSynthetic(); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_SBFrame_IsHidden(PyObject *self, PyObject *args) { PyObject *resultobj = 0; lldb::SBFrame *arg1 = (lldb::SBFrame *) 0 ; @@ -63614,6 +63643,269 @@ SWIGINTERN PyObject *_wrap_SBStructuredData_GetGenericValue(PyObject *self, PyOb } +SWIGINTERN PyObject *_wrap_SBStructuredData_SetValueForKey(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + lldb::SBStructuredData *arg1 = (lldb::SBStructuredData *) 0 ; + char *arg2 = (char *) 0 ; + lldb::SBStructuredData *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + PyObject *swig_obj[3] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SBStructuredData_SetValueForKey", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBStructuredData, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBStructuredData_SetValueForKey" "', argument " "1"" of type '" "lldb::SBStructuredData *""'"); + } + arg1 = reinterpret_cast< lldb::SBStructuredData * >(argp1); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SBStructuredData_SetValueForKey" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = reinterpret_cast< char * >(buf2); + res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_lldb__SBStructuredData, 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "SBStructuredData_SetValueForKey" "', argument " "3"" of type '" "lldb::SBStructuredData &""'"); + } + if (!argp3) { + SWIG_exception_fail(SWIG_NullReferenceError, "invalid null reference " "in method '" "SBStructuredData_SetValueForKey" "', argument " "3"" of type '" "lldb::SBStructuredData &""'"); + } + arg3 = reinterpret_cast< lldb::SBStructuredData * >(argp3); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + (arg1)->SetValueForKey((char const *)arg2,*arg3); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SBStructuredData_SetUnsignedIntegerValue(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + lldb::SBStructuredData *arg1 = (lldb::SBStructuredData *) 0 ; + uint64_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + unsigned long long val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SBStructuredData_SetUnsignedIntegerValue", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBStructuredData, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBStructuredData_SetUnsignedIntegerValue" "', argument " "1"" of type '" "lldb::SBStructuredData *""'"); + } + arg1 = reinterpret_cast< lldb::SBStructuredData * >(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SBStructuredData_SetUnsignedIntegerValue" "', argument " "2"" of type '" "uint64_t""'"); + } + arg2 = static_cast< uint64_t >(val2); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + (arg1)->SetUnsignedIntegerValue(arg2); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SBStructuredData_SetSignedIntegerValue(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + lldb::SBStructuredData *arg1 = (lldb::SBStructuredData *) 0 ; + int64_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + long long val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SBStructuredData_SetSignedIntegerValue", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBStructuredData, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBStructuredData_SetSignedIntegerValue" "', argument " "1"" of type '" "lldb::SBStructuredData *""'"); + } + arg1 = reinterpret_cast< lldb::SBStructuredData * >(argp1); + ecode2 = SWIG_AsVal_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SBStructuredData_SetSignedIntegerValue" "', argument " "2"" of type '" "int64_t""'"); + } + arg2 = static_cast< int64_t >(val2); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + (arg1)->SetSignedIntegerValue(arg2); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SBStructuredData_SetFloatValue(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + lldb::SBStructuredData *arg1 = (lldb::SBStructuredData *) 0 ; + double arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + double val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SBStructuredData_SetFloatValue", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBStructuredData, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBStructuredData_SetFloatValue" "', argument " "1"" of type '" "lldb::SBStructuredData *""'"); + } + arg1 = reinterpret_cast< lldb::SBStructuredData * >(argp1); + ecode2 = SWIG_AsVal_double(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SBStructuredData_SetFloatValue" "', argument " "2"" of type '" "double""'"); + } + arg2 = static_cast< double >(val2); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + (arg1)->SetFloatValue(arg2); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SBStructuredData_SetBooleanValue(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + lldb::SBStructuredData *arg1 = (lldb::SBStructuredData *) 0 ; + bool arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + bool val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SBStructuredData_SetBooleanValue", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBStructuredData, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBStructuredData_SetBooleanValue" "', argument " "1"" of type '" "lldb::SBStructuredData *""'"); + } + arg1 = reinterpret_cast< lldb::SBStructuredData * >(argp1); + ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SBStructuredData_SetBooleanValue" "', argument " "2"" of type '" "bool""'"); + } + arg2 = static_cast< bool >(val2); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + (arg1)->SetBooleanValue(arg2); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SBStructuredData_SetStringValue(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + lldb::SBStructuredData *arg1 = (lldb::SBStructuredData *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SBStructuredData_SetStringValue", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBStructuredData, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBStructuredData_SetStringValue" "', argument " "1"" of type '" "lldb::SBStructuredData *""'"); + } + arg1 = reinterpret_cast< lldb::SBStructuredData * >(argp1); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SBStructuredData_SetStringValue" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = reinterpret_cast< char * >(buf2); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + (arg1)->SetStringValue((char const *)arg2); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SBStructuredData_SetGenericValue(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + lldb::SBStructuredData *arg1 = (lldb::SBStructuredData *) 0 ; + SwigValueWrapper< lldb::SBScriptObject > arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject *swig_obj[2] ; + + (void)self; + if (!SWIG_Python_UnpackTuple(args, "SBStructuredData_SetGenericValue", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBStructuredData, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBStructuredData_SetGenericValue" "', argument " "1"" of type '" "lldb::SBStructuredData *""'"); + } + arg1 = reinterpret_cast< lldb::SBStructuredData * >(argp1); + { + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_lldb__SBScriptObject, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SBStructuredData_SetGenericValue" "', argument " "2"" of type '" "lldb::SBScriptObject""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_NullReferenceError, "invalid null reference " "in method '" "SBStructuredData_SetGenericValue" "', argument " "2"" of type '" "lldb::SBScriptObject""'"); + } else { + lldb::SBScriptObject * temp = reinterpret_cast< lldb::SBScriptObject * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + (arg1)->SetGenericValue(SWIG_STD_MOVE(arg2)); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_SBStructuredData___repr__(PyObject *self, PyObject *args) { PyObject *resultobj = 0; lldb::SBStructuredData *arg1 = (lldb::SBStructuredData *) 0 ; @@ -98453,6 +98745,7 @@ static PyMethodDef SwigMethods[] = { " capture a tail call). Local variables may not be available in an artificial\n" " frame.\n" ""}, + { "SBFrame_IsSynthetic", _wrap_SBFrame_IsSynthetic, METH_O, "SBFrame_IsSynthetic(SBFrame self) -> bool"}, { "SBFrame_IsHidden", _wrap_SBFrame_IsHidden, METH_O, "\n" "Return whether a frame recognizer decided this frame should not\n" "be displayes in backtraces etc.\n" @@ -100347,6 +100640,35 @@ static PyMethodDef SwigMethods[] = { " *dst* in all cases.\n" ""}, { "SBStructuredData_GetGenericValue", _wrap_SBStructuredData_GetGenericValue, METH_O, "Return the generic pointer if this data structure is a generic type."}, + { "SBStructuredData_SetValueForKey", _wrap_SBStructuredData_SetValueForKey, METH_VARARGS, "\n" + "Set the value corresponding to a key. If this data structure\n" + "is not a dictionary type, reset the type to be dictionary and overwrite\n" + "the previous data.\n" + ""}, + { "SBStructuredData_SetUnsignedIntegerValue", _wrap_SBStructuredData_SetUnsignedIntegerValue, METH_VARARGS, "\n" + "Change the type to unsigned interger and overwrite the previous data with\n" + "the new value.\n" + ""}, + { "SBStructuredData_SetSignedIntegerValue", _wrap_SBStructuredData_SetSignedIntegerValue, METH_VARARGS, "\n" + "Change the type to signed interger and overwrite the previous data with\n" + "the new value.\n" + ""}, + { "SBStructuredData_SetFloatValue", _wrap_SBStructuredData_SetFloatValue, METH_VARARGS, "\n" + "Change the type to float and overwrite the previous data with the new\n" + "value.\n" + ""}, + { "SBStructuredData_SetBooleanValue", _wrap_SBStructuredData_SetBooleanValue, METH_VARARGS, "\n" + "Change the type to boolean and overwrite the previous data with the new\n" + "value.\n" + ""}, + { "SBStructuredData_SetStringValue", _wrap_SBStructuredData_SetStringValue, METH_VARARGS, "\n" + "Change the type to string and overwrite the previous data with the new\n" + "value.\n" + ""}, + { "SBStructuredData_SetGenericValue", _wrap_SBStructuredData_SetGenericValue, METH_VARARGS, "\n" + "Change the type to generic and overwrite the previous data with the new\n" + "value.\n" + ""}, { "SBStructuredData___repr__", _wrap_SBStructuredData___repr__, METH_O, "SBStructuredData___repr__(SBStructuredData self) -> std::string"}, { "SBStructuredData_swigregister", SBStructuredData_swigregister, METH_O, NULL}, { "SBStructuredData_swiginit", SBStructuredData_swiginit, METH_VARARGS, NULL}, @@ -103516,6 +103838,7 @@ static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__RegularExpression static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t = {"_p_std__shared_ptrT_lldb_private__ScriptInterpreter_t", "lldb::ScriptInterpreterSP *|std::shared_ptr< lldb_private::ScriptInterpreter > *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t = {"_p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t", "lldb::ScriptSummaryFormatSP *|std::shared_ptr< lldb_private::ScriptSummaryFormat > *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptedBreakpointInterface_t = {"_p_std__shared_ptrT_lldb_private__ScriptedBreakpointInterface_t", "lldb::ScriptedBreakpointInterfaceSP *|std::shared_ptr< lldb_private::ScriptedBreakpointInterface > *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptedFrameInterface_t = {"_p_std__shared_ptrT_lldb_private__ScriptedFrameInterface_t", "lldb::ScriptedFrameInterfaceSP *|std::shared_ptr< lldb_private::ScriptedFrameInterface > *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptedMetadata_t = {"_p_std__shared_ptrT_lldb_private__ScriptedMetadata_t", "lldb::ScriptedMetadataSP *|std::shared_ptr< lldb_private::ScriptedMetadata > *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptedStopHookInterface_t = {"_p_std__shared_ptrT_lldb_private__ScriptedStopHookInterface_t", "lldb::ScriptedStopHookInterfaceSP *|std::shared_ptr< lldb_private::ScriptedStopHookInterface > *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t = {"_p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t", "lldb::ScriptedSyntheticChildrenSP *|std::shared_ptr< lldb_private::ScriptedSyntheticChildren > *", 0, 0, (void*)0, 0}; @@ -103777,6 +104100,7 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t, &_swigt__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t, &_swigt__p_std__shared_ptrT_lldb_private__ScriptedBreakpointInterface_t, + &_swigt__p_std__shared_ptrT_lldb_private__ScriptedFrameInterface_t, &_swigt__p_std__shared_ptrT_lldb_private__ScriptedMetadata_t, &_swigt__p_std__shared_ptrT_lldb_private__ScriptedStopHookInterface_t, &_swigt__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t, @@ -104038,6 +104362,7 @@ static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__RegularExpression static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptedBreakpointInterface_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptedBreakpointInterface_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptedFrameInterface_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptedFrameInterface_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptedMetadata_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptedMetadata_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptedStopHookInterface_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptedStopHookInterface_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t, 0, 0, 0},{0, 0, 0, 0}}; @@ -104299,6 +104624,7 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t, _swigc__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t, _swigc__p_std__shared_ptrT_lldb_private__ScriptedBreakpointInterface_t, + _swigc__p_std__shared_ptrT_lldb_private__ScriptedFrameInterface_t, _swigc__p_std__shared_ptrT_lldb_private__ScriptedMetadata_t, _swigc__p_std__shared_ptrT_lldb_private__ScriptedStopHookInterface_t, _swigc__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t, diff --git a/lldb/bindings/python/static-binding/lldb.py b/lldb/bindings/python/static-binding/lldb.py index 5f1b1cb420974..df50a82a93d98 100644 --- a/lldb/bindings/python/static-binding/lldb.py +++ b/lldb/bindings/python/static-binding/lldb.py @@ -7336,6 +7336,10 @@ def IsArtificial(self, *args): """ return _lldb.SBFrame_IsArtificial(self, *args) + def IsSynthetic(self): + r"""IsSynthetic(SBFrame self) -> bool""" + return _lldb.SBFrame_IsSynthetic(self) + def IsHidden(self): r""" Return whether a frame recognizer decided this frame should not @@ -12231,6 +12235,56 @@ def GetGenericValue(self): r"""Return the generic pointer if this data structure is a generic type.""" return _lldb.SBStructuredData_GetGenericValue(self) + def SetValueForKey(self, key, value): + r""" + Set the value corresponding to a key. If this data structure + is not a dictionary type, reset the type to be dictionary and overwrite + the previous data. + """ + return _lldb.SBStructuredData_SetValueForKey(self, key, value) + + def SetUnsignedIntegerValue(self, value): + r""" + Change the type to unsigned interger and overwrite the previous data with + the new value. + """ + return _lldb.SBStructuredData_SetUnsignedIntegerValue(self, value) + + def SetSignedIntegerValue(self, value): + r""" + Change the type to signed interger and overwrite the previous data with + the new value. + """ + return _lldb.SBStructuredData_SetSignedIntegerValue(self, value) + + def SetFloatValue(self, value): + r""" + Change the type to float and overwrite the previous data with the new + value. + """ + return _lldb.SBStructuredData_SetFloatValue(self, value) + + def SetBooleanValue(self, value): + r""" + Change the type to boolean and overwrite the previous data with the new + value. + """ + return _lldb.SBStructuredData_SetBooleanValue(self, value) + + def SetStringValue(self, value): + r""" + Change the type to string and overwrite the previous data with the new + value. + """ + return _lldb.SBStructuredData_SetStringValue(self, value) + + def SetGenericValue(self, value): + r""" + Change the type to generic and overwrite the previous data with the new + value. + """ + return _lldb.SBStructuredData_SetGenericValue(self, value) + def __repr__(self): r"""__repr__(SBStructuredData self) -> std::string""" return _lldb.SBStructuredData___repr__(self)