Author: Jonas Devlieghere Date: 2026-07-28T17:49:21Z New Revision: 7ac6b9ff31dbd3a028585ccd18d8a7a290303d58
URL: https://github.com/llvm/llvm-project/commit/7ac6b9ff31dbd3a028585ccd18d8a7a290303d58 DIFF: https://github.com/llvm/llvm-project/commit/7ac6b9ff31dbd3a028585ccd18d8a7a290303d58.diff LOG: [lldb] Report the unwound PC for WebAssembly caller frames (#212326) RegisterContextWasm delegated the PC register read to GDBRemoteRegisterContext, which reports the live innermost PC for every frame. Resolving a variable whose DWARF location is a location list in a caller frame therefore chose the entry using the innermost frame's PC instead of the caller's, so the variable read back as unavailable even though its location covered the caller's PC. Return the program counter the WebAssembly unwinder recorded for the frame (from qWasmCallStack) when reading a caller frame's PC, so the location list entry uses the correct frame. Added: Modified: lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp lldb/source/Plugins/Process/wasm/ThreadWasm.cpp lldb/source/Plugins/Process/wasm/ThreadWasm.h Removed: ################################################################################ diff --git a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp index bdeb0c927a387..a05fbd56e8680 100644 --- a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp +++ b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp @@ -64,14 +64,27 @@ const RegisterSet *RegisterContextWasm::GetRegisterSet(size_t reg_set) { bool RegisterContextWasm::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { - // The only real registers is the PC. - if (reg_info->name) + ThreadWasm &wasm_thread = static_cast<ThreadWasm &>(GetThread()); + + // The only real register is the PC. + if (reg_info->name) { + // A caller frame's PC is the unwound return address, which the base + // register context cannot provide because it only sees the innermost + // frame's live PC. Use the PC the unwinder recorded for this frame. + if (m_concrete_frame_idx > 0) { + lldb::addr_t pc = wasm_thread.GetConcreteFramePC(m_concrete_frame_idx); + if (pc != LLDB_INVALID_ADDRESS) { + value.SetUInt(pc, reg_info->byte_size); + return true; + } + } return GDBRemoteRegisterContext::ReadRegister(reg_info, value); + } // Read the virtual registers. - ThreadWasm *thread = static_cast<ThreadWasm *>(&GetThread()); - ProcessWasm *process = static_cast<ProcessWasm *>(thread->GetProcess().get()); - if (!thread) + ProcessWasm *process = + static_cast<ProcessWasm *>(wasm_thread.GetProcess().get()); + if (!process) return false; uint32_t frame_index = m_concrete_frame_idx; diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp index 0666b75d4afe0..c7c05cb815261 100644 --- a/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp +++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp @@ -12,6 +12,7 @@ #include "RegisterContextWasm.h" #include "UnwindWasm.h" #include "lldb/Target/Target.h" +#include "lldb/Target/Unwind.h" using namespace lldb; using namespace lldb_private; @@ -34,6 +35,15 @@ llvm::Expected<std::vector<lldb::addr_t>> ThreadWasm::GetWasmCallStack() { return llvm::createStringError("no process"); } +lldb::addr_t ThreadWasm::GetConcreteFramePC(uint32_t concrete_frame_idx) { + lldb::addr_t cfa, pc; + bool behaves_like_zeroth_frame; + if (GetUnwinder().GetFrameInfoAtIndex(concrete_frame_idx, cfa, pc, + behaves_like_zeroth_frame)) + return pc; + return LLDB_INVALID_ADDRESS; +} + lldb::RegisterContextSP ThreadWasm::CreateRegisterContextForFrame(StackFrame *frame) { uint32_t concrete_frame_idx = 0; diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.h b/lldb/source/Plugins/Process/wasm/ThreadWasm.h index c2f5762b30484..a2d1d66ced0d7 100644 --- a/lldb/source/Plugins/Process/wasm/ThreadWasm.h +++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.h @@ -25,6 +25,10 @@ class ThreadWasm : public process_gdb_remote::ThreadGDBRemote { /// Retrieve the current call stack from the WebAssembly remote process. llvm::Expected<std::vector<lldb::addr_t>> GetWasmCallStack(); + /// Return the program counter the Wasm unwinder recorded for the given + /// concrete frame index, or LLDB_INVALID_ADDRESS if it is unavailable. + lldb::addr_t GetConcreteFramePC(uint32_t concrete_frame_idx); + lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) override; _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
