How to generate symbol files when distributing release binaries on Windows?

If I want to distribute a Swift Windows release-mode executable or dynamic library using SPM with most of the debug information in the binary itself stripped but want to be able to symbolicate minidumps, what do I do?

Does

swift build -c release -Xswiftc -g -Xswiftc -debug-info-format=codeview -Xlinker -debug

do the right thing, or is there something better for "distribution" binaries where I don't necessarily want symbols to be distributed to the end user?

I'm gonna cc @compnerd (I know, I know, sorry) because it would be great to have a canonical answer.

1 Like

That would technically do the right thing of generating PDBs. That would work to a certain extent but is what is needed to symbolicate mini dumps. If you’re on a recent snapshot I would say that the way to do this is: swift build -debug-info-format=codeview because I like simpler command lines :slight_smile:

The better solution would be to use DWARF, and then try to use objcopy to strip the DWARF. That would give you better debugging overall, but I do remember having some issues with this (where sometimes the binary could get corrupted). We include llvm-objcopy in the toolchain distribution so the necessary tools should be readily available.

Figuring out what works and doesn’t work for the objcopy route would be nice, but there are currently other things that I’m focused on. If someone else wants to take that on, it would be wonderful.

Thanks for your reply @compnerd!

In my case I'm using Sentry and they seem to only support PE/PDB for symbolication on Windows.

So for Windows + Swift 5.10.1, it seems like:

swift build -c release -debug-info-format=codeview -Xlinker /pdbaltpath:%_PDB%

I've included that pdbaltpath bit because I believe otherwise the PDB's absolute path will be included in the distributed binary, which I would prefer not to have included. I believe %_PDB% will include just the name of the PDB file.

Ah, in that case, that command seems like what you want. If you would like to strip the reference to the build path, then, yes, -Xlinker /pdbaltpath:%_PDB% seems correct.

1 Like

Made an issue on swiftlang/swift about this:

This is trickier than it seems at first blush. The problem is today if we start including the debug symbols, the installer will fall due to the size. Additionally, it would make the installer unreasonable to distribute: the maximally compressed installer ends up at about 10-20 GiB. That is possible to overcome with multiple cabinets for the debug information, but in order for us to be able to distribute the symbols, we would need to switch to an online installer rather than the offline installer we create today. The infrastructure for this is in place in the installer, however, that requires additional work on the server side to host the cabinets and MSI files.

CC: @mishal_shah

I am certainly not expecting the debug symbols to get shipped with the toolchain installer (though some sort of "online" installer component for that as you mention might be cool). Even just a .zip file of the .pdb debug files or something would be sufficient. I realize it's going to be very large though, and I'm not entirely sure how one hosts files that large...

The installer is actually setup in a way that makes this more interesting/reasonable. We have components that can be excluded - e.g. ide integration. This would mean that you don't need the symbols for that component. Each component is a MSI, and we could have each MSI have the optional PDBs, allowing a smaller download.