Author: Med Ismail Bennani Date: 2022-01-24T20:25:53+01:00 New Revision: d3e0f7e1503b1bca8baa6483d3b5c452a91f60a6
URL: https://github.com/llvm/llvm-project/commit/d3e0f7e1503b1bca8baa6483d3b5c452a91f60a6 DIFF: https://github.com/llvm/llvm-project/commit/d3e0f7e1503b1bca8baa6483d3b5c452a91f60a6.diff LOG: [lldb/Plugins] Add support of multiple ScriptedThreads in a ScriptedProcess This patch adds support of multiple Scripted Threads in a ScriptedProcess. This is done by fetching the Scripted Threads info dictionary at every ScriptedProcess::DoUpdateThreadList and iterate over each element to create a new ScriptedThread using the object instance, if it was not already available. This patch also adds the ability to pass a pointer of a script interpreter object instance to initialize a ScriptedInterface instead of having to call the script object initializer in the ScriptedInterface constructor. This is used to instantiate the ScriptedThreadInterface from the ScriptedThread constructor, to be able to perform call on that script interpreter object instance. Finally, the patch also updates the scripted process test to check for multiple threads. rdar://84507704 Differential Revision: https://reviews.llvm.org/D117071 Signed-off-by: Med Ismail Bennani <medismail.benn...@gmail.com> Added: lldb/test/API/functionalities/scripted_process/main.cpp Modified: lldb/examples/python/scripted_process/scripted_process.py lldb/include/lldb/Interpreter/ScriptedInterface.h lldb/include/lldb/Interpreter/ScriptedProcessInterface.h lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp lldb/source/Plugins/Process/scripted/ScriptedThread.cpp lldb/source/Plugins/Process/scripted/ScriptedThread.h lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h lldb/test/API/functionalities/scripted_process/Makefile lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py lldb/test/API/functionalities/scripted_process/invalid_scripted_process.py lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py Removed: lldb/test/API/functionalities/scripted_process/main.c ################################################################################ diff --git a/lldb/examples/python/scripted_process/scripted_process.py b/lldb/examples/python/scripted_process/scripted_process.py index ec751b495fdb6..83ec3513cfcd7 100644 --- a/lldb/examples/python/scripted_process/scripted_process.py +++ b/lldb/examples/python/scripted_process/scripted_process.py @@ -70,7 +70,7 @@ def get_thread_with_id(self, tid): tid (int): Thread ID to look for in the scripted process. Returns: - Dict: The thread represented as a dictionary, withr the + Dict: The thread represented as a dictionary, with the tid thread ID. None if tid doesn't match any of the scripted process threads. """ @@ -212,11 +212,12 @@ def __init__(self, process, args): self.target = None self.process = None self.args = None - if isinstance(process, lldb.SBProcess) and process.IsValid(): - self.process = process - self.target = process.GetTarget() + if isinstance(process, ScriptedProcess): + self.target = process.target + self.process = self.target.GetProcess() self.id = None + self.idx = None self.name = None self.queue = None self.state = None diff --git a/lldb/include/lldb/Interpreter/ScriptedInterface.h b/lldb/include/lldb/Interpreter/ScriptedInterface.h index 427fa3f4f793a..27cf9f036e5fd 100644 --- a/lldb/include/lldb/Interpreter/ScriptedInterface.h +++ b/lldb/include/lldb/Interpreter/ScriptedInterface.h @@ -27,7 +27,8 @@ class ScriptedInterface { virtual StructuredData::GenericSP CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, - StructuredData::DictionarySP args_sp) = 0; + StructuredData::DictionarySP args_sp, + StructuredData::Generic *script_obj = nullptr) = 0; template <typename Ret> Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_msg, diff --git a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h index d62767417f339..0712b3bf4a3ee 100644 --- a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h +++ b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h @@ -23,7 +23,8 @@ class ScriptedProcessInterface : virtual public ScriptedInterface { public: StructuredData::GenericSP CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, - StructuredData::DictionarySP args_sp) override { + StructuredData::DictionarySP args_sp, + StructuredData::Generic *script_obj = nullptr) override { return nullptr; } @@ -77,7 +78,8 @@ class ScriptedThreadInterface : virtual public ScriptedInterface { public: StructuredData::GenericSP CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, - StructuredData::DictionarySP args_sp) override { + StructuredData::DictionarySP args_sp, + StructuredData::Generic *script_obj = nullptr) override { return nullptr; } diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index cb21a3e7e65f3..f01e599ad5585 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -164,9 +164,6 @@ Status ScriptedProcess::DoLaunch(Module *exe_module, SetPrivateState(eStateStopped); - UpdateThreadListIfNeeded(); - GetThreadList(); - return {}; } @@ -304,19 +301,55 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, .str(), error); - lldb::ThreadSP thread_sp; - thread_sp = std::make_shared<ScriptedThread>(*this, error); - - if (!thread_sp || error.Fail()) - return GetInterface().ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, - error.AsCString(), error); + StructuredData::DictionarySP thread_info_sp = GetInterface().GetThreadsInfo(); - RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); - if (!reg_ctx_sp) + if (!thread_info_sp) return GetInterface().ErrorWithMessage<bool>( - LLVM_PRETTY_FUNCTION, "Invalid Register Context", error); - - new_thread_list.AddThread(thread_sp); + LLVM_PRETTY_FUNCTION, + "Couldn't fetch thread list from Scripted Process.", error); + + auto create_scripted_thread = + [this, &old_thread_list, &error, + &new_thread_list](ConstString key, StructuredData::Object *val) -> bool { + if (!val) + return GetInterface().ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, "Invalid thread info object", error); + + lldb::tid_t tid = LLDB_INVALID_THREAD_ID; + if (!llvm::to_integer(key.AsCString(), tid)) + return GetInterface().ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, + "Invalid thread id", error); + + if (ThreadSP thread_sp = + old_thread_list.FindThreadByID(tid, false /*=can_update*/)) { + // If the thread was already in the old_thread_list, + // just add it back to the new_thread_list. + new_thread_list.AddThread(thread_sp); + return true; + } + + lldb::ThreadSP thread_sp = + std::make_shared<ScriptedThread>(*this, error, val->GetAsGeneric()); + + if (!thread_sp || error.Fail()) + return GetInterface().ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, + error.AsCString(), error); + + RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); + if (!reg_ctx_sp) + return GetInterface().ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine("Invalid Register Context for thread " + + llvm::Twine(key.AsCString())) + .str(), + error); + + new_thread_list.AddThread(thread_sp); + + return true; + }; + + thread_info_sp->ForEach(create_scripted_thread); return new_thread_list.GetSize(false) > 0; } diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index 4185e1b67587b..1b9841c2048ea 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -28,7 +28,8 @@ void ScriptedThread::CheckInterpreterAndScriptObject() const { lldbassert(GetInterface() && "Invalid Scripted Thread Interface."); } -ScriptedThread::ScriptedThread(ScriptedProcess &process, Status &error) +ScriptedThread::ScriptedThread(ScriptedProcess &process, Status &error, + StructuredData::Generic *script_object) : Thread(process, LLDB_INVALID_THREAD_ID), m_scripted_process(process), m_scripted_thread_interface_sp( m_scripted_process.GetInterface().CreateScriptedThreadInterface()) { @@ -54,18 +55,23 @@ ScriptedThread::ScriptedThread(ScriptedProcess &process, Status &error) ExecutionContext exe_ctx(process); - StructuredData::GenericSP object_sp = - scripted_thread_interface->CreatePluginObject( - class_name->c_str(), exe_ctx, - process.m_scripted_process_info.GetArgsSP()); - if (!object_sp || !object_sp->IsValid()) { - error.SetErrorString("Failed to create valid script object"); + m_script_object_sp = scripted_thread_interface->CreatePluginObject( + class_name->c_str(), exe_ctx, process.m_scripted_process_info.GetArgsSP(), + script_object); + + if (!m_script_object_sp) { + error.SetErrorString("Failed to create script object"); return; } - m_script_object_sp = object_sp; + if (!m_script_object_sp->IsValid()) { + m_script_object_sp = nullptr; + error.SetErrorString("Created script object is invalid"); + return; + } - SetID(scripted_thread_interface->GetThreadID()); + lldb::tid_t tid = scripted_thread_interface->GetThreadID(); + SetID(tid); } ScriptedThread::~ScriptedThread() { DestroyThread(); } diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/lldb/source/Plugins/Process/scripted/ScriptedThread.h index 54b095777ab73..d3cd26c57826d 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.h @@ -26,7 +26,8 @@ namespace lldb_private { class ScriptedThread : public lldb_private::Thread { public: - ScriptedThread(ScriptedProcess &process, Status &error); + ScriptedThread(ScriptedProcess &process, Status &error, + StructuredData::Generic *script_object = nullptr); ~ScriptedThread() override; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp index 29516c4c4501e..e39f8be73e49a 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -32,7 +32,7 @@ ScriptedProcessPythonInterface::ScriptedProcessPythonInterface( StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( llvm::StringRef class_name, ExecutionContext &exe_ctx, - StructuredData::DictionarySP args_sp) { + StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) { if (class_name.empty()) return {}; @@ -47,9 +47,6 @@ StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, args_impl, error_string); - if (!ret_val) - return {}; - m_object_instance_sp = StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val))); diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h index 83507a93bb973..e34a181849eb4 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h @@ -25,7 +25,8 @@ class ScriptedProcessPythonInterface : public ScriptedProcessInterface, StructuredData::GenericSP CreatePluginObject(const llvm::StringRef class_name, ExecutionContext &exe_ctx, - StructuredData::DictionarySP args_sp) override; + StructuredData::DictionarySP args_sp, + StructuredData::Generic *script_obj = nullptr) override; Status Launch() override; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp index fb55d44aca840..511a42fe2c26a 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -31,8 +31,7 @@ ScriptedThreadPythonInterface::ScriptedThreadPythonInterface( StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject( const llvm::StringRef class_name, ExecutionContext &exe_ctx, - StructuredData::DictionarySP args_sp) { - + StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) { if (class_name.empty()) return {}; @@ -43,9 +42,15 @@ StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject( Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); - PythonObject ret_val = LLDBSwigPythonCreateScriptedThread( - class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp, - args_impl, error_string); + PythonObject ret_val; + + if (!script_obj) + ret_val = LLDBSwigPythonCreateScriptedThread( + class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp, + args_impl, error_string); + else + ret_val = PythonObject(PyRefType::Borrowed, + static_cast<PyObject *>(script_obj->GetValue())); if (!ret_val) return {}; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h index 4222cdfa8fcfe..59bb182ae3f3d 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h @@ -24,7 +24,8 @@ class ScriptedThreadPythonInterface : public ScriptedThreadInterface, StructuredData::GenericSP CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, - StructuredData::DictionarySP args_sp) override; + StructuredData::DictionarySP args_sp, + StructuredData::Generic *script_obj = nullptr) override; lldb::tid_t GetThreadID() override; diff --git a/lldb/test/API/functionalities/scripted_process/Makefile b/lldb/test/API/functionalities/scripted_process/Makefile index 692ba17322859..785b17c7fd698 100644 --- a/lldb/test/API/functionalities/scripted_process/Makefile +++ b/lldb/test/API/functionalities/scripted_process/Makefile @@ -1,4 +1,4 @@ -C_SOURCES := main.c - +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES include Makefile.rules diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index 2a5eff3122145..be55771c14fb1 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -130,7 +130,8 @@ def cleanup(): def create_stack_skinny_corefile(self, file): self.build() - target, process, thread, _ = lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.c")) + target, process, thread, _ = lldbutil.run_to_source_breakpoint(self, "// break here", + lldb.SBFileSpec("main.cpp")) self.assertTrue(process.IsValid(), "Process is invalid.") # FIXME: Use SBAPI to save the process corefile. self.runCmd("process save-core -s stack " + file) @@ -186,14 +187,14 @@ def cleanup(): self.assertTrue(process, PROCESS_IS_VALID) self.assertEqual(process.GetProcessID(), 42) - self.assertEqual(process.GetNumThreads(), 1) + self.assertEqual(process.GetNumThreads(), 3) thread = process.GetSelectedThread() self.assertTrue(thread, "Invalid thread.") - self.assertEqual(thread.GetName(), "StackCoreScriptedThread.thread-1") + self.assertEqual(thread.GetName(), "StackCoreScriptedThread.thread-0") - self.assertEqual(thread.GetNumFrames(), 3) + self.assertEqual(thread.GetNumFrames(), 2) frame = thread.GetSelectedFrame() self.assertTrue(frame, "Invalid frame.") - self.assertEqual(frame.GetFunctionName(), "bar") - self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42) - self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42) + # self.assertEqual(frame.GetFunctionName(), "bar") + # self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42) + # self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42) diff --git a/lldb/test/API/functionalities/scripted_process/invalid_scripted_process.py b/lldb/test/API/functionalities/scripted_process/invalid_scripted_process.py index 7dfc55bc30c5b..0a2977c69d457 100644 --- a/lldb/test/API/functionalities/scripted_process/invalid_scripted_process.py +++ b/lldb/test/API/functionalities/scripted_process/invalid_scripted_process.py @@ -9,6 +9,7 @@ class InvalidScriptedProcess(ScriptedProcess): def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData): super().__init__(target, args) + self.threads[0] = InvalidScriptedThread(self, None) def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo: return None @@ -81,4 +82,4 @@ def __lldb_init_module(debugger, dict): InvalidScriptedProcess.__name__)) else: print("Name of the class that will manage the scripted process: '%s.%s'" - % (__name__, InvalidScriptedProcess.__name__)) \ No newline at end of file + % (__name__, InvalidScriptedProcess.__name__)) diff --git a/lldb/test/API/functionalities/scripted_process/main.c b/lldb/test/API/functionalities/scripted_process/main.c deleted file mode 100644 index 67d3732441da2..0000000000000 --- a/lldb/test/API/functionalities/scripted_process/main.c +++ /dev/null @@ -1,8 +0,0 @@ -int bar(int i) { - int j = i * i; - return j; // break here -} - -int foo(int i) { return bar(i); } - -int main() { return foo(42); } diff --git a/lldb/test/API/functionalities/scripted_process/main.cpp b/lldb/test/API/functionalities/scripted_process/main.cpp new file mode 100644 index 0000000000000..26dc123558921 --- /dev/null +++ b/lldb/test/API/functionalities/scripted_process/main.cpp @@ -0,0 +1,34 @@ +#include <iostream> +#include <mutex> +#include <thread> + +int bar(int i) { + int j = i * i; + return j; // break here +} + +int foo(int i) { return bar(i); } + +void call_and_wait(int &n) { + std::cout << "waiting for computation!" << std::endl; + while (n != 42 * 42) + ; + std::cout << "finished computation!" << std::endl; +} + +void compute_pow(int &n) { n = foo(n); } + +int main() { + int n = 42; + std::mutex mutex; + std::unique_lock<std::mutex> lock(mutex); + + std::thread thread_1(call_and_wait, std::ref(n)); + std::thread thread_2(compute_pow, std::ref(n)); + lock.unlock(); + + thread_1.join(); + thread_2.join(); + + return 0; +} diff --git a/lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py b/lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py index da7c69ee7b993..ac455fe3d2717 100644 --- a/lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py +++ b/lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py @@ -1,4 +1,4 @@ -import os,struct,signal +import os,json,struct,signal from typing import Any, Dict @@ -21,6 +21,14 @@ def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData): idx = int(self.backing_target_idx.GetStringValue(100)) self.corefile_target = target.GetDebugger().GetTargetAtIndex(idx) self.corefile_process = self.corefile_target.GetProcess() + for corefile_thread in self.corefile_process: + structured_data = lldb.SBStructuredData() + structured_data.SetFromJSON(json.dumps({ + "backing_target_idx" : idx, + "thread_idx" : corefile_thread.GetIndexID() + })) + + self.threads[corefile_thread.GetThreadID()] = StackCoreScriptedThread(self, structured_data) def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo: mem_region = lldb.SBMemoryRegionInfo() @@ -70,23 +78,43 @@ def get_scripted_thread_plugin(self): class StackCoreScriptedThread(ScriptedThread): def __init__(self, process, args): super().__init__(process, args) - self.backing_target_idx = args.GetValueForKey("backing_target_idx") + backing_target_idx = args.GetValueForKey("backing_target_idx") + thread_idx = args.GetValueForKey("thread_idx") + + def extract_value_from_structured_data(data, default_val): + if data and data.IsValid(): + if data.GetType() == lldb.eStructuredDataTypeInteger: + return data.GetIntegerValue(default_val) + if data.GetType() == lldb.eStructuredDataTypeString: + return int(data.GetStringValue(100)) + return None + + #TODO: Change to Walrus operator (:=) with oneline if assignment + # Requires python 3.8 + val = extract_value_from_structured_data(thread_idx, 0) + if val is not None: + self.idx = val self.corefile_target = None self.corefile_process = None - if (self.backing_target_idx and self.backing_target_idx.IsValid()): - if self.backing_target_idx.GetType() == lldb.eStructuredDataTypeInteger: - idx = self.backing_target_idx.GetIntegerValue(42) - if self.backing_target_idx.GetType() == lldb.eStructuredDataTypeString: - idx = int(self.backing_target_idx.GetStringValue(100)) - self.corefile_target = self.target.GetDebugger().GetTargetAtIndex(idx) + self.corefile_thread = None + + #TODO: Change to Walrus operator (:=) with oneline if assignment + # Requires python 3.8 + val = extract_value_from_structured_data(backing_target_idx, 42) + if val is not None: + self.corefile_target = self.target.GetDebugger().GetTargetAtIndex(val) self.corefile_process = self.corefile_target.GetProcess() + self.corefile_thread = self.corefile_process.GetThreadByIndexID(self.idx) + + if self.corefile_thread: + self.id = self.corefile_thread.GetThreadID() def get_thread_id(self) -> int: - return 0x19 + return self.id def get_name(self) -> str: - return StackCoreScriptedThread.__name__ + ".thread-1" + return StackCoreScriptedThread.__name__ + ".thread-" + str(self.id) def get_stop_reason(self) -> Dict[str, Any]: return { "type": lldb.eStopReasonSignal, "data": { @@ -109,10 +137,9 @@ def __init__(idx, cfa, pc, symbol_ctx): return self.frame_zero[0:0] def get_register_context(self) -> str: - thread = self.corefile_process.GetSelectedThread() - if not thread or thread.GetNumFrames() == 0: + if not self.corefile_thread or self.corefile_thread.GetNumFrames() == 0: return None - frame = thread.GetFrameAtIndex(0) + frame = self.corefile_thread.GetFrameAtIndex(0) GPRs = None registerSet = frame.registers # Returns an SBValueList. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits