Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Backward-cpp – A stack trace pretty-printer for C++ (github.com/bombela)
90 points by negrit on March 15, 2013 | hide | past | favorite | 28 comments


GCC 4.8 comes with a built-in address sanitizer that prints nice stack traces for most memory-related errors.

Basically you just add "-fsanitize=address" and link appropriately:

     gcc -pthread  -fno-omit-frame-pointer -g -fsanitize=address badass.c -lasan -ldl

     ./a.out
      ==22420== ERROR: AddressSanitizer crashed on address 0x0000200000703c18 at pc 0x401947
      READ of size 1 at 0x0000200000703c18; shadow: 0x0000100000381e0c; mem: 0x0000000001c0f065 thread: 0x787d4720
          #0 0x401947 main use-after-free.c:5
          #1 0x7ff87792cc4d __libc_start_main ??:0
          #2 0x401839 _start ??:0
      0x0000000001c0f065 is located 5 bytes inside of 80-byte region [0x0000000001c0f060,0x0000000001c0f0b0)
      freed by thread 0x787d4720 here:
          #0 0x404b9b free asan_rtl.cc:1203
          #1 0x40191b main use-after-free.c:5
          #2 0x7ff87792cc4d __libc_start_main ??:0
          #3 0x401839 _start ??:0
      previously allocated by thread 0x787d4720 here:
          #0 0x405c27 malloc asan_rtl.cc:1196
          #1 0x401910 main use-after-free.c:3
          #2 0x7ff87792cc4d __libc_start_main ??:0
          #3 0x401839 _start ??:0

See the changelog [1] as well as the library [2] itself. Of course, the OP's project is certainly cool too.

[1]: http://gcc.gnu.org/gcc-4.8/changes.html

[2]: https://code.google.com/p/address-sanitizer/wiki/AddressSani...


Author of the code here. Yes, this is cool, but it instruments your code "This tool is very fast. The average slowdown of the instrumented program is ~2x (see PerformanceNumbers).". backward-cpp doesn't change the generated code in any way. This is only using the debug informations. There is no performance impact, the binary code stays the same.


Wow, that is as perfect as it can get :)


What I need, moreso than this, is a tool for parsing really long and winding multi-screen error messages involving templates (screw up a std::map key or value? At least 100 characters in the error message just to describe it. Add an additional 50 if you try to use string [basic_string ...])


Which compiler are you using? Clang is much better at dumping template related error messages and recent versions of gcc are getting better.


gcc 4.2, although at this stage I'm so used to reading the error messages that I just gloss over most of the verbiage


For that I use gccfilter which does an awesome job at parsing the hell out of compile errors.

http://www.mixtion.org/gccfilter/

In our project we use gccfilter with the options -c and -p which are colorize and remove path but it supports as well -a for removing the template arguments. Give it a try it will definitely help your.


Played with it, helps with some template issues involving STL, but doesn't seem to interpret CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_p...) issues correctly. Nonetheless, very cool.


That's cool! Eases the workflow when developing cpp, no need to fire up gdb to make sense of 'Segmentation fault'.

Reminds me of tiny-cc's default output for segfaults.


There is no need to fire up gdb in the example case on the backward-cpp Github page because it's a trivial example (dereferencing an obviously invalid pointer), but to say it eliminates the need for gdb to debug segfaults in general is a bit of an overstatement.


I get errors when I try to compile it on my system.

  $ g++ -v
  gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)

  $ g++ -c backward.cpp
  In file included from backward.cpp:26:
  backward.hpp: In member function ‘_Unwind_Reason_Code backward::details::Unwinder<F>::backtrace(_Unwind_Context*)’:
  backward.hpp:595: error: there are no arguments to ‘_Unwind_GetIPInfo’ that depend on a template parameter, so a declaration of ‘_Unwind_GetIPInfo’ must be available
  backward.hpp:595: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
  backward.hpp: In member function ‘_Unwind_Reason_Code backward::details::Unwinder<F>::backtrace(_Unwind_Context*) [with F = backward::StackTraceImpl<backward::system_tag::linux_tag>::callback]’:
  backward.hpp:587:   instantiated from ‘static _Unwind_Reason_Code backward::details::Unwinder<F>::backtrace_trampoline(_Unwind_Context*, void*) [with F = backward::StackTraceImpl<backward::system_tag::linux_tag>::callback]’
  backward.hpp:576:   instantiated from ‘size_t backward::details::Unwinder<F>::operator()(F&, size_t) [with F = backward::StackTraceImpl<backward::system_tag::linux_tag>::callback]’
  backward.hpp:612:   instantiated from ‘size_t backward::details::unwind(F, size_t) [with F = backward::StackTraceImpl<backward::system_tag::linux_tag>::callback]’
  backward.hpp:628:   instantiated from here
  backward.hpp:595: error: ‘_Unwind_GetIPInfo’ was not declared in this scope


Hey, I am not the OP, but the author of the code. So it seems that the function is not always declared in some header, while it exists in libgcc. Can you add an issue on github? Meanwhile, you can set the #define BACKWARD_HAS_BACKTRACE=1 which will disable the use of "unwind". You will get slightly less accurate stack trace (especially on CPU exception and other signals), but it should work ok until this bug is fixed.


Hi there, I've also run into this issue. I've opened an issue on your github: https://github.com/bombela/backward-cpp/issues/2

Thanks again for the really useful open source contribution! I will be integrating this with my C++ projects.


This actually fills a need for me, I've been toying with writing one for a while but always find something that needs my attention more.


Ok, this does pretty backtraces.

I was hoping for an actual 'reverse cpp': a tool that took preprocessed C source code and undoes macro expansions. I mean, it should read some C source and some header files, and use the macro definitions found in the header files to try and shorten the source code.


Why is this useful?


Does this also work with frame pointers omitted?


It does, because it uses the debug information generated by the compiler. both clang and gcc produce a good quality DWARF (http://www.dwarfstd.org/), which contains everything needed to unwind the stack. In Bacward-cpp I do use the unwinder provided by libgcc, which is in fact extracting all the information from DWARF. This is as accurate as GDB can be, it uses the same debug information.


It looks like it should, since it has an unwinder


> Backward support pretty printed stack trace on GNU/Linux only, it will compile fine under other platforms but will not do anything.

:(


Google has a similar library that supports Windows:

https://code.google.com/p/google-breakpad/wiki/StackWalking


You can probably make it work on OSX too - the toolchain is very similar.


Patches accepted?


Actually, says 'Pull requests are welcome :)'


so this is a colored version of gdb's `bt` command? am I missing something?


...without running gdb?

I think this eases the workflow if you're not always running the application from within gdb.

Btw, does gdb expand inline calls in the backtrace?


yes, gdb can expand inline calls in a backtrace.


Nice.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: