While DbgHelp provides a convenient API to create backtraces, any executable
linking against DbgHelp gets a more than a significant slow down. Further, it
can only lookup global symbols, as it expects PDB files we can't produce with a
MinGW build.
With some core Kernel32.dll functionality, we can capture stack traces much
faster. Together with the optional libbfd, we can print very fine backtraces.
When --enable-bfd-backtraces is used on Windows, a libbfd.dll is required for
the build. Such a DLL can be created from the binutils sources using:
# build binutils with mingw...
# extract archive members from binutils libraries
x86_64-w64-mingw32-ar x $BINUTILS/bfd/.libs/libbfd.a
x86_64-w64-mingw32-ar x $BINUTILS/intl/libintl.a
x86_64-w64-mingw32-ar x $BINUTILS/libiberty/libiberty.a
# create self-contained libbfd.a, with index
x86_64-w64-mingw32-ar qs libbfd.a *.o
# create DLL from static library
x86_64-w64-mingw32-dlltool -e libbfd.o -l libbfd.lib libbfd.a
x86_64-w64-mingw32-gcc -shared libbfd.a libbfd.o -o libbfd.dll
The invocation of addr2line to resolve backtrace source locations
is slow and cumbersome. When using libbfd directly, we can eliminate
the overhead of the process invocation. Even better, we can cache
library symbol names, bringing wicked fast lookups. As a neat bonus,
we can resolve static function names.