gluck / il-repack

Open-source alternative to ILMerge
Apache License 2.0
1.16k stars 214 forks source link

ILRepacked DLL is looking for PDB files in a non-existent subfolder #352

Closed tippmar-nr closed 6 months ago

tippmar-nr commented 6 months ago

We're using NuGet package v2.0.27 in our project and when we build our DLL, the embedded path to the .PDB file references a non-existent subfolder below the location where our DLL was written during ILRepack. If we roll back to NuGet version 2.0.16, we don't see that issue.

From Core.csproj:

    <PropertyGroup>
      <ILRepackCommand>"$(ILRepack)" --parallel --internalize --norepackres --keepotherversionreferences --keyfile:"$(AssemblyOriginatorKeyFile)" --lib:"$(ILRepackSearchDirOutputPath)" --out:"$(OutputPath)..\$(TargetFramework)-ILRepacked\$(AssemblyName).dll" "$(TargetPath)" "@(ILRepackInclude, '" "')"</ILRepackCommand>
    </PropertyGroup>

Our ILRepacked DLL is written to

C:\Source\Repos\newrelic-dotnet-agent\src\_build\AnyCPU-Debug\NewRelic.Agent.Core\netstandard2.0-ILRepacked

But when I run

dumpbin /headers NewRelic.Agent.Core.dll | findstr RSDS

I get the following:

    65CBDA7D cv            B4 0030BF78   30A178    Format: RSDS, {397A64F2-C290-49CD-B1B2-AB7A6AF97AC6}, 1, C:\Source\Repos\newrelic-dotnet-agent\src\_build\AnyCPU-Release\NewRelic.Agent.Core\netstandard2.0-ILRepacked\ILRepack-54844-877183\NewRelic.Agent.Core.pdb

Note the additional subfolder ILRepack-54844-877183 in the path -- that folder doesn't exist on my machine, so when I try to debug the ILRepacked DLL, the debugger can't find the PDB.

Running dumpbin after building with ILRepack v2.0.16 shows the expected value:

65CCDE70 cv            9E 003217E8   31F9E8    Format: RSDS, {BB7E5805-6314-4266-A3B6-A7E17C4BE842}, 1, C:\Source\Repos\newrelic-dotnet-agent\src\_build\AnyCPU-Release\NewRelic.Agent.Core\netstandard2.0-ILRepacked\NewRelic.Agent.Core.pdb
KirillOsenkov commented 6 months ago

good bug, I'm on vacation, will deal with this after Feb 25.

As a workaround, try compiling your input assemblies with DebugType embedded. This will embed the pdbs and sidestep the problem of looking up pdbs altogether.

KirillOsenkov commented 6 months ago

This is strange that this is causing a problem. The path to the pdb embedded into the exe is just a hint anyway. Normally Visual Studio is able to load the pdb if it's in the same location as the dll. Is that not the case for you? What scenario is breaking?

KirillOsenkov commented 6 months ago

Not sure this can be easily fixed as writing the .dll and the .pdb is in the temporary subfolder, and there's no easy way to provide a different path to the .pdb.

However I'm also not sure it's worth fixing because as long as the pdb travels together with the dll and they're in the same directory the debugger will be able to find it. The path embedded into the .dll is only used as a hint for local testing and will be wrong on another machine or if you delete your bin and obj.

tippmar-nr commented 6 months ago

This is strange that this is causing a problem. The path to the pdb embedded into the exe is just a hint anyway. Normally Visual Studio is able to load the pdb if it's in the same location as the dll. Is that not the case for you? What scenario is breaking?

In our case, the Visual Studio debugger would not load symbols for any of our ILRepack'ed DLLs, even when the PDBs were in the same folder as the DLLs. I probably should have called that out in my initial report, but was under the assumption that the embedded path was to blame for the problem.

What changed about how the ILRepack'ed DLLs are being written between 2.0.16 and 2.0.27?

This isn't a pressing issue for us at the moment, as we used your advice to embed the PDBs in our local debug builds and everything is working fine. We don't ship PDBs with our product, so the current solution is working well enough.

KirillOsenkov commented 6 months ago

If the VS debugger is not loading symbols for a pair of .dll + .pdb, that's a separate issue that needs to be investigated.

In the VS modules window, during debugging, you can right-click on the module in question and click Symbol Load Information.

You can also use the pdb tool I wrote, and pass the .dll and the .pdb path to the tool: https://github.com/KirillOsenkov/MetadataTools/tree/main/src/Pdb

A lot has changed between 2.0.16 and 2.0.27 - we moved to a newer version of Mono.Cecil that is the library that is reading and writing .dll and .pdb files. However I doubt it's a bug that was introduced - something else is going wrong and it's hard to say without a concrete repro.

If you ever run into this again we can investigate. However the pdb path embedded into the debug view entry is not the problem.