1 Backward-cpp [![badge](https://img.shields.io/badge/conan.io-backward%2F1.3.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](http://www.conan.io/source/backward/1.3.0/Manu343726/testing) [![Build Status](https://travis-ci.org/bombela/backward-cpp.svg?branch=master)](https://travis-ci.org/bombela/backward-cpp)
4 Backward is a beautiful stack trace pretty printer for C++.
6 If you are bored to see this:
8 ![default trace](doc/rude.png)
10 Backward will spice it up for you:
12 ![pretty stackstrace](doc/pretty.png)
14 There is not much to say. Of course it will be able to display the code
15 snippets only if the source files are accessible (else see trace #4 in the
18 All "Source" lines and code snippet prefixed by a pipe "|" are frames inline
20 You can see that for the trace #1 in the example, the function
21 `you_shall_not_pass()` was inlined in the function `...read2::do_test()` by the
26 #### Install backward.hpp
28 Backward is a header only library. So installing Backward is easy, simply drop
29 a copy of `backward.hpp` along with your other source files in your C++ project.
30 You can also use a git submodule or really any other way that best fits your
31 environment, as long as you can include `backward.hpp`.
33 #### Install backward.cpp
35 If you want Backward to automatically print a stack trace on most common fatal
36 errors (segfault, abort, un-handled exception...), simply add a copy of
37 `backward.cpp` to your project, and don't forget to tell your build system.
39 The code in `backward.cpp` is trivial anyway, you can simply copy what it's
40 doing at your convenience.
42 ## Configuration & Dependencies
44 ### Integration with CMake
46 If you are using CMake and want to use its configuration abilities to save
47 you the trouble, you can easily integrate Backward, depending on how you obtained
50 #### As a subdirectory:
52 In this case you have a subdirectory containing the whole repository of Backward
53 (eg.: using git-submodules), in this case you can do:
56 add_subdirectory(/path/to/backward-cpp)
58 # This will add backward.cpp to your target
59 add_executable(mytarget mysource.cpp ${BACKWARD_ENABLE})
61 # This will add libraries, definitions and include directories needed by backward
62 # by setting each property on the target.
63 add_backward(mytarget)
66 #### Modifying CMAKE_MODULE_PATH
68 In this case you can have Backward installed as a subdirectory:
71 list(APPEND CMAKE_MODULE_PATH /path/to/backward-cpp)
72 find_package(Backward)
74 # This will add libraries, definitions and include directories needed by backward
75 # through an IMPORTED target.
76 target_link_libraries(mytarget PUBLIC Backward::Backward)
79 Notice that this is equivalent to using the the approach that uses `add_subdirectory()`,
80 however it uses cmake's [imported target](https://cmake.org/Wiki/CMake/Tutorials/Exporting_and_Importing_Targets) mechanism.
82 #### Installation through a regular package manager
84 In this case you have obtained Backward through a package manager.
86 Packages currently available:
87 - [conda-forge](https://anaconda.org/conda-forge/backward-cpp)
90 find_package(Backward)
92 # This will add libraries, definitions and include directories needed by backward
93 # through an IMPORTED target.
94 target_link_libraries(mytarget PUBLIC Backward::Backward)
97 ### Compile with debug info
99 You need to compile your project with generation of debug symbols enabled,
100 usually `-g` with clang++ and g++.
102 Note that you can use `-g` with any level of optimization, with modern debug
103 information encoding like DWARF, it only takes space in the binary (it's not
104 loaded in memory until your debugger or Backward makes use of it, don't worry),
105 and it doesn't impact the code generation (at least on GNU/Linux x86\_64 for
108 If you are missing debug information, the stack trace will lack details about
111 ### Libraries to read the debug info
113 Backward support pretty printed stack traces on GNU/Linux only, it will compile
114 fine under other platforms but will not do anything. **Pull requests are
117 Also, by default you will get a really basic stack trace, based on the
118 `backtrace_symbols` API:
120 ![default trace](doc/nice.png)
122 You will need to install some dependencies to get the ultimate stack trace. Two
123 libraries are currently supported, the only difference is which one is the
124 easiest for you to install, so pick your poison:
126 #### libbfd from the [GNU/binutils](http://www.gnu.org/software/binutils/)
128 apt-get install binutils-dev (or equivalent)
130 And do not forget to link with the lib: `g++/clang++ -lbfd -ldl ...`
132 This library requires dynamic loading. Which is provided by the library `dl`.
133 Hence why we also link with `-ldl`.
135 Then define the following before every inclusion of `backward.hpp` (don't
136 forget to update `backward.cpp` as well):
138 #define BACKWARD_HAS_BFD 1
140 #### libdw from the [elfutils](https://fedorahosted.org/elfutils/)
142 apt-get install libdw-dev (or equivalent)
144 And do not forget to link with the lib and inform Backward to use it:
146 #define BACKWARD_HAS_DW 1
148 Of course you can simply add the define (`-DBACKWARD_HAS_...=1`) and the
149 linkage details in your build system and even auto-detect which library is
150 installed, it's up to you.
152 #### [libdwarf](https://sourceforge.net/projects/libdwarf/) and [libelf](http://www.mr511.de/software/english.html)
154 apt-get install libdwarf-dev (or equivalent)
156 And do not forget to link with the lib and inform Backward to use it:
158 #define BACKWARD_HAS_DWARF 1
160 There are several alternative implementations of libdwarf and libelf that
161 are API compatible so it's possible, although it hasn't been tested, to
162 replace the ones used when developing backward (in bold, below):
164 * **_libelf_** by [Michael "Tired" Riepe](http://www.mr511.de/software/english.html)
165 * **_libdwarf_** by [David Anderson](https://www.prevanders.net/dwarf.html)
166 * libelf from [elfutils](https://fedorahosted.org/elfutils/)
167 * libelf and libdwarf from FreeBSD's [ELF Tool Chain](https://sourceforge.net/p/elftoolchain/wiki/Home/) project
170 Of course you can simply add the define (`-DBACKWARD_HAS_...=1`) and the
171 linkage details in your build system and even auto-detect which library is
172 installed, it's up to you.
174 That's it, you are all set, you should be getting nice stack traces like the
175 one at the beginning of this document.
179 If you don't want to limit yourself to the defaults offered by `backward.cpp`,
180 and you want to take some random stack traces for whatever reason and pretty
181 print them the way you love or you decide to send them all to your buddies over
182 the Internet, you will appreciate the simplicity of Backward's API.
186 The StackTrace class lets you take a "snapshot" of the current stack.
187 You can use it like this:
190 using namespace backward;
191 StackTrace st; st.load_here(32);
192 Printer p; p.print(st);
195 The public methods are:
198 class StackTrace { public:
199 // Take a snapshot of the current stack, with at most "trace_cnt_max"
200 // traces in it. The first trace is the most recent (ie the current
201 // frame). You can also provide a trace address to load_from() assuming
202 // the address is a valid stack frame (useful for signal handling traces).
203 // Both function return size().
204 size_t load_here(size_t trace_cnt_max)
205 size_t load_from(void* address, size_t trace_cnt_max)
207 // The number of traces loaded. This can be less than "trace_cnt_max".
210 // A unique id for the thread in which the trace was taken. The value
211 // 0 means the stack trace comes from the main thread.
212 size_t thread_id() const
214 // Retrieve a trace by index. 0 is the most recent trace, size()-1 is
216 Trace operator[](size_t trace_idx)
222 The `TraceResolver` does the heavy lifting, and intends to transform a simple
223 `Trace` from its address into a fully detailed `ResolvedTrace` with the
224 filename of the source, line numbers, inlined functions and so on.
226 You can use it like this:
229 using namespace backward;
230 StackTrace st; st.load_here(32);
232 TraceResolver tr; tr.load_stacktrace(st);
233 for (size_t i = 0; i < st.size(); ++i) {
234 ResolvedTrace trace = tr.resolve(st[i]);
235 std::cout << "#" << i
236 << " " << trace.object_filename
237 << " " << trace.object_function
238 << " [" << trace.addr << "]"
243 The public methods are:
246 class TraceResolver { public:
247 // Pre-load whatever is necessary from the stack trace.
249 void load_stacktrace(ST&)
251 // Resolve a trace. It takes a ResolvedTrace, because a `Trace` is
252 // implicitly convertible to it.
253 ResolvedTrace resolve(ResolvedTrace t)
259 The SnippetFactory is a simple helper class to automatically load and cache
260 source files in order to extract code snippets.
263 class SnippetFactory { public:
264 // A snippet is a list of line numbers and line contents.
265 typedef std::vector<std::pair<size_t, std::string> > lines_t;
267 // Return a snippet starting at line_start with up to context_size lines.
268 lines_t get_snippet(const std::string& filename,
269 size_t line_start, size_t context_size)
271 // Return a combined snippet from two different locations and combine them.
272 // context_size / 2 lines will be extracted from each location.
273 lines_t get_combined_snippet(
274 const std::string& filename_a, size_t line_a,
275 const std::string& filename_b, size_t line_b,
278 // Tries to return a unified snippet if the two locations from the same
279 // file are close enough to fit inside one context_size, else returns
280 // the equivalent of get_combined_snippet().
281 lines_t get_coalesced_snippet(const std::string& filename,
282 size_t line_a, size_t line_b, size_t context_size)
287 A simpler way to pretty print a stack trace to the terminal. It will
288 automatically resolve the traces for you:
291 using namespace backward;
292 StackTrace st; st.load_here(32);
295 p.color_mode = ColorMode::always;
300 You can set a few options:
303 class Printer { public:
304 // Print a little snippet of code if possible.
307 // Colorize the trace
308 // - ColorMode::automatic: Activate colors if possible. For example, when using a TTY on linux.
309 // - ColorMode::always: Always use colors.
310 // - ColorMode::never: Never use colors.
311 bool color_mode = ColorMode::automatic;
313 // Add the addresses of every source location to the trace.
314 bool address = false;
316 // Even if there is a source location, also prints the object
317 // from where the trace came from.
320 // Resolve and print a stack trace to the given C FILE* object.
321 // On linux, if the FILE* object is attached to a TTY,
322 // color will be used if color_mode is set to automatic.
323 template <typename StackTrace>
324 FILE* print(StackTrace& st, FILE* fp = stderr);
326 // Resolve and print a stack trace to the given std::ostream object.
327 // Color will only be used if color_mode is set to always.
328 template <typename ST>
329 std::ostream& print(ST& st, std::ostream& os);
335 A simple helper class that registers for you the most common signals and other
336 callbacks to segfault, hardware exception, un-handled exception etc.
338 `backward.cpp` simply uses it like that:
341 backward::SignalHandling sh;
344 Creating the object registers all the different signals and hooks. Destroying
345 this object doesn't do anything. It exposes only one method:
348 bool loaded() const // true if loaded with success
353 To keep the memory footprint of a loaded `StackTrace` on the low-side, there a
354 hierarchy of trace object, from a minimal `Trace `to a `ResolvedTrace`.
360 void* addr; // address of the trace
361 size_t idx; // its index (0 == most recent)
367 A `ResolvedTrace` should contains a maximum of details about the location of
368 the trace in the source code. Note that not all fields might be set.
371 struct ResolvedTrace: public Trace {
374 std::string function;
375 std::string filename;
380 // In which binary object this trace is located.
381 std::string object_filename;
383 // The function in the object that contains the trace. This is not the same
384 // as source.function which can be an function inlined in object_function.
385 std::string object_function;
387 // The source location of this trace. It is possible for filename to be
388 // empty and for line/col to be invalid (value 0) if this information
389 // couldn't be deduced, for example if there is no debug information in the
393 // An optional list of "inliners". All of these sources locations where
394 // inlined in the source location of the trace (the attribute right above).
395 // This is especially useful when you compile with optimizations turned on.
396 typedef std::vector<SourceLoc> source_locs_t;
397 source_locs_t inliners;
401 ## Contact and copyright
403 François-Xavier Bourlet <bombela@gmail.com>
405 Copyright 2013-2017 Google Inc. All Rights Reserved.
410 Although this project is owned by Google Inc. this is not a Google supported or