Reducing the size of the .PDB file on Windows

I find it useful to ship debug symbols only for panic unwinds, which on windows requires shipping the associated .PDB file. I am doing this by setting debug=1 in the [profiles.release] section.

However, the .exe is just over 3MB but the .PDB file is 14MB, which is a heavy cost for a stack trace!

Is there a way to shrink the .PDB, or, alternatively, how else can I preserve the stack trace from a panic!?

Thanks!

It looks like the MSVC linker accepts a /PDBSTRIPPED:pdb_file_name argument which tells it to emit a cut down PDB file.

The /PDBSTRIPPED option creates a second program database (PDB) file when you build your program image with any of the compiler or linker options that generate a PDB file (/DEBUG, /Z7, /Zd, or /Zi). This second PDB file omits symbols that you would not want to ship to your customers. The second PDB file will only contain:

  • Public symbols
  • The list of object files and the portions of the executable to which they contribute
  • Frame pointer optimization (FPO) debug records used to traverse the stack

The stripped PDB file will not contain:

  • Type information
  • Line number information
  • Per-object file CodeView symbols such as those for functions, locals, and static data

The full PDB file will still be generated when you use /PDBSTRIPPED.

If you do not create a PDB file, /PDBSTRIPPED is ignored.

You can adjust the arguments rustc sends to the linker with the -Clink-arg=--some-arg command-line argument. cargo has a .cargo/config file which lets you do this in a more structured way, allowing you to only pass the argument to rustc on the desired target.

# /path-to-project-root/.cargo/config
[target.thumbv7em-none-eabi]
rustflags = [
  "-C", "link-arg=-Tlayout.ld",
  "-C", "link-arg=-nostartfiles",
  "-C", "link-arg=-Wl,-Map=firmware.map",
  "-C", "target-cpu=cortex-m4",
  "-C", "target-feature=+soft-float",
]

(relevant chapter in the docs)

Thanks Michael - I think I need to keep the line number information though? I'll have an experiment.

I'm guessing the linker will expose some knobs to let you control the amount of information that's added to the PDB. Large file sizes due to debug symbols isn't normally a concern for me though, so I've never needed this amount of control.

You could also try enabling LTO on release builds. It may be that extra inlining and optimisations during the linking process will reduce the amount of debug info generated (i.e. if all calls to a function are inlined away, there's no need to generate debug info for it).

1 Like

I wouldn't normally care, only I am chunking a single deployable (Java WAR) into a bunch of smaller .exes - if it was a single .exe it wouldn't be so bad I guess.

How well do the PDBs compress down? I found a random PDB on my computer and it went from 1.8M to 449k. I'm guessing larger files would compress even better because there are more chances for duplicate information.

The smallest I've gotten is 6MB which compressed down to 3MB

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.