首页 > 解决方案 > Mono.Cecil AssemblyDefinition.ReadAssembly():找不到文件的符号

问题描述

我使用的是 nuget 的最新版本 Mono.Cecil 0.10.3.0。

这一行:

var ad = AssemblyDefinition.ReadAssembly(@"C:\path\to\my\library.dll", new ReaderParameters { ReadSymbols = true });

抛出异常:

Mono.Cecil.Cil.SymbolsNotFoundException was unhandled by user code
  HResult=-2147024894
  Message=No symbol found for file: C:\path\to\my\library.dll
  Source=Mono.Cecil
  StackTrace:
       at Mono.Cecil.Cil.DefaultSymbolReaderProvider.GetSymbolReader(ModuleDefinition module, String fileName)
       at Mono.Cecil.ModuleReader.ReadSymbols(ModuleDefinition module, ReaderParameters parameters)
       at Mono.Cecil.ModuleReader.CreateModule(Image image, ReaderParameters parameters)
       at Mono.Cecil.ModuleDefinition.ReadModule(String fileName, ReaderParameters parameters)
       at Mono.Cecil.AssemblyDefinition.ReadAssembly(String fileName, ReaderParameters parameters)

这个错误是什么意思?是不是找不到 library.pdb?因为 .pdb 文件存在。

这是关于这个问题的另一个奇怪之处。ReadAssembly() 调用将在代码集的一个版本中正常工作,但随后我将在 git 中创建一个新的代码分支,并在新分支中尝试同一行,它会失败。

标签: c#.netcilmono.cecil

解决方案


我不确定这会对您有所帮助,而且我从未亲自使用过它,但我查看了此处的代码并对其进行了评论以供您娱乐。

static void ReadSymbols(ModuleDefinition module, ReaderParameters parameters)
{
   var symbol_reader_provider = parameters.SymbolReaderProvider;

   if (symbol_reader_provider == null && parameters.ReadSymbols)
      symbol_reader_provider = new DefaultSymbolReaderProvider(); // we get here

   if (symbol_reader_provider != null)
   {
      module.SymbolReaderProvider = symbol_reader_provider;

      var reader = parameters.SymbolStream != null
                      ? symbol_reader_provider.GetSymbolReader(module, parameters.SymbolStream)
                      : symbol_reader_provider.GetSymbolReader(module, module.FileName); // we get here

      ...
   }

   ...
}

实施GetSymbolReader

public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName)
{

   ...

   // this just changes the extension
   var pdb_file_name = Mixin.GetPdbFileName(fileName);

   // this should be true
   if (File.Exists(pdb_file_name))
   {
      if (Mixin.IsPortablePdb(Mixin.GetPdbFileName(fileName)))
         return new PortablePdbReaderProvider().GetSymbolReader(module, fileName);

      try
      {
         return SymbolProvider.GetReaderProvider(SymbolKind.NativePdb).GetSymbolReader(module, fileName);
      }
      catch (Exception)
      {
         // We might not include support for native pdbs.
      }
   }

   // can't find the pdb file, your error
   if (throw_if_no_symbol)
      throw new SymbolsNotFoundException(string.Format("No symbol found for file: {0}", fileName));

   return null;
}

的定义GetPdbFileName

public static string GetPdbFileName(string assemblyFileName)
{
   return Path.ChangeExtension(assemblyFileName, ".pdb");
}

如您所见,这里有些不对劲。这段代码所做的就是

  1. 更改文件名的扩展名以查找PBD

  2. 检查是否存在PBD文件,

  3. 如果不是,则抛出您得到的异常

我认为您需要仔细检查所有内容,还要注意,

// We might not include support for native pdbs.

这是此错误可能引发的唯一其他方式。


推荐阅读