Browse Source

Fix "Select PDB" command when working with bundles.

pull/2221/head
Siegfried Pammer 5 years ago
parent
commit
924e7a0ec4
  1. 3
      ICSharpCode.Decompiler.PdbProvider.Cecil/MonoCecilDebugInfoProvider.cs
  2. 1
      ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs
  3. 3
      ILSpy/AssemblyList.cs
  4. 3
      ILSpy/Commands/SelectPdbContextMenuEntry.cs
  5. 18
      ILSpy/DebugInfo/DebugInfoUtils.cs
  6. 15
      ILSpy/DebugInfo/PortableDebugInfoProvider.cs
  7. 35
      ILSpy/LoadedAssembly.cs
  8. 2
      ILSpy/TreeNodes/AssemblyTreeNode.cs

3
ICSharpCode.Decompiler.PdbProvider.Cecil/MonoCecilDebugInfoProvider.cs

@ -50,6 +50,7 @@ namespace ICSharpCode.Decompiler.PdbProvider
} }
this.Description = description ?? $"Loaded from PDB file: {pdbFileName}"; this.Description = description ?? $"Loaded from PDB file: {pdbFileName}";
this.SourceFileName = pdbFileName;
var image = module.Reader.GetEntireImage(); var image = module.Reader.GetEntireImage();
this.debugInfo = new Dictionary<SRM.MethodDefinitionHandle, (IList<SequencePoint> SequencePoints, IList<Variable> Variables)>(); this.debugInfo = new Dictionary<SRM.MethodDefinitionHandle, (IList<SequencePoint> SequencePoints, IList<Variable> Variables)>();
@ -97,6 +98,8 @@ namespace ICSharpCode.Decompiler.PdbProvider
public string Description { get; } public string Description { get; }
public string SourceFileName { get; }
public IList<SequencePoint> GetSequencePoints(SRM.MethodDefinitionHandle handle) public IList<SequencePoint> GetSequencePoints(SRM.MethodDefinitionHandle handle)
{ {
if (!debugInfo.TryGetValue(handle, out var info)) if (!debugInfo.TryGetValue(handle, out var info))

1
ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs

@ -23,5 +23,6 @@ namespace ICSharpCode.Decompiler.DebugInfo
IList<SequencePoint> GetSequencePoints(MethodDefinitionHandle method); IList<SequencePoint> GetSequencePoints(MethodDefinitionHandle method);
IList<Variable> GetVariables(MethodDefinitionHandle method); IList<Variable> GetVariables(MethodDefinitionHandle method);
bool TryGetName(MethodDefinitionHandle method, int index, out string name); bool TryGetName(MethodDefinitionHandle method, int index, out string name);
string SourceFileName { get; }
} }
} }

3
ILSpy/AssemblyList.cs

