0

I would like to distribute and executable file built in C++ with full optimization in release mode. I am generating a core dump in case of unhandled exception and I would like to be able to get a readable call stack out of the minidump.

Online I see solutions that engage the /DEBUG option, but when I enable that option the executable file becomes sensibly bigger. My worries are that:

  • maybe visual studio embeds information within the exe so that it would be easier to reverse engineer it
  • it is not a fully optimized executable as it was without the /DEBUG option

Otherwise why the file would be bigger?

Isn't there the possibility to just keep aside the debug information in a file (isn't the pdb file meant for that?) such that it would be enough to reconstruct the call stack?

Do I have to enable other options together with /DEBUG maybe so that the exe would not increase in size?

I'm not necessarily interested to exactly which instruction cause the issue, but at least I would need to have a reliable and readable reconstruction of the call stack so I can identify the function responsible of the crash.

higlu
  • 433
  • 3
  • 9
  • What are all the options you're sending to the build tools? `/Z7`, for instance, embeds debug info into the .obj files, which you do not want. See here: https://learn.microsoft.com/en-us/cpp/build/reference/debug-generate-debug-info?view=msvc-170 and see here: https://learn.microsoft.com/en-us/cpp/build/reference/z7-zi-zi-debug-information-format?view=msvc-170 – veefu Mar 21 '23 at 13:32
  • 2
    Configure VS to generate a PDB file, even for your Release builds, and make sure you hang on to it. Then, when a crash dump makes it back to base, make sure the PDB file is in the same folder as the crash dump, along with your .exe file, and when you open the crash dump it should all 'just work'. – Paul Sanders Mar 21 '23 at 13:40

2 Answers2

2

You probably need the /ZI or /Zi options along with the /DEBUG:FULL.

It's pretty standard practice to archive .pdb files for each release internally. Then, when a customer reports a crash, the memory dump can be matched with the correct version's debug info and the debugger gives a decent stack-trace.

Archive the debug info for any .dlls, shipped with your product as well. If the crash happens within .dll code, the debugger won't be able to create a sensible stack trace without their .pdbs.

veefu
  • 2,820
  • 1
  • 19
  • 29
  • thanks for your answer. However despite adding /DEBUG option along with the /Zi option, the executable grows of a few megabytes anyway – higlu Mar 21 '23 at 16:12
1

As @veefu mentioned, /Zi together with /DEBUG option is needed, but that still makes the size much bigger.

It turns out though that /OPT:REF option is also needed because /DEBUG disable that automatically, therefore you need to explicitly re-state it.

Here is what you need to set if you use CMake:

set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF")
higlu
  • 433
  • 3
  • 9