diff options
| author | Med Ismail Bennani <medismail.bennani@gmail.com> | 2022-02-09 19:04:21 -0800 |
|---|---|---|
| committer | Med Ismail Bennani <medismail.bennani@gmail.com> | 2022-02-16 11:44:07 -0800 |
| commit | 70665844915eeb66273a84f131ffc33a202539d5 (patch) | |
| tree | ee284912d8248768e4f4abb1b99f18b8278a8546 /lldb/source/Plugins/Process/scripted/ScriptedThread.cpp | |
| parent | c30742ba73816ca61926121c82b81a766ebe1a6e (diff) | |
[lldb/Plugin] Add artificial stackframe loading in ScriptedThread
This patch adds the ability for ScriptedThread to load artificial stack
frames. To do so, the interpreter instance can create a list that will
contain the frame index and its pc address.
Then, when the Scripted Process plugin stops, it will refresh its
Scripted Threads state by invalidating their register context and load
to list from the interpreter object and reconstruct each frame.
This patch also removes all of the default implementation for
`get_stackframes` from the derived ScriptedThread classes, and add the
interface code for the Scripted Thread Interface.
rdar://88721095
Differential Revision: https://reviews.llvm.org/D119388
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
Diffstat (limited to 'lldb/source/Plugins/Process/scripted/ScriptedThread.cpp')
| -rw-r--r-- | lldb/source/Plugins/Process/scripted/ScriptedThread.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index 173f503f279d..8174a8bde331 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -147,6 +147,73 @@ ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) { return m_reg_context_sp; } +bool ScriptedThread::LoadArtificialStackFrames() { + StructuredData::ArraySP arr_sp = GetInterface()->GetStackFrames(); + + Status error; + if (!arr_sp) + return GetInterface()->ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stackframes.", + error, LLDBLog::Thread); + + size_t arr_size = arr_sp->GetSize(); + if (arr_size > std::numeric_limits<uint32_t>::max()) + return GetInterface()->ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine( + "StackFrame array size (" + llvm::Twine(arr_size) + + llvm::Twine( + ") is greater than maximum autorized for a StackFrameList.")) + .str(), + error, LLDBLog::Thread); + + StackFrameListSP frames = GetStackFrameList(); + + for (size_t idx = 0; idx < arr_size; idx++) { + + StructuredData::Dictionary *dict; + + if (!arr_sp->GetItemAtIndexAsDictionary(idx, dict) || !dict) + return GetInterface()->ErrorWithMessage<bool>( + 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); + + lldb::addr_t pc; + if (!dict->GetValueForKeyAsInteger("pc", pc)) + return ScriptedInterface::ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + "Couldn't find value for key 'pc' in stackframe dictionary.", error, + LLDBLog::Thread); + + Address symbol_addr; + symbol_addr.SetLoadAddress(pc, &this->GetProcess()->GetTarget()); + + lldb::addr_t cfa = LLDB_INVALID_ADDRESS; + bool cfa_is_valid = false; + const bool behaves_like_zeroth_frame = false; + SymbolContext sc; + symbol_addr.CalculateSymbolContext(&sc); + + StackFrameSP synth_frame_sp = std::make_shared<StackFrame>( + this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, + StackFrame::Kind::Artificial, behaves_like_zeroth_frame, &sc); + + if (!frames->SetFrameAtIndex(static_cast<uint32_t>(idx), synth_frame_sp)) + return GetInterface()->ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine("Couldn't add frame (" + llvm::Twine(idx) + + llvm::Twine(") to ScriptedThread StackFrameList.")) + .str(), + error, LLDBLog::Thread); + } + + return true; +} + bool ScriptedThread::CalculateStopInfo() { StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason(); @@ -216,6 +283,7 @@ bool ScriptedThread::CalculateStopInfo() { void ScriptedThread::RefreshStateAfterStop() { GetRegisterContext()->InvalidateIfNeeded(/*force=*/false); + LoadArtificialStackFrames(); } lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const { |