@ -252,9 +252,8 @@ namespace ICSharpCode.ILSpy
public LoadedAssembly ReloadAssembly(LoadedAssembly target) public LoadedAssembly ReloadAssembly(LoadedAssembly target)
{ {
var index = this.assemblies.IndexOf(target); var index = this.assemblies.IndexOf(target);
var newAsm = new LoadedAssembly(this, target.FileName); var newAsm = new LoadedAssembly(this, target.FileName, pdbFileName: target.PdbFileName);
newAsm.IsAutoLoaded = target.IsAutoLoaded; newAsm.IsAutoLoaded = target.IsAutoLoaded;
newAsm.PdbFileOverride = target.PdbFileOverride;
lock (assemblies) lock (assemblies)
{ {
this.assemblies.Remove(target); this.assemblies.Remove(target);

3
ILSpy/Commands/SelectPdbContextMenuEntry.cs

@ -43,8 +43,7 @@ namespace ICSharpCode.ILSpy
using (context.TreeView.LockUpdates()) using (context.TreeView.LockUpdates())
{ {
assembly.PdbFileOverride = dlg.FileName; assembly.LoadDebugInfo(dlg.FileName);
assembly.AssemblyList.ReloadAssembly(assembly);
} }
MainWindow.Instance.SelectNode(MainWindow.Instance.FindNodeByPath(new[] { assembly.FileName }, true)); MainWindow.Instance.SelectNode(MainWindow.Instance.FindNodeByPath(new[] { assembly.FileName }, true));

18
ILSpy/DebugInfo/DebugInfoUtils.cs

@ -37,12 +37,15 @@ namespace ICSharpCode.Decompiler.PdbProvider
// try to open portable pdb file/embedded pdb info: // try to open portable pdb file/embedded pdb info:
if (TryOpenPortablePdb(module, out var provider, out var pdbFileName)) if (TryOpenPortablePdb(module, out var provider, out var pdbFileName))
{ {
return new PortableDebugInfoProvider(pdbFileName, provider); return new PortableDebugInfoProvider(pdbFileName, provider, module.FileName);
} }
else else
{ {
// search for pdb in same directory as dll // search for pdb in same directory as dll
pdbFileName = Path.Combine(Path.GetDirectoryName(module.FileName), Path.GetFileNameWithoutExtension(module.FileName) + ".pdb"); pdbFileName = Path.Combine(
Path.GetDirectoryName(module.FileName),
Path.GetFileNameWithoutExtension(module.FileName) + ".pdb"
);
if (File.Exists(pdbFileName)) if (File.Exists(pdbFileName))
{ {
return new MonoCecilDebugInfoProvider(module, pdbFileName); return new MonoCecilDebugInfoProvider(module, pdbFileName);
@ -75,14 +78,15 @@ namespace ICSharpCode.Decompiler.PdbProvider
{ {
stream.Position = 0; stream.Position = 0;
var provider = MetadataReaderProvider.FromPortablePdbStream(stream); var provider = MetadataReaderProvider.FromPortablePdbStream(stream);
return new PortableDebugInfoProvider(pdbFileName, provider); return new PortableDebugInfoProvider(pdbFileName, provider, module.FileName);
} }
} }
const string LegacyPDBPrefix = "Microsoft C/C++ MSF 7.00"; const string LegacyPDBPrefix = "Microsoft C/C++ MSF 7.00";
static readonly byte[] buffer = new byte[LegacyPDBPrefix.Length]; static readonly byte[] buffer = new byte[LegacyPDBPrefix.Length];
static bool TryOpenPortablePdb(PEFile module, out MetadataReaderProvider provider, out string pdbFileName) static bool TryOpenPortablePdb(PEFile module,
out MetadataReaderProvider provider, out string pdbFileName)
{ {
provider = null; provider = null;
pdbFileName = null; pdbFileName = null;
@ -91,12 +95,14 @@ namespace ICSharpCode.Decompiler.PdbProvider
{ {
if (entry.IsPortableCodeView) if (entry.IsPortableCodeView)
{ {
return reader.TryOpenAssociatedPortablePdb(module.FileName, OpenStream, out provider, out pdbFileName); return reader.TryOpenAssociatedPortablePdb(module.FileName, OpenStream,
out provider, out pdbFileName);
} }
if (entry.Type == DebugDirectoryEntryType.CodeView) if (entry.Type == DebugDirectoryEntryType.CodeView)
{ {
string pdbDirectory = Path.GetDirectoryName(module.FileName); string pdbDirectory = Path.GetDirectoryName(module.FileName);
pdbFileName = Path.Combine(pdbDirectory, Path.GetFileNameWithoutExtension(module.FileName) + ".pdb"); pdbFileName = Path.Combine(
pdbDirectory, Path.GetFileNameWithoutExtension(module.FileName) + ".pdb");
if (File.Exists(pdbFileName)) if (File.Exists(pdbFileName))
{ {
Stream stream = OpenStream(pdbFileName); Stream stream = OpenStream(pdbFileName);

15
ILSpy/DebugInfo/PortableDebugInfoProvider.cs

@ -27,20 +27,27 @@ namespace ICSharpCode.Decompiler.PdbProvider
class PortableDebugInfoProvider : IDebugInfoProvider class PortableDebugInfoProvider : IDebugInfoProvider
{ {
string pdbFileName; string pdbFileName;
string moduleFileName;
internal MetadataReaderProvider Provider { get; } internal MetadataReaderProvider Provider { get; }
internal bool IsEmbedded => pdbFileName == null; internal bool IsEmbedded => pdbFileName == null;
public PortableDebugInfoProvider(string pdbFileName, MetadataReaderProvider provider) public PortableDebugInfoProvider(string pdbFileName, MetadataReaderProvider provider,
string moduleFileName)
{ {
this.pdbFileName = pdbFileName; this.pdbFileName = pdbFileName;
this.Provider = provider; this.moduleFileName = moduleFileName;
this.Provider = provider ?? throw new ArgumentNullException(nameof(provider));
} }
public string Description => pdbFileName == null ? "Embedded in this assembly" : $"Loaded from portable PDB: {pdbFileName}"; public string Description => pdbFileName == null
? "Embedded in this assembly"
: $"Loaded from portable PDB: {pdbFileName}";
public IList<Decompiler.DebugInfo.SequencePoint> GetSequencePoints(MethodDefinitionHandle method) public string SourceFileName => pdbFileName ?? moduleFileName;
public IList<DebugInfo.SequencePoint> GetSequencePoints(MethodDefinitionHandle method)
{ {
var metadata = Provider.GetMetadataReader(); var metadata = Provider.GetMetadataReader();
var debugInfo = metadata.GetMethodDebugInformation(method); var debugInfo = metadata.GetMethodDebugInformation(method);

35
ILSpy/LoadedAssembly.cs

@ -85,10 +85,12 @@ namespace ICSharpCode.ILSpy
public LoadedAssembly ParentBundle { get; } public LoadedAssembly ParentBundle { get; }
public LoadedAssembly(AssemblyList assemblyList, string fileName, Task<Stream> stream = null, IAssemblyResolver assemblyResolver = null) public LoadedAssembly(AssemblyList assemblyList, string fileName,
Task<Stream> stream = null, IAssemblyResolver assemblyResolver = null, string pdbFileName = null)
{ {
this.assemblyList = assemblyList ?? throw new ArgumentNullException(nameof(assemblyList)); this.assemblyList = assemblyList ?? throw new ArgumentNullException(nameof(assemblyList));
this.fileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); this.fileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
this.PdbFileName = pdbFileName;
this.providedAssemblyResolver = assemblyResolver; this.providedAssemblyResolver = assemblyResolver;
this.loadingTask = Task.Run(() => LoadAsync(stream)); // requires that this.fileName is set this.loadingTask = Task.Run(() => LoadAsync(stream)); // requires that this.fileName is set
@ -256,7 +258,10 @@ namespace ICSharpCode.ILSpy
public bool IsAutoLoaded { get; set; } public bool IsAutoLoaded { get; set; }
public string PdbFileOverride { get; set; } /// <summary>
/// Gets the PDB file name or null, if no PDB was found or it's embedded.
/// </summary>
public string PdbFileName { get; private set; }
async Task<LoadResult> LoadAsync(Task<Stream> streamTask) async Task<LoadResult> LoadAsync(Task<Stream> streamTask)
{ {
@ -323,11 +328,21 @@ namespace ICSharpCode.ILSpy
PEFile module = new PEFile(fileName, stream, streamOptions, metadataOptions: options); PEFile module = new PEFile(fileName, stream, streamOptions, metadataOptions: options);
debugInfoProvider = LoadDebugInfo(module);
lock (loadedAssemblies)
{
loadedAssemblies.Add(module, this);
}
return new LoadResult(module);
}
IDebugInfoProvider LoadDebugInfo(PEFile module)
{
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols)
{ {
try try
{ {
debugInfoProvider = DebugInfoUtils.FromFile(module, PdbFileOverride) return DebugInfoUtils.FromFile(module, PdbFileName)
?? DebugInfoUtils.LoadSymbols(module); ?? DebugInfoUtils.LoadSymbols(module);
} }
catch (IOException) catch (IOException)
@ -341,11 +356,15 @@ namespace ICSharpCode.ILSpy
// ignore any errors during symbol loading // ignore any errors during symbol loading
} }
} }
lock (loadedAssemblies) return null;
{ }
loadedAssemblies.Add(module, this);
} public async Task<IDebugInfoProvider> LoadDebugInfo(string fileName)
return new LoadResult(module); {
this.PdbFileName = fileName;
var assembly = await GetPEFileAsync().ConfigureAwait(false);
debugInfoProvider = await Task.Run(() => LoadDebugInfo(assembly));
return debugInfoProvider;
} }
[ThreadStatic] [ThreadStatic]

2
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -124,9 +124,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
} }
tooltip.Inlines.Add(new Bold(new Run("Location: "))); tooltip.Inlines.Add(new Bold(new Run("Location: ")));
tooltip.Inlines.Add(new Run(LoadedAssembly.FileName)); tooltip.Inlines.Add(new Run(LoadedAssembly.FileName));
tooltip.Inlines.Add(new LineBreak());
if (module != null) if (module != null)
{ {
tooltip.Inlines.Add(new LineBreak());
tooltip.Inlines.Add(new Bold(new Run("Architecture: "))); tooltip.Inlines.Add(new Bold(new Run("Architecture: ")));
tooltip.Inlines.Add(new Run(Language.GetPlatformDisplayName(module))); tooltip.Inlines.Add(new Run(Language.GetPlatformDisplayName(module)));
string runtimeName = Language.GetRuntimeDisplayName(module); string runtimeName = Language.GetRuntimeDisplayName(module);

Loading…
Cancel
Save