}
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct DbgSequencePoint
+ {
+ public int startLine;
+ public int startColumn;
+ public int endLine;
+ public int endColumn;
+ public int offset;
+ }
+
/// <summary>
/// Read memory callback
/// </summary>
return false;
}
+ internal static bool GetSequencePoints(IntPtr symbolReaderHandle, int methodToken, out IntPtr points, out int pointsCount)
+ {
+ Debug.Assert(symbolReaderHandle != IntPtr.Zero);
+ pointsCount = 0;
+ points = IntPtr.Zero;
+
+ Debug.Assert(symbolReaderHandle != IntPtr.Zero);
+
+ 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();
+ if (methodDebugHandle.IsNil)
+ return false;
+
+ MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle);
+ SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints();
+
+ var list = new List<DbgSequencePoint>();
+ foreach (SequencePoint p in sequencePoints)
+ {
+ list.Add(new DbgSequencePoint() {
+ startLine = p.StartLine,
+ endLine = p.EndLine,
+ startColumn = p.StartColumn,
+ endColumn = p.EndColumn,
+ offset = p.Offset
+ });
+ }
+
+ if (list.Count == 0)
+ return true;
+
+ var structSize = Marshal.SizeOf<DbgSequencePoint>();
+ IntPtr allPoints = Marshal.AllocCoTaskMem(list.Count * structSize);
+ var currentPtr = allPoints;
+
+ foreach (var p in list)
+ {
+ Marshal.StructureToPtr(p, currentPtr, false);
+ currentPtr = (IntPtr)(currentPtr.ToInt64() + structSize);
+ }
+
+ points = allPoints;
+ pointsCount = list.Count;
+ return true;
+ }
+ catch
+ {
+ }
+ return false;
+ }
+
internal static bool GetStepRangesFromIP(IntPtr symbolReaderHandle, int ip, int methodToken, out uint ilStartOffset, out uint ilEndOffset)
{
Debug.Assert(symbolReaderHandle != IntPtr.Zero);
#include "common.h"
#include <string>
+#include <vector>
#include "symbolreader.h"
GetLocalVariableNameAndScope SymbolReader::getLocalVariableNameAndScopeDelegate;
GetLineByILOffsetDelegate SymbolReader::getLineByILOffsetDelegate;
GetStepRangesFromIPDelegate SymbolReader::getStepRangesFromIPDelegate;
+GetSequencePointsDelegate SymbolReader::getSequencePointsDelegate;
+
+const int SymbolReader::HiddenLine = 0xfeefee;
HRESULT SymbolReader::LoadSymbols(IMetaDataImport* pMD, ICorDebugModule* pModule)
{
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));
+ IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "GetSequencePoints", (void **)&getSequencePointsDelegate));
return Status;
}
}
return S_OK;
}
+
+HRESULT SymbolReader::GetSequencePoints(mdMethodDef methodToken, std::vector<SequencePoint> &points)
+{
+ HRESULT Status = S_OK;
+
+ if (m_symbolReaderHandle != 0)
+ {
+ _ASSERTE(getSequencePointsDelegate != nullptr);
+
+ SequencePoint *allocatedPoints = nullptr;
+ int pointsCount = 0;
+
+ if (getSequencePointsDelegate(m_symbolReaderHandle, methodToken, (PVOID*)&allocatedPoints, &pointsCount) == FALSE)
+ {
+ return E_FAIL;
+ }
+
+ points.assign(allocatedPoints, allocatedPoints + pointsCount);
+
+ CoTaskMemFree(allocatedPoints);
+
+ return S_OK;
+ }
+
+ return E_FAIL;
+}
\ No newline at end of file
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*);
+typedef BOOL (*GetSequencePointsDelegate)(PVOID, mdMethodDef, PVOID*, int*);
BOOL SafeReadMemory (TADDR offset, PVOID lpBuffer, ULONG cb,
PULONG lpcbBytesRead);
static GetLocalVariableNameAndScope getLocalVariableNameAndScopeDelegate;
static GetLineByILOffsetDelegate getLineByILOffsetDelegate;
static GetStepRangesFromIPDelegate getStepRangesFromIPDelegate;
+ static GetSequencePointsDelegate getSequencePointsDelegate;
static HRESULT PrepareSymbolReader();
ULONG64 inMemoryPdbSize);
public:
+ static const int HiddenLine;
+ struct __attribute__((packed)) SequencePoint {
+ int32_t startLine;
+ int32_t startColumn;
+ int32_t endLine;
+ int32_t endColumn;
+ int32_t offset;
+ };
+
SymbolReader()
{
m_symbolReaderHandle = 0;
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);
+ HRESULT GetSequencePoints(mdMethodDef methodToken, std::vector<SequencePoint> &points);
};