C++ exceptions with stack traces

  1. Introduction : In this post,  I will share a simple single header file “pretty_exception.h”. Basically it is for throwing exception messages with much more information. This one will have file, file line number and the function/method that is throwing the exception. Further more it also adds callstack information, can have colored console outputs, traces for syslog/Dbgview and even comes with a simple message box ( Windows only ). Below you can see outputs from Linux and Windows consoles :

And Windows console output :

If you enable tracing,  you can see exception trace in syslog on Linux:

[root@localhost ~]# tail -f /var/log/messages
Jul 24 22:36:58 localhost dbus[633]: [system] Successfully activated service ‘org.freedesktop.hostname1’
Jul 24 22:36:58 localhost systemd: Started Hostname Service.
Jul 24 22:40:01 localhost systemd: Starting Session 3 of user root.
Jul 24 22:40:01 localhost systemd: Started Session 3 of user root.
Jul 24 22:40:32 localhost chronyd[636]: Selected source 94.125.132.7
Jul 24 22:45:49 localhost systemd: Starting Cleanup of Temporary Directories…
Jul 24 22:45:50 localhost systemd: Started Cleanup of Temporary Directories.
Jul 24 22:48:38 localhost systemd: Starting Session 4 of user root.
Jul 24 22:48:38 localhost systemd: Started Session 4 of user root.
Jul 24 22:48:38 localhost systemd-logind: New session 4 of user root.
Jul 24 22:48:44 localhost slog[4589]: Exception type : std::runtime_error

Message : AAA

File : main.cppLine : 5

Callstack :

5 : ./pretty() [0x4021a4]
4 : ./pretty() [0x40197a]
3 : ./pretty() [0x401bad]
2 : /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f6ca71bdaf5]
1 : ./pretty() [0x4016b9]

And you can use Microsoft`s Dbgview utility to see the exception trace on Windows :

 

Additionally on Windows, you can also have message boxes if you enable it in the header file :

2. Implementation notes :

  • File number , line number, function name : The code uses __LINE__ , __FILE__ macros. As for the function name , initially intended to use C99 __func__ however currently not using it as the callstack information already provides it.

 

 

 

  • Macro expansion : In order to have __FILE__ and __LINE__ macros , I had to define throw functionality as macros as __FILE__ and __LINE__ macros should be copied to the place of the caller by the preprocessor. However I needed to concatenate these predefined macros with my macros therefore I had to use the technique described perfectly on this page : http://stackoverflow.com/questions/19343205/c-concatenating-file-and-line-macros

 

 

  • Supporting string literals & std::string : In order to support both string literals and std::string as input message , we define a template convertToStdString function and an const char* overload for it :

inline std::string convertToStdString(const char* str){ return std::string(str);}


template <typename T>T convertToStdString(T const& t){ return t;}

 

3. Source code and usage : Its target platforms are Linux with GCC ( tested on CentOS7 with GCC4.8 ) and Windows with MSVC ( tested with MSVC2013 on Windows8) . The code initially check predefined macros to see if it is a supported system. For other platforms & compilers, the changes should be straightforward. Currently you can throw 4 different std::exception types : std::runtime_error, std::invalid_arg and std::length_error and std::logic_error. In order to use just include its header file and call one of the throw macros :

#include “pretty_exception.h”

void foo()
{
THROW_PRETTY_RUNTIME_EXCEPTION(“AAA”)
}

And finally here is the source code :

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s