Browse Source

implement GetMethodsFromDocumentPosition and set breakpoints in all methods (lambdas, etc.) in that location

pull/59/merge
Siegfried Pammer 12 years ago
parent
commit
9cce5d9369
  1. 3
      src/AddIns/Debugger/Debugger.Core/Breakpoint.cs
  2. 4
      src/AddIns/Debugger/Debugger.Core/Interop/CorSym.cs
  3. 18
      src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs
  4. 23
      src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs
  5. 3
      src/AddIns/Debugger/Debugger.Core/Process.cs
  6. 5
      src/AddIns/Debugger/Debugger.Core/StackFrame.cs
  7. 10
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpySymbolSource.cs

3
src/AddIns/Debugger/Debugger.Core/Breakpoint.cs

@ -70,8 +70,7 @@ namespace Debugger @@ -70,8 +70,7 @@ namespace Debugger
public void SetBreakpoint(Module module)
{
foreach(var symbolSource in module.Process.Debugger.SymbolSources) {
var seq = symbolSource.GetSequencePoint(module, this.FileName, this.Line, this.Column);
if (seq != null) {
foreach (var seq in symbolSource.GetSequencePoints(module, this.FileName, this.Line, this.Column)) {
ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken);
ICorDebugFunctionBreakpoint corBreakpoint = corFunction.GetILCode().CreateBreakpoint((uint)seq.ILOffset);
corBreakpoint.Activate(enabled ? 1 : 0);

4
src/AddIns/Debugger/Debugger.Core/Interop/CorSym.cs

@ -77,7 +77,7 @@ namespace Debugger.Interop.CorSym @@ -77,7 +77,7 @@ namespace Debugger.Interop.CorSym
public virtual extern ISymUnmanagedMethod __GetMethodFromDocumentPosition([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
public virtual extern void __GetMethodsFromDocumentPosition([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [In] uint cMethod, out uint pcMethod, [Out] IntPtr pRetVal);
public virtual extern void __GetMethodsFromDocumentPosition([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [In] uint cMethod, out uint pcMethod, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedMethod[] pRetVal);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
public virtual extern void __GetMethodVersion([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedMethod pMethod, out int version);
@ -332,7 +332,7 @@ namespace Debugger.Interop.CorSym @@ -332,7 +332,7 @@ namespace Debugger.Interop.CorSym
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void __GetSymbolStoreFileName([In] uint cchName, out uint pcchName, [Out] IntPtr szName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void __GetMethodsFromDocumentPosition([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [In] uint cMethod, out uint pcMethod, [Out] IntPtr pRetVal);
void __GetMethodsFromDocumentPosition([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [In] uint cMethod, out uint pcMethod, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedMethod[] pRetVal);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void __GetDocumentVersion([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument pDoc, out int version, out int pbCurrent);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]

18
src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs

@ -67,9 +67,14 @@ namespace Debugger.Interop.CorSym @@ -67,9 +67,14 @@ namespace Debugger.Interop.CorSym
return returnValue;
}
public static void GetMethodsFromDocumentPosition(this CorSymReader_SxSClass instance, ISymUnmanagedDocument document, uint line, uint column, uint cMethod, out uint pcMethod, IntPtr pRetVal)
public static ISymUnmanagedMethod[] GetMethodsFromDocumentPosition(this CorSymReader_SxSClass instance, ISymUnmanagedDocument document, uint line, uint column)
{
instance.__GetMethodsFromDocumentPosition(document, line, column, cMethod, out pcMethod, pRetVal);
uint count;
instance.__GetMethodsFromDocumentPosition(document, line, column, 0, out count, new ISymUnmanagedMethod[0]);
var methods = new ISymUnmanagedMethod[count];
instance.__GetMethodsFromDocumentPosition(document, line, column, count, out count, methods);
ProcessOutParameter(methods);
return methods;
}
public static int GetMethodVersion(this CorSymReader_SxSClass instance, ISymUnmanagedMethod pMethod)
@ -485,9 +490,14 @@ namespace Debugger.Interop.CorSym @@ -485,9 +490,14 @@ namespace Debugger.Interop.CorSym
instance.__GetSymbolStoreFileName(cchName, out pcchName, szName);
}
public static void GetMethodsFromDocumentPosition(this ISymUnmanagedReader instance, ISymUnmanagedDocument document, uint line, uint column, uint cMethod, out uint pcMethod, IntPtr pRetVal)
public static ISymUnmanagedMethod[] GetMethodsFromDocumentPosition(this ISymUnmanagedReader instance, ISymUnmanagedDocument document, uint line, uint column)
{
instance.__GetMethodsFromDocumentPosition(document, line, column, cMethod, out pcMethod, pRetVal);
uint count;
instance.__GetMethodsFromDocumentPosition(document, line, column, 0, out count, new ISymUnmanagedMethod[0]);
var methods = new ISymUnmanagedMethod[count];
instance.__GetMethodsFromDocumentPosition(document, line, column, count, out count, methods);
ProcessOutParameter(methods);
return methods;
}
public static void GetDocumentVersion(this ISymUnmanagedReader instance, ISymUnmanagedDocument pDoc, out int version, out int pbCurrent)

23
src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs

@ -72,9 +72,9 @@ namespace Debugger @@ -72,9 +72,9 @@ namespace Debugger
/// <summary> Find sequence point by IL offset </summary>
SequencePoint GetSequencePoint(IMethod method, int iloffset);
/// <summary> Find sequence point by source code location </summary>
/// <summary> Find sequence points by source code location. Might find multiple methods at one location (lambda expressions, etc.) </summary>
/// <remarks> Only source files corresponding to the given module are searched </remarks>
SequencePoint GetSequencePoint(Module module, string filename, int line, int column);
IEnumerable<SequencePoint> GetSequencePoints(Module module, string filename, int line, int column);
/// <summary> Get IL ranges that should be always stepped over by the debugger </summary>
/// <remarks> This is used for compiler generated code </remarks>
@ -190,14 +190,14 @@ namespace Debugger @@ -190,14 +190,14 @@ namespace Debugger
return sequencePoint;
}
public SequencePoint GetSequencePoint(Module module, string filename, int line, int column)
public IEnumerable<SequencePoint> GetSequencePoints(Module module, string filename, int line, int column)
{
// Do not use ISymUnmanagedReader.GetDocument! It is broken if two files have the same name
// Do not use ISymUnmanagedMethod.GetOffset! It sometimes returns negative offset
ISymUnmanagedReader symReader = module.SymReader;
if (symReader == null)
return null; // No symbols
yield break; // No symbols
// Find ISymUnmanagedDocument which excactly matches the filename.
var symDoc = module.SymDocuments.FirstOrDefault(d => string.Equals(filename, d.GetURL(), StringComparison.OrdinalIgnoreCase));
@ -205,16 +205,19 @@ namespace Debugger @@ -205,16 +205,19 @@ namespace Debugger
// Find the file even if the symbol is relative or if the file was moved
var symDocs = module.SymDocuments.Where(d => string.Equals(Path.GetFileName(filename), Path.GetFileName(d.GetURL()), StringComparison.OrdinalIgnoreCase));
symDoc = symDoc ?? symDocs.FirstOrDefault(d => string.Equals(GetSourceCodePath(module.Process, d.GetURL()), filename, StringComparison.OrdinalIgnoreCase));
if (symDoc == null) return null; // Document not found
if (symDoc == null) yield break; // Document not found
ISymUnmanagedMethod symMethod;
ISymUnmanagedMethod symMethod2;
ISymUnmanagedMethod[] symMethods;
try {
uint validLine = symDoc.FindClosestLine((uint)line);
symMethod = symReader.GetMethodFromDocumentPosition(symDoc, (uint)validLine, (uint)column);
symMethods = symReader.GetMethodsFromDocumentPosition(symDoc, validLine, (uint)column);
symMethod2 = symReader.GetMethodFromDocumentPosition(symDoc, (uint)validLine, (uint)column);
} catch {
return null; //Not found
yield break; //Not found
}
foreach (ISymUnmanagedMethod symMethod in symMethods) {
var corFunction = module.CorModule.GetFunctionFromToken(symMethod.GetToken());
int codesize = (int)corFunction.GetILCode().GetSize();
var seqPoints = symMethod.GetSequencePoints(codesize).Where(s => s.StartLine != 0xFEEFEE);
@ -224,7 +227,9 @@ namespace Debugger @@ -224,7 +227,9 @@ namespace Debugger
(line < s.EndLine || (line == s.EndLine && column <= s.EndColumn)));
}
seqPoint = seqPoint ?? seqPoints.FirstOrDefault(s => line <= s.StartLine);
return seqPoint;
if (seqPoint != null)
yield return seqPoint;
}
}
public IEnumerable<ILRange> GetIgnoredILRanges(IMethod method)

3
src/AddIns/Debugger/Debugger.Core/Process.cs

@ -436,8 +436,7 @@ namespace Debugger @@ -436,8 +436,7 @@ namespace Debugger
foreach(var symbolSource in this.Debugger.SymbolSources) {
foreach(Module module in this.Modules) {
// Note the we might get multiple matches
SequencePoint seq = symbolSource.GetSequencePoint(module, fileName, line, column);
if (seq != null) {
foreach (SequencePoint seq in symbolSource.GetSequencePoints(module, fileName, line, column)) {
ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken);
ICorDebugFunctionBreakpoint corBreakpoint = corFunction.GetILCode().CreateBreakpoint((uint)seq.ILOffset);
corBreakpoint.Activate(1);

5
src/AddIns/Debugger/Debugger.Core/StackFrame.cs

@ -198,8 +198,8 @@ namespace Debugger @@ -198,8 +198,8 @@ namespace Debugger
this.Process.AssertPaused();
foreach(var symbolSource in this.Process.Debugger.SymbolSources) {
var seq = symbolSource.GetSequencePoint(this.Module, filename, line, column);
if (seq != null && seq.MethodDefToken == this.MethodInfo.GetMetadataToken()) {
foreach (var seq in symbolSource.GetSequencePoints(this.Module, filename, line, column)) {
if (seq.MethodDefToken == this.MethodInfo.GetMetadataToken()) {
try {
if (dryRun) {
CorILFrame.CanSetIP((uint)seq.ILOffset);
@ -215,6 +215,7 @@ namespace Debugger @@ -215,6 +215,7 @@ namespace Debugger
return true;
}
}
}
return false;
}

10
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpySymbolSource.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@ -57,13 +58,13 @@ namespace ICSharpCode.ILSpyAddIn @@ -57,13 +58,13 @@ namespace ICSharpCode.ILSpyAddIn
return null;
}
public Debugger.SequencePoint GetSequencePoint(Module module, string filename, int line, int column)
public IEnumerable<Debugger.SequencePoint> GetSequencePoints(Module module, string filename, int line, int column)
{
var content = DecompiledViewContent.Get(new FileName(filename));
if (content == null)
return null;
yield break;
if (!FileUtility.IsEqualFileName(module.FullPath, content.AssemblyFile))
return null;
yield break;
TextLocation loc = new TextLocation(line, column);
foreach(var symbols in content.DebugSymbols.Values.Where(s => s.StartLocation <= loc && loc <= s.EndLocation)) {
@ -73,9 +74,8 @@ namespace ICSharpCode.ILSpyAddIn @@ -73,9 +74,8 @@ namespace ICSharpCode.ILSpyAddIn
if (seq == null)
seq = symbols.SequencePoints.FirstOrDefault(p => line <= p.StartLocation.Line);
if (seq != null)
return seq.ToDebugger(symbols, content.VirtualFileName);
yield return seq.ToDebugger(symbols, content.VirtualFileName);
}
return null;
}
public IEnumerable<ILRange> GetIgnoredILRanges(IMethod method)

Loading…
Cancel
Save