Cecil fails to load portable pdb files for crossgen'd assemblies #704

Closed
opened 2020-11-12 21:31:18 -06:00 by eerhardt · 2 comments
eerhardt commented 2020-11-12 21:31:18 -06:00 (Migrated from github.com)

See https://github.com/mono/linker/issues/1620#issuecomment-726012522 for more context.

Using the following code:

				ISymbolReaderProvider _symbolReaderProvider = ...;
				AssemblyDefinition assembly = ...;

				var symbolReader = _symbolReaderProvider.GetSymbolReader (
					assembly.MainModule,
					fileName);

				assembly.MainModule.ReadSymbols (symbolReader);

When the AssemblyDefinition assembly points to a crossgen'd assembly, fails to load the symbols in a portable pdb file.

The reason it fails is because a cross gen'd assembly's Debug Directories has two entries:

>dumpbin /headers C:\Users\eerhardt\.nuget\packages\microsoft.netcore.app.runtime.win-x64\5.0.0-rtm.20508.7\runtimes\win-x64\lib\net5.0\System.Private.Xml.dll

Debug Directories

        Time Type        Size      RVA  Pointer
    -------- ------- -------- -------- --------
    8B4C3C7E cv           11C 00801444   800044    Format: RSDS, {2E2D2AB8-5EC5-3956-8E87-3741A2D79E30}, 1, System.Private.Xml.ni.pdb
    8B4C3C7E cv            77 00801560   800160    Format: RSDS, {62DF6790-3B25-4522-8E89-99FB491C298D}, 1, F:\git\runtime2\artifacts\obj\System.Private.Xml\net6.0-windows-Release\System.Private.Xml.pdb
    00000000 repro          0 00000000        0

And the 2nd entry is the portable pdb entry.

However, ModuleDefinition.ReadSymbols appears to only look at the first entry in the Debug Directories and it throws an exception when the first entry doesn't match the portable pdb's Guid. See the following code:

github.com/jbevain/cecil@0a2f294463/Mono.Cecil/ModuleDefinition.cs (L1060-L1064)

and

github.com/jbevain/cecil@ab5075b3a8/Mono.Cecil.Cil/PortablePdb.cs (L68-L100)

Cecil should continue iterating the list and discover the 2nd entry and match it.

See https://github.com/mono/linker/issues/1620#issuecomment-726012522 for more context. Using the following code: ```C# ISymbolReaderProvider _symbolReaderProvider = ...; AssemblyDefinition assembly = ...; var symbolReader = _symbolReaderProvider.GetSymbolReader ( assembly.MainModule, fileName); assembly.MainModule.ReadSymbols (symbolReader); ``` When the `AssemblyDefinition assembly` points to a crossgen'd assembly, fails to load the symbols in a portable pdb file. The reason it fails is because a cross gen'd assembly's Debug Directories has two entries: ``` >dumpbin /headers C:\Users\eerhardt\.nuget\packages\microsoft.netcore.app.runtime.win-x64\5.0.0-rtm.20508.7\runtimes\win-x64\lib\net5.0\System.Private.Xml.dll Debug Directories Time Type Size RVA Pointer -------- ------- -------- -------- -------- 8B4C3C7E cv 11C 00801444 800044 Format: RSDS, {2E2D2AB8-5EC5-3956-8E87-3741A2D79E30}, 1, System.Private.Xml.ni.pdb 8B4C3C7E cv 77 00801560 800160 Format: RSDS, {62DF6790-3B25-4522-8E89-99FB491C298D}, 1, F:\git\runtime2\artifacts\obj\System.Private.Xml\net6.0-windows-Release\System.Private.Xml.pdb 00000000 repro 0 00000000 0 ``` And the 2nd entry is the portable pdb entry. However, `ModuleDefinition.ReadSymbols` appears to only look at the first entry in the `Debug Directories` and it throws an exception when the first entry doesn't match the portable pdb's Guid. See the following code: https://github.com/jbevain/cecil/blob/0a2f2944638c13987d8a2318bc34bd64fdac55fd/Mono.Cecil/ModuleDefinition.cs#L1060-L1064 and https://github.com/jbevain/cecil/blob/ab5075b3a885ffd5bee5d347b79ce71aabeb32d1/Mono.Cecil.Cil/PortablePdb.cs#L68-L100 Cecil should continue iterating the list and discover the 2nd entry and match it.
jbevain commented 2020-11-13 11:09:22 -06:00 (Migrated from github.com)

Good catch. Any chance you could attach a dll here that reproduces the issue?

Good catch. Any chance you could attach a dll here that reproduces the issue?
eerhardt commented 2020-11-13 11:26:58 -06:00 (Migrated from github.com)

No problem. You can use any dll that is in the .NET Core's runtimepack for win-x64. I found it using System.Private.Xml, so I've attached that assembly and its corresponding portable pdb in the following .zip:

System.Private.Xml.zip

No problem. You can use any dll that is in the [.NET Core's runtimepack for win-x64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.win-x64/5.0.0). I found it using System.Private.Xml, so I've attached that assembly and its corresponding portable pdb in the following .zip: [System.Private.Xml.zip](https://github.com/jbevain/cecil/files/5538351/System.Private.Xml.zip)
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-jbevain/cecil#704
No description provided.