From fa412309f1b8aee1e90797c76b61afeab5fd1cf0 Mon Sep 17 00:00:00 2001 From: Leo Katzengruber Date: Sat, 23 Aug 2025 14:35:53 +0200 Subject: [PATCH] Add memoryReference field for variables in dap protocol --- src/debugger/variables.cpp | 16 ++++++++++++++++ src/interfaces/types.h | 3 ++- src/protocols/vscodeprotocol.cpp | 4 ++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/debugger/variables.cpp b/src/debugger/variables.cpp index 8e9efb94..98f2f5eb 100644 --- a/src/debugger/variables.cpp +++ b/src/debugger/variables.cpp @@ -138,6 +138,18 @@ static HRESULT FetchFieldsAndProperties(Evaluator *pEvaluator, ICorDebugValue *p return S_OK; } +static HRESULT GetMemoryReference(ICorDebugValue* pInputValue, uint64_t& memoryReference) { + HRESULT Status; + + ToRelease pReferenceValue; + if (FAILED(pInputValue->QueryInterface(IID_ICorDebugReferenceValue, (void**)&pReferenceValue))) + IfFailRet(pInputValue->GetAddress(&memoryReference)); + else + IfFailRet(pReferenceValue->GetValue(&memoryReference)); + + return S_OK; +} + int Variables::GetNamedVariables(uint32_t variablesReference) { std::lock_guard lock(m_referencesMutex); @@ -219,6 +231,7 @@ HRESULT Variables::GetExceptionVariable(FrameId frameId, ICorDebugThread *pThrea HRESULT Status; IfFailRet(PrintValue(pExceptionValue, var.value)); IfFailRet(TypePrinter::GetTypeOfValue(pExceptionValue, var.type)); + IfFailRet(GetMemoryReference(pExceptionValue, var.memoryReference)); return AddVariableReference(var, frameId, pExceptionValue, ValueIsVariable); } @@ -259,6 +272,7 @@ HRESULT Variables::GetStackVariables( IfFailRet(getValue(&iCorValue, var.evalFlags)); IfFailRet(TypePrinter::GetTypeOfValue(iCorValue, var.type)); IfFailRet(PrintValue(iCorValue, var.value)); + IfFailRet(GetMemoryReference(iCorValue, var.memoryReference)); IfFailRet(AddVariableReference(var, frameId, iCorValue, ValueIsVariable)); variables.push_back(var); @@ -355,6 +369,7 @@ HRESULT Variables::GetChildren( if (var.name.find('(') == std::string::npos) // expression evaluator does not support typecasts var.evaluateName = ref.evaluateName + (isIndex ? "" : ".") + var.name; IfFailRet(FillValueAndType(it, var)); + IfFailRet(GetMemoryReference(it.value, var.memoryReference)); IfFailRet(AddVariableReference(var, ref.frameId, it.value, ValueIsVariable)); variables.push_back(var); } @@ -405,6 +420,7 @@ HRESULT Variables::Evaluate( variable.evaluateName = expression; IfFailRet(TypePrinter::GetTypeOfValue(pResultValue, variable.type)); IfFailRet(PrintValue(pResultValue, variable.value)); + IfFailRet(GetMemoryReference(pResultValue, variable.memoryReference)); return AddVariableReference(variable, frameId, pResultValue, ValueIsVariable); } diff --git a/src/interfaces/types.h b/src/interfaces/types.h index 019d1692..3f763b5a 100644 --- a/src/interfaces/types.h +++ b/src/interfaces/types.h @@ -414,13 +414,14 @@ struct Variable std::string type; VariablePresentationHint presentationHint; std::string evaluateName; + uint64_t memoryReference; uint32_t variablesReference; int namedVariables; int indexedVariables; int evalFlags; bool editable; - Variable(int flags = defaultEvalFlags) : variablesReference(0), namedVariables(0), indexedVariables(0), evalFlags(flags), editable(false) {} + Variable(int flags = defaultEvalFlags) : memoryReference(0), variablesReference(0), namedVariables(0), indexedVariables(0), evalFlags(flags), editable(false) {} }; enum VariablesFilter diff --git a/src/protocols/vscodeprotocol.cpp b/src/protocols/vscodeprotocol.cpp index 7712318b..513427af 100644 --- a/src/protocols/vscodeprotocol.cpp +++ b/src/protocols/vscodeprotocol.cpp @@ -108,11 +108,15 @@ void to_json(json &j, const Scope &s) { } void to_json(json &j, const Variable &v) { + char memoryReference[19] = "0x0000000000000000"; + snprintf(memoryReference, 19, "0x%016llx", v.memoryReference); + j = json{ {"name", v.name}, {"value", v.value}, {"type", v.type}, {"evaluateName", v.evaluateName}, + {"memoryReference", memoryReference}, {"variablesReference", v.variablesReference}}; if (v.variablesReference > 0)