How can I use a minidump to get readable callstack from executable built in fully optimized release mode?

211 Views Asked by At

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.

2

There are 2 best solutions below

1
veefu On

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.

0
higlu On

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")