|
|
|
@ -3,11 +3,11 @@
@@ -3,11 +3,11 @@
|
|
|
|
|
// </file>
|
|
|
|
|
|
|
|
|
|
using System; |
|
|
|
|
using System.Diagnostics.SymbolStore; |
|
|
|
|
using System.Runtime.InteropServices; |
|
|
|
|
using System.Threading; |
|
|
|
|
|
|
|
|
|
using DebuggerInterop.Core; |
|
|
|
|
using DebuggerInterop.Symbols; |
|
|
|
|
using DebuggerInterop.MetaData; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -17,7 +17,7 @@ namespace DebuggerLibrary
@@ -17,7 +17,7 @@ namespace DebuggerLibrary
|
|
|
|
|
{ |
|
|
|
|
string name; |
|
|
|
|
Module module; |
|
|
|
|
uint token; |
|
|
|
|
SymbolToken token; |
|
|
|
|
uint parentClassToken = 0; |
|
|
|
|
uint attributes; |
|
|
|
|
ICorDebugFrame corFrame; |
|
|
|
@ -39,7 +39,9 @@ namespace DebuggerLibrary
@@ -39,7 +39,9 @@ namespace DebuggerLibrary
|
|
|
|
|
{ |
|
|
|
|
this.corFrame = corFrame; |
|
|
|
|
corFrame.GetFunction(out corFunction); |
|
|
|
|
corFunction.GetToken(out token); |
|
|
|
|
uint functionToken; |
|
|
|
|
corFunction.GetToken(out functionToken); |
|
|
|
|
this.token = new SymbolToken((int)functionToken); |
|
|
|
|
ICorDebugModule corModule; |
|
|
|
|
corFunction.GetModule(out corModule); |
|
|
|
|
module = NDebugger.Modules[corModule]; |
|
|
|
@ -54,7 +56,7 @@ namespace DebuggerLibrary
@@ -54,7 +56,7 @@ namespace DebuggerLibrary
|
|
|
|
|
IntPtr pSigBlob; |
|
|
|
|
uint sigBlobSize; |
|
|
|
|
module.MetaDataInterface.GetMethodProps( |
|
|
|
|
token, |
|
|
|
|
(uint)token.GetToken(), |
|
|
|
|
out parentClassToken, |
|
|
|
|
NDebugger.pString, |
|
|
|
|
NDebugger.pStringLen, |
|
|
|
@ -91,7 +93,7 @@ namespace DebuggerLibrary
@@ -91,7 +93,7 @@ namespace DebuggerLibrary
|
|
|
|
|
|
|
|
|
|
// Helpping properties for symbols
|
|
|
|
|
|
|
|
|
|
internal ISymUnmanagedReader symReader { |
|
|
|
|
internal ISymbolReader symReader { |
|
|
|
|
get { |
|
|
|
|
if (module.SymbolsLoaded == false) throw new SymbolsNotAviableException(); |
|
|
|
|
if (module.SymReader == null) throw new SymbolsNotAviableException(); |
|
|
|
@ -99,7 +101,7 @@ namespace DebuggerLibrary
@@ -99,7 +101,7 @@ namespace DebuggerLibrary
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
internal ISymUnmanagedMethod symMethod { |
|
|
|
|
internal ISymbolMethod symMethod { |
|
|
|
|
get { |
|
|
|
|
return symReader.GetMethod(token); |
|
|
|
|
} |
|
|
|
@ -140,13 +142,22 @@ namespace DebuggerLibrary
@@ -140,13 +142,22 @@ namespace DebuggerLibrary
|
|
|
|
|
ICorDebugStepper stepper; |
|
|
|
|
corFrame.CreateStepper(out stepper); |
|
|
|
|
|
|
|
|
|
uint rangeCount; |
|
|
|
|
symMethod.GetRanges(nextSt.SymUnmanagedDocument, nextSt.StartLine, 0, 0, out rangeCount, IntPtr.Zero); |
|
|
|
|
IntPtr pRanges = Marshal.AllocHGlobal(4*(int)rangeCount); |
|
|
|
|
symMethod.GetRanges(nextSt.SymUnmanagedDocument, nextSt.StartLine, 0, rangeCount, out rangeCount, pRanges); |
|
|
|
|
stepper.StepRange(stepIn?1:0, pRanges, rangeCount); |
|
|
|
|
//uint rangeCount;
|
|
|
|
|
//symMethod.GetRanges(nextSt.SymbolDocument, nextSt.StartLine, 0, 0, out rangeCount, IntPtr.Zero);
|
|
|
|
|
//IntPtr pRanges = Marshal.AllocHGlobal(4*(int)rangeCount);
|
|
|
|
|
//symMethod.GetRanges(nextSt.SymbolDocument, nextSt.StartLine, 0, rangeCount, out rangeCount, pRanges);
|
|
|
|
|
|
|
|
|
|
int[] ranges = symMethod.GetRanges(nextSt.SymbolDocument, nextSt.StartLine, 0); |
|
|
|
|
IntPtr pRanges = Marshal.AllocHGlobal(4*ranges.Length); |
|
|
|
|
for (int i = 0; i < ranges.Length; i++) { |
|
|
|
|
((int*)pRanges.ToPointer())[i] = ranges[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
stepper.StepRange(stepIn?1:0, pRanges, (uint)ranges.Length); |
|
|
|
|
Marshal.FreeHGlobal(pRanges); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDebugger.Continue(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -155,7 +166,7 @@ namespace DebuggerLibrary
@@ -155,7 +166,7 @@ namespace DebuggerLibrary
|
|
|
|
|
get { |
|
|
|
|
SourcecodeSegment retVal = new SourcecodeSegment(); |
|
|
|
|
|
|
|
|
|
ISymUnmanagedMethod symMethod; |
|
|
|
|
ISymbolMethod symMethod; |
|
|
|
|
try { |
|
|
|
|
symMethod = this.symMethod; |
|
|
|
|
} |
|
|
|
@ -166,19 +177,17 @@ namespace DebuggerLibrary
@@ -166,19 +177,17 @@ namespace DebuggerLibrary
|
|
|
|
|
throw new NextStatementNotAviableException(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint sequencePointCount = symMethod.GetSequencePointCount(); |
|
|
|
|
int sequencePointCount = symMethod.SequencePointCount; |
|
|
|
|
|
|
|
|
|
uint[] offsets = new uint[sequencePointCount]; |
|
|
|
|
uint[] startLine = new uint[sequencePointCount]; |
|
|
|
|
uint[] startColumn = new uint[sequencePointCount]; |
|
|
|
|
uint[] endLine = new uint[sequencePointCount]; |
|
|
|
|
uint[] endColumn = new uint[sequencePointCount]; |
|
|
|
|
int[] offsets = new int[sequencePointCount]; |
|
|
|
|
int[] startLine = new int[sequencePointCount]; |
|
|
|
|
int[] startColumn = new int[sequencePointCount]; |
|
|
|
|
int[] endLine = new int[sequencePointCount]; |
|
|
|
|
int[] endColumn = new int[sequencePointCount]; |
|
|
|
|
|
|
|
|
|
ISymUnmanagedDocument[] Doc = new ISymUnmanagedDocument[sequencePointCount]; |
|
|
|
|
ISymbolDocument[] Doc = new ISymbolDocument[sequencePointCount]; |
|
|
|
|
|
|
|
|
|
symMethod.GetSequencePoints( |
|
|
|
|
sequencePointCount, |
|
|
|
|
out sequencePointCount, |
|
|
|
|
offsets, |
|
|
|
|
Doc, |
|
|
|
|
startLine, |
|
|
|
@ -189,18 +198,15 @@ namespace DebuggerLibrary
@@ -189,18 +198,15 @@ namespace DebuggerLibrary
|
|
|
|
|
|
|
|
|
|
uint corInstructionPtr = this.corInstructionPtr; // cache
|
|
|
|
|
|
|
|
|
|
for (uint i = sequencePointCount-1 ; i >= 0; i--) // backwards
|
|
|
|
|
for (int i = sequencePointCount - 1; i >= 0; i--) // backwards
|
|
|
|
|
if (offsets[i] <= corInstructionPtr) |
|
|
|
|
{ |
|
|
|
|
// 0xFeeFee means "code generated by compiler"
|
|
|
|
|
if (startLine[i] == 0xFeeFee) throw new NextStatementNotAviableException(); |
|
|
|
|
|
|
|
|
|
retVal.SymUnmanagedDocument = Doc[i]; |
|
|
|
|
retVal.SymbolDocument = Doc[i]; |
|
|
|
|
|
|
|
|
|
retVal.SymUnmanagedDocument.GetURL(NDebugger.pStringLen, |
|
|
|
|
out NDebugger.unused, // real string lenght
|
|
|
|
|
NDebugger.pString); |
|
|
|
|
retVal.SourceFilename = NDebugger.pStringAsUnicode; |
|
|
|
|
retVal.SourceFilename = retVal.SymbolDocument.URL; |
|
|
|
|
|
|
|
|
|
retVal.ModuleFilename = module.FullPath; |
|
|
|
|
|
|
|
|
@ -244,7 +250,7 @@ namespace DebuggerLibrary
@@ -244,7 +250,7 @@ namespace DebuggerLibrary
|
|
|
|
|
uint paramsFetched; |
|
|
|
|
for (uint i = (uint)(isStatic?0:1); i < argCount; i++) { |
|
|
|
|
uint paramToken; |
|
|
|
|
Module.MetaDataInterface.EnumParams(ref paramEnumPtr , token, out paramToken, 1, out paramsFetched); |
|
|
|
|
Module.MetaDataInterface.EnumParams(ref paramEnumPtr , (uint)token.GetToken(), out paramToken, 1, out paramsFetched); |
|
|
|
|
if (paramsFetched == 0) break; |
|
|
|
|
|
|
|
|
|
ICorDebugValue arg; |
|
|
|
@ -268,8 +274,8 @@ namespace DebuggerLibrary
@@ -268,8 +274,8 @@ namespace DebuggerLibrary
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// local variables
|
|
|
|
|
ISymUnmanagedScope symRootScope; |
|
|
|
|
symRootScope = symMethod.GetRootScope(); |
|
|
|
|
ISymbolScope symRootScope; |
|
|
|
|
symRootScope = symMethod.RootScope; |
|
|
|
|
AddScopeToVariableCollection(symRootScope, ref collection); |
|
|
|
|
|
|
|
|
|
// Properties
|
|
|
|
@ -315,52 +321,26 @@ namespace DebuggerLibrary
@@ -315,52 +321,26 @@ namespace DebuggerLibrary
|
|
|
|
|
return collection; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private unsafe void AddScopeToVariableCollection(ISymUnmanagedScope symScope, ref VariableCollection collection) |
|
|
|
|
private unsafe void AddScopeToVariableCollection(ISymbolScope symScope, ref VariableCollection collection) |
|
|
|
|
{ |
|
|
|
|
uint childScopesCount; |
|
|
|
|
symScope.GetChildren(0, out childScopesCount, null); |
|
|
|
|
|
|
|
|
|
if (childScopesCount > 0) { |
|
|
|
|
ISymUnmanagedScope[] childScopes = new ISymUnmanagedScope[childScopesCount]; |
|
|
|
|
|
|
|
|
|
symScope.GetChildren(childScopesCount, out childScopesCount, childScopes); |
|
|
|
|
|
|
|
|
|
foreach(ISymUnmanagedScope childScope in childScopes) { |
|
|
|
|
AddScopeToVariableCollection(childScope, ref collection); |
|
|
|
|
} |
|
|
|
|
foreach(ISymbolScope childScope in symScope.GetChildren()) { |
|
|
|
|
AddScopeToVariableCollection(childScope, ref collection); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AddVariablesToVariableCollection(symScope, ref collection); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private unsafe void AddVariablesToVariableCollection(ISymUnmanagedScope symScope, ref VariableCollection collection) |
|
|
|
|
private unsafe void AddVariablesToVariableCollection(ISymbolScope symScope, ref VariableCollection collection) |
|
|
|
|
{ |
|
|
|
|
uint varCount; |
|
|
|
|
varCount = symScope.GetLocalCount(); |
|
|
|
|
|
|
|
|
|
if (varCount > 0) { |
|
|
|
|
ISymUnmanagedVariable[] symVars = new ISymUnmanagedVariable[varCount]; |
|
|
|
|
|
|
|
|
|
symScope.GetLocals(varCount, out varCount, symVars); |
|
|
|
|
|
|
|
|
|
foreach (ISymUnmanagedVariable symVar in symVars) { |
|
|
|
|
AddVariableToVariableCollection(symVar , ref collection); |
|
|
|
|
} |
|
|
|
|
foreach (ISymbolVariable symVar in symScope.GetLocals()) { |
|
|
|
|
AddVariableToVariableCollection(symVar , ref collection); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private unsafe void AddVariableToVariableCollection(ISymUnmanagedVariable symVar, ref VariableCollection collection) |
|
|
|
|
private unsafe void AddVariableToVariableCollection(ISymbolVariable symVar, ref VariableCollection collection) |
|
|
|
|
{ |
|
|
|
|
ICorDebugValue runtimeVar; |
|
|
|
|
uint address; |
|
|
|
|
address = symVar.GetAddressField1(); |
|
|
|
|
corILFrame.GetLocalVariable(address, out runtimeVar); |
|
|
|
|
|
|
|
|
|
symVar.GetName(NDebugger.pStringLen, |
|
|
|
|
out NDebugger.unused, // real string name
|
|
|
|
|
NDebugger.pString); |
|
|
|
|
|
|
|
|
|
collection.Add(VariableFactory.CreateVariable(runtimeVar, NDebugger.pStringAsUnicode)); |
|
|
|
|
corILFrame.GetLocalVariable((uint)symVar.AddressField1, out runtimeVar); |
|
|
|
|
collection.Add(VariableFactory.CreateVariable(runtimeVar, symVar.Name)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|