dbg
dbg is a library that I now use in all my home-grown projects, containing various different types of assert macros, each of which prints a traceback for the point of failure. It also includes tools for capturing tracebacks of exception throw-sites.
The low-level frame collection and symbol lookup code is also exposed in the public headers should anyone wish to use these facilities in their own assert macros rather than use dbg's directly.
Most notably, this is the first attempt I've made at implementing my own symbol lookup code for MinGW targets. My older stack_trace library uses libbfd and libiberty which are respectively licensed under the GPL and LGPL. dbg is released under the Boost Software License 1.0, meaning the symbol collection method can be freely used in 'closed-source' code.
OS X and Windows are supported. Adaptation to other UNIX systems shouldn't take much work.
Recent activity
Code
Clone the repository using mercurial:
> hg clone https://bitbucket.org/edd/dbg
Or get a zip file of the code.
Quick start
The DBG_ASSERT macro provides a traceback on failure and additional information can be added with the DBG_TAG macro:
DBG_ASSERT(x + y > z), DBG_TAG(x), DBG_TAG(y), DBG_TAG(z);
On failure:
[15:40:10.590283] An assertion has been triggered:
location: assert_example.cpp:36
function: void oops()
condition: x + y > z
'x': -4
'y': 17
'z': 491.72
0x0000000100001653: oops() in build/gcc-debug-64/assert_example/bin/assert_example
0x00000001000018c1: h() in build/gcc-debug-64/assert_example/bin/assert_example
0x00000001000018cc: g() in build/gcc-debug-64/assert_example/bin/assert_example
0x00000001000018d7: f() in build/gcc-debug-64/assert_example/bin/assert_example
0x00000001000018ee: main in build/gcc-debug-64/assert_example/bin/assert_example
0x0000000100001304: start in build/gcc-debug-64/assert_example/bin/assert_exampleOther macros provided include:
DBG_ASSERT_RELATION(x, >=, y)— shorthand forDBG_ASSERT(x >= y), DBG_TAG(x), DBG_TAG(y)DBG_IMPURE_ASSERT— evaluates the asserted expression even when assertions are disabled. The value of the expression is also 'returned' by the macro.DBG_ASSERT_UNREACHABLE— used to assert that a particular code-path is unreachable e.g. thedefaultcase in a switch where all possible values should have been enumerated. Can be used withDBG_TAG.DBG_UNUSUAL— used to log events that can be handled gracefully, but failure indicates something fishy might be going on. Can be tagged withDBG_UTAGin the same way as assertions.DBG_NOTE— used to log notes and the values of variables that might be significant. Disabled unlessDBG_ENABLE_NOTE=1is present as an environment variable.
'Hot' variants of the above macros are also available e.g. DBG_HOT_ASSERT(denominator != 0), DBG_HOT_TAG(denominator);. These are always no-ops unless explicitly enabled. Useful for situations where it is known that normal assertions render builds unusably slow for day-to-day development.
DBG_STATIC_ASSERT provides a static assertion macro that can be used at any scope in C++ source code.
Tracebacks
A traceback can be collected as follows:
#include <dbg/frames.hpp>
#include <dbg/symbols.hpp>
#include <iostream>
dbg::symdb db;
dbg::call_stack<64> traceback;
traceback.collect(0);
traceback.log(db, std::cout);
If DBG_THROW is used to throw exceptions, a traceback will be printed if the exception is not caught by the application:
#include <dbg/throw.hpp>
// ...
DBG_THROW(std::runtime_error("oops"));
[15:58:29.751330] An uncaught exception has caused process termination:
location: throw_example.cpp:18
function: void hurl()
expression: std::runtime_error("oops")
details: oops
0x000000010000179e: hurl() in build/gcc-debug-64/throw_example/bin/throw_example
0x00000001000017f3: h() in build/gcc-debug-64/throw_example/bin/throw_example
0x00000001000017fe: g() in build/gcc-debug-64/throw_example/bin/throw_example
0x0000000100001809: f() in build/gcc-debug-64/throw_example/bin/throw_example
0x0000000100001814: main in build/gcc-debug-64/throw_example/bin/throw_example
0x0000000100001740: start in build/gcc-debug-64/throw_example/bin/throw_example
terminate called throwing an exceptionAnother benefit of using DBG_THROW is that throw-site tracebacks can be obtained even if the exception is caught:
try
{
something_that_throws();
}
catch (...)
{
dbg::throw_info info = dbg::current_exception();
if (!info.empty())
{
// thrown with DBG_THROW.
dbg::call_stack<256> *traceback = info.trace;
// ...
}
}
Further reading
Additional information is available on the dbg wiki, including customization options and more in-depth usage instructions.
Comments
[12/12/2012 at 04:27:58]
Hi Steve. Please see the instructions on the wiki.
[25/12/2012 at 23:17:13]
Hi, very nice. I was the one who once used wine's dbghelp together with stacktrace. Nice to see this lib!
[13/01/2013 at 00:40:27]
This looks useful, however, can't get it to build on windows.
Python 2.7
C:\edd-dbg-1abb9939664c\edd-dbg-1abb9939664c>python doozer.py make.py variant=msvc.cfg
-> unpacking doozerlib to c:\users\admin\appdata\local\temp\doozerlib-a80266ccf0f382bce4564fd51e4aa0
03143722ca.zip
-> using default of '5' for 'jobs' (the number of jobs that should be processed concurrently)
-> using default of 'C:\Program Files (x86)\Microsoft Visual Studio 10.0' for 'msvc.vsroot' (Visual
Studio installation directory)
-> using default of 'C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A' for 'msvc.sdkroot' (path t
o the Windows/Platform SDK)
-> using 'C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat' to augment build
environment
-> using default of '0x05010000' for 'win.ntddi_version' (the value of the NTDDI_VERSION macro, dete
rmining the minimum target OS)
-> loading subproject 'make.py'
-> using default of 'False' for 'dbg.optimize_out' (True if the library shouldn't be built e.g. for
release builds where asserts are dummy macros)
-> using default of 'None' for 'dbg.dbghelp_dll_path' (Location of a recent dbghelp.dll to be hardco
ded (optional))
-> loading subproject 'C:\edd-dbg-1abb9939664c\edd-fungo-9518b2e0588c\make.py'
-> ERROR! recursive subproject inclusion:
C:\edd-dbg-1abb9939664c\edd-dbg-1abb9939664c\make.py > C:\edd-dbg-1abb9939664c\edd-fungo-9518b2e05
88c\make.py > C:\edd-dbg-1abb9939664c\edd-dbg-1abb9939664c\make.py
That said, does this only work with try/catch blocks?
Seems it would be much more useful if SetUnhandledExceptionFilter() is used?
[17/02/2013 at 00:40:18]
Hi Steven,
Sorry for not replying sooner. Does the circular inclusion mentioned in the final line indicate an actual problem?
The error seems to imply that the make.py for fungo is trying to load dbg as a subproject. Have you modified fungo's make.py? The canonical version doesn't depend on dbg.
If you're still having problems, please feel free to email me a zip of your setup, or file a bug on bitbucket.
[09/03/2013 at 09:56:06]
Just a note for anybody else having similar trouble to Steven, the build instructions on the wiki have been clarified to point out that test-o-matic is a required dependency when building with doozer.
[06/04/2013 at 19:30:38]
Hi Mr Edd,
is there a way to show the stacktrace of an unhandled exception? (captured with SetUnhandledExceptionFilter).
I can only get something like this:
UnhandledExceptionFilter
RtlCreateUserThread
RtlInitializeExceptionChain
Thanks for your libs!
[21/05/2013 at 00:28:26]
Hi Carlos,
Sorry for the dreadfully late reply.
It would be possible with some further modifications to the library, but not as it stands.
If you still need this, please feel free to submit a feature request on the bug tracker. I can't make any promises as to when I'd get around to adding the feature, but it would certainly serve as a reminder.
All original content copyright© Edd Dawson.
Any opinions expressed by Edd are his own and are not necessarily shared by his employer. Or by anyone else, in fact.
All source code appearing on this website that was written by Edd Dawson is made available under the terms of the Boost software license version 1.0 unless otherwise stated or implied by the license associated with the work from which the code is derived.

Steve
[10/12/2012 at 17:29:55]
No build instruction is there.
$python3 ./make.py
Traceback (most recent call last):
File "./make.py", line 6, in <module>
project('dbg')
NameError: name 'project' is not defined
How can I build it?