return false;
}
+ internal static bool GetLocalVariableNameAndScope(IntPtr symbolReaderHandle, int methodToken, int localIndex, out IntPtr localVarName, out int ilStartOffset, out int ilEndOffset)
+ {
+ localVarName = IntPtr.Zero;
+ ilStartOffset = 0;
+ ilEndOffset = 0;
+
+ string localVar = null;
+ if (!GetLocalVariableAndScopeByIndex(symbolReaderHandle, methodToken, localIndex, out localVar, out ilStartOffset, out ilEndOffset))
+ return false;
+
+ localVarName = Marshal.StringToBSTR(localVar);
+ localVar = null;
+ return true;
+ }
+
+ internal static bool GetLocalVariableAndScopeByIndex(IntPtr symbolReaderHandle, int methodToken, int localIndex, out string localVarName, out int ilStartOffset, out int ilEndOffset)
+ {
+ Debug.Assert(symbolReaderHandle != IntPtr.Zero);
+ localVarName = null;
+ ilStartOffset = 0;
+ ilEndOffset = 0;
+
+ GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle);
+ MetadataReader reader = ((OpenedReader)gch.Target).Reader;
+
+ try
+ {
+ Handle handle = MetadataTokens.Handle(methodToken);
+ if (handle.Kind != HandleKind.MethodDefinition)
+ return false;
+
+ MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
+ LocalScopeHandleCollection localScopes = reader.GetLocalScopes(methodDebugHandle);
+ foreach (LocalScopeHandle scopeHandle in localScopes)
+ {
+ LocalScope scope = reader.GetLocalScope(scopeHandle);
+ LocalVariableHandleCollection localVars = scope.GetLocalVariables();
+ foreach (LocalVariableHandle varHandle in localVars)
+ {
+ LocalVariable localVar = reader.GetLocalVariable(varHandle);
+ if (localVar.Index == localIndex)
+ {
+ if (localVar.Attributes == LocalVariableAttributes.DebuggerHidden)
+ return false;
+
+ localVarName = reader.GetString(localVar.Name);
+ ilStartOffset = scope.StartOffset;
+ ilEndOffset = scope.EndOffset;
+ return true;
+ }
+ }
+ }
+ }
+ catch
+ {
+ }
+ return false;
+ }
+
/// <summary>
/// Returns local variable name for given local index and IL offset.
/// </summary>
mdMethodDef methodToken,
ULONG localIndex,
std::string ¶mName,
- ICorDebugValue** ppValue)
+ ICorDebugValue** ppValue,
+ ULONG32 *pIlStart,
+ ULONG32 *pIlEnd)
{
HRESULT Status;
return E_FAIL;
}
- IfFailRet(info_pair->second.symbols->GetNamedLocalVariable(pILFrame, methodToken, localIndex, wParamName, _countof(wParamName), ppValue));
+ IfFailRet(info_pair->second.symbols->GetNamedLocalVariableAndScope(pILFrame, methodToken, localIndex, wParamName, _countof(wParamName), ppValue, pIlStart, pIlEnd));
}
paramName = to_utf8(wParamName);
LoadSymbolsForModuleDelegate SymbolReader::loadSymbolsForModuleDelegate;
DisposeDelegate SymbolReader::disposeDelegate;
ResolveSequencePointDelegate SymbolReader::resolveSequencePointDelegate;
-GetLocalVariableName SymbolReader::getLocalVariableNameDelegate;
+GetLocalVariableNameAndScope SymbolReader::getLocalVariableNameAndScopeDelegate;
GetLineByILOffsetDelegate SymbolReader::getLineByILOffsetDelegate;
GetStepRangesFromIPDelegate SymbolReader::getStepRangesFromIPDelegate;
IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "LoadSymbolsForModule", (void **)&loadSymbolsForModuleDelegate));
IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "Dispose", (void **)&disposeDelegate));
IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "ResolveSequencePoint", (void **)&resolveSequencePointDelegate));
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "GetLocalVariableName", (void **)&getLocalVariableNameDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "GetLocalVariableNameAndScope", (void **)&getLocalVariableNameAndScopeDelegate));
IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "GetLineByILOffset", (void **)&getLineByILOffsetDelegate));
IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "GetStepRangesFromIP", (void **)&getStepRangesFromIPDelegate));
return E_FAIL;
}
-HRESULT SymbolReader::GetNamedLocalVariable(ICorDebugILFrame * pILFrame, mdMethodDef methodToken,
- ULONG localIndex, WCHAR* paramName, ULONG paramNameLen, ICorDebugValue** ppValue)
+HRESULT SymbolReader::GetNamedLocalVariableAndScope(
+ ICorDebugILFrame * pILFrame,
+ mdMethodDef methodToken,
+ ULONG localIndex,
+ WCHAR* paramName,
+ ULONG paramNameLen,
+ ICorDebugValue** ppValue,
+ ULONG32* pIlStart,
+ ULONG32* pIlEnd)
{
HRESULT Status = S_OK;
if (!m_symbolReaderHandle)
return E_FAIL;
- _ASSERTE(getLocalVariableNameDelegate != nullptr);
+ _ASSERTE(getLocalVariableNameAndScopeDelegate != nullptr);
BSTR wszParamName = SysAllocStringLen(0, mdNameLen);
if (wszParamName == NULL)
return E_OUTOFMEMORY;
}
- if (getLocalVariableNameDelegate(m_symbolReaderHandle, methodToken, localIndex, &wszParamName) == FALSE)
+ if (getLocalVariableNameAndScopeDelegate(m_symbolReaderHandle, methodToken, localIndex, &wszParamName, pIlStart, pIlEnd) == FALSE)
{
SysFreeString(wszParamName);
return E_FAIL;
typedef PVOID (*LoadSymbolsForModuleDelegate)(const char*, BOOL, ULONG64, int, ULONG64, int, ReadMemoryDelegate);
typedef void (*DisposeDelegate)(PVOID);
typedef BOOL (*ResolveSequencePointDelegate)(PVOID, const char*, unsigned int, unsigned int*, unsigned int*);
-typedef BOOL (*GetLocalVariableName)(PVOID, int, int, BSTR*);
+typedef BOOL (*GetLocalVariableNameAndScope)(PVOID, int, int, BSTR*, unsigned int*, unsigned int*);
typedef BOOL (*GetLineByILOffsetDelegate)(PVOID, mdMethodDef, ULONG64, ULONG *, BSTR*);
typedef BOOL (*GetStepRangesFromIPDelegate)(PVOID, int, mdMethodDef, unsigned int*, unsigned int*);
static LoadSymbolsForModuleDelegate loadSymbolsForModuleDelegate;
static DisposeDelegate disposeDelegate;
static ResolveSequencePointDelegate resolveSequencePointDelegate;
- static GetLocalVariableName getLocalVariableNameDelegate;
+ static GetLocalVariableNameAndScope getLocalVariableNameAndScopeDelegate;
static GetLineByILOffsetDelegate getLineByILOffsetDelegate;
static GetStepRangesFromIPDelegate getStepRangesFromIPDelegate;
HRESULT LoadSymbols(IMetaDataImport* pMD, ICorDebugModule* pModule);
HRESULT GetLineByILOffset(mdMethodDef MethodToken, ULONG64 IlOffset, ULONG *pLinenum, WCHAR* pwszFileName, ULONG cchFileName);
- HRESULT GetNamedLocalVariable(ICorDebugILFrame * pILFrame, mdMethodDef methodToken, ULONG localIndex, WCHAR* paramName, ULONG paramNameLen, ICorDebugValue **ppValue);
+ HRESULT GetNamedLocalVariableAndScope(ICorDebugILFrame * pILFrame, mdMethodDef methodToken, ULONG localIndex, WCHAR* paramName, ULONG paramNameLen, ICorDebugValue **ppValue, ULONG32* pIlStart, ULONG32* pIlEnd);
HRESULT ResolveSequencePoint(WCHAR* pFilename, ULONG32 lineNumber, TADDR mod, mdMethodDef* pToken, ULONG32* pIlOffset);
HRESULT GetStepRangesFromIP(ULONG64 ip, mdMethodDef MethodToken, ULONG32 *ilStartOffset, ULONG32 *ilEndOffset);
};
#include "torelease.h"
#include "arrayholder.h"
#include "cputil.h"
-
-// Modules
-HRESULT GetFrameNamedLocalVariable(
- ICorDebugModule *pModule,
- ICorDebugILFrame *pILFrame,
- mdMethodDef methodToken,
- ULONG localIndex,
- std::string ¶mName,
- ICorDebugValue** ppValue);
-
#include "typeprinter.h"
// From strike.cpp
mdMethodDef methodToken,
ULONG localIndex,
std::string ¶mName,
- ICorDebugValue** ppValue);
+ ICorDebugValue** ppValue,
+ ULONG32 *pIlStart,
+ ULONG32 *pIlEnd);
#include "typeprinter.h"
ULONG cLocals = 0;
ToRelease<ICorDebugValueEnum> pLocalsEnum;
+ ULONG32 currentIlOffset;
+ CorDebugMappingResult mappingResult;
+ IfFailRet(pILFrame->GetIP(¤tIlOffset, &mappingResult));
+
IfFailRet(pILFrame->EnumerateLocalVariables(&pLocalsEnum));
IfFailRet(pLocalsEnum->GetCount(&cLocals));
if (cLocals > 0)
std::string paramName;
ToRelease<ICorDebugValue> pValue;
- Status = GetFrameNamedLocalVariable(pModule, pILFrame, methodDef, i, paramName, &pValue);
+ ULONG32 ilStart;
+ ULONG32 ilEnd;
+ Status = GetFrameNamedLocalVariable(pModule, pILFrame, methodDef, i, paramName, &pValue, &ilStart, &ilEnd);
if (FAILED(Status))
continue;
+ if (currentIlOffset < ilStart || currentIlOffset >= ilEnd)
+ continue;
+
if (Status == S_FALSE)
break;
#include "torelease.h"
#include "arrayholder.h"
-
-// Modules
-HRESULT GetFrameNamedLocalVariable(
- ICorDebugModule *pModule,
- ICorDebugILFrame *pILFrame,
- mdMethodDef methodToken,
- ULONG localIndex,
- std::string ¶mName,
- ICorDebugValue** ppValue);
-
#include "typeprinter.h"
// Valuewalk