Files
stacktrace/boost_stacktrace/getting_started.html
Antony Polukhin c65ec7294d Docs regenerated
2016-11-26 23:25:15 +03:00

412 lines
51 KiB
HTML

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Getting Started</title>
<link rel="stylesheet" href="http://www.boost.org/doc/libs/1_61_0/doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Stacktrace 1.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Stacktrace 1.0">
<link rel="prev" href="../index.html" title="Chapter&#160;1.&#160;Boost.Stacktrace 1.0">
<link rel="next" href="build_macros_and_backends.html" title="Build, Macros and Backends">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="http://www.boost.org/doc/libs/1_61_0/boost.png"></td>
<td align="center"><a href="http://www.boost.org/doc/libs/1_61_0/index.html">Home</a></td>
<td align="center"><a href="http://www.boost.org/doc/libs/1_61_0/libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="http://www.boost.org/doc/libs/1_61_0/more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="http://www.boost.org/doc/libs/1_61_0/doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="http://www.boost.org/doc/libs/1_61_0/doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="http://www.boost.org/doc/libs/1_61_0/doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="build_macros_and_backends.html"><img src="http://www.boost.org/doc/libs/1_61_0/doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_stacktrace.getting_started"></a><a class="link" href="getting_started.html" title="Getting Started">Getting Started</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="getting_started.html#boost_stacktrace.getting_started.how_to_print_current_call_stack">How
to print current call stack</a></span></dt>
<dt><span class="section"><a href="getting_started.html#boost_stacktrace.getting_started.handle_terminates_and_segmentati">Handle
Terminates and Segmentation Faults</a></span></dt>
<dt><span class="section"><a href="getting_started.html#boost_stacktrace.getting_started.better_asserts">Better
asserts</a></span></dt>
<dt><span class="section"><a href="getting_started.html#boost_stacktrace.getting_started.exceptions_with_stacktrace">Exceptions
with Stacktrace</a></span></dt>
<dt><span class="section"><a href="getting_started.html#boost_stacktrace.getting_started.enabling_and_disabling_stacktrac">Enabling
and Disabling stacktraces</a></span></dt>
<dt><span class="section"><a href="getting_started.html#boost_stacktrace.getting_started.saving_stacktraces_by_specified_">Saving
stacktraces by specified format</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stacktrace.getting_started.how_to_print_current_call_stack"></a><a class="link" href="getting_started.html#boost_stacktrace.getting_started.how_to_print_current_call_stack" title="How to print current call stack">How
to print current call stack</a>
</h3></div></div></div>
<p>
<code class="computeroutput"><a class="link" href="../boost/stacktrace/stacktrace.html" title="Class stacktrace">boost::stacktrace::stacktrace</a></code>
contains methods for working with call-stack/backtraces/stacktraces. Here's
a small example:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stacktrace</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">// ... somewere inside the `bar(int)` function that is called recursively:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">();</span>
</pre>
<p>
In that example:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">::</span></code>
is the namespace that has all the classes and functions to work with
stacktraces
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/stacktrace/stacktrace.html" title="Class stacktrace">stacktrace()</a></code>
is the default constructor call; constructor stores the current function
call sequence inside the stacktrace class.
</li>
</ul></div>
<p>
Code from above will output something like this:
</p>
<pre class="programlisting"><span class="number">0</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">1</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">2</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">3</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">4</span><span class="special">#</span> <span class="identifier">main</span>
<span class="number">5</span><span class="special">#</span> <span class="identifier">__libc_start_main</span>
<span class="number">6</span><span class="special">#</span> <span class="identifier">_start</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stacktrace.getting_started.handle_terminates_and_segmentati"></a><a class="link" href="getting_started.html#boost_stacktrace.getting_started.handle_terminates_and_segmentati" title="Handle Terminates and Segmentation Faults">Handle
Terminates and Segmentation Faults</a>
</h3></div></div></div>
<p>
Segmentation Faults and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code>
calls sometimes happen in programs. Programmers usually wish to get as much
information as possible on such incidents, so having a stacktrace will significantly
improve debugging and fixing.
</p>
<p>
To deal with Segmentation Faults and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code>
calls we would need to write handlers:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">exception</span><span class="special">&gt;</span> <span class="comment">// std::set_terminate, std::abort</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">signal</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span> <span class="comment">// ::signal</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stacktrace</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span> <span class="comment">// std::cerr</span>
<span class="keyword">void</span> <span class="identifier">my_terminate_handler</span><span class="special">()</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"Terminate called:\n"</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">abort</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">my_signal_handler</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">signum</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">::</span><span class="identifier">stacktrace</span> <span class="identifier">bt</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">bt</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"Signal "</span> <span class="special">&lt;&lt;</span> <span class="identifier">signum</span> <span class="special">&lt;&lt;</span> <span class="string">", backtrace:\n"</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span> <span class="comment">// <sup>[<a name="boost_stacktrace.getting_started.handle_terminates_and_segmentati.f0" href="#ftn.boost_stacktrace.getting_started.handle_terminates_and_segmentati.f0" class="footnote">1</a>]</sup></span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">abort</span><span class="special">();</span>
<span class="special">}</span>
</pre>
<p>
After that we can set them as a default handlers and get some more information
on incidents:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">set_terminate</span><span class="special">(&amp;</span><span class="identifier">my_terminate_handler</span><span class="special">);</span>
<span class="special">::</span><span class="identifier">signal</span><span class="special">(</span><span class="identifier">SIGSEGV</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">my_signal_handler</span><span class="special">);</span>
</pre>
<p>
Now we'll get the following output on <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code>
call:
</p>
<pre class="programlisting"><span class="identifier">Terminate</span> <span class="identifier">called</span><span class="special">:</span>
<span class="number">0</span><span class="special">#</span> <span class="identifier">my_terminate_handler</span><span class="special">()</span>
<span class="number">1</span><span class="special">#</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">rethrow_exception</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">__exception_ptr</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">)</span>
<span class="number">2</span><span class="special">#</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span><span class="special">()</span>
<span class="number">3</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">4</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">5</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">6</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">7</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">8</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">9</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">10</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">11</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">12</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">13</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">14</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">15</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">16</span><span class="special">#</span> <span class="identifier">main</span>
<span class="number">17</span><span class="special">#</span> <span class="identifier">__libc_start_main</span>
<span class="number">18</span><span class="special">#</span> <span class="identifier">_start</span>
<span class="number">19</span><span class="special">#</span> <span class="special">??</span>
</pre>
<p>
And the following output on Segmentation Fault:
</p>
<pre class="programlisting"><span class="identifier">Signal</span> <span class="number">11</span><span class="special">,</span> <span class="identifier">backtrace</span><span class="special">:</span>
<span class="number">0</span><span class="special">#</span> <span class="identifier">my_signal_handler</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">1</span><span class="special">#</span> <span class="identifier">killpg</span>
<span class="number">2</span><span class="special">#</span> <span class="special">??</span>
<span class="number">3</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">4</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">5</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">6</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">7</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">8</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">9</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">10</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">11</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">12</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">13</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">14</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">15</span><span class="special">#</span> <span class="identifier">main</span>
<span class="number">16</span><span class="special">#</span> <span class="identifier">__libc_start_main</span>
<span class="number">17</span><span class="special">#</span> <span class="identifier">_start</span>
<span class="number">18</span><span class="special">#</span> <span class="special">??</span>
</pre>
<p>
The output stacktrace may be corrupted by previous actions. But now at least
some basic information is available to work with.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stacktrace.getting_started.better_asserts"></a><a class="link" href="getting_started.html#boost_stacktrace.getting_started.better_asserts" title="Better asserts">Better
asserts</a>
</h3></div></div></div>
<p>
Pretty often assertions provide not enough information to locate the problem.
For example you can see the following message on out-of-range access:
</p>
<pre class="programlisting"><span class="special">../../../</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">:</span><span class="number">123</span><span class="special">:</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">N</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">[](</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">N</span><span class="special">&gt;::</span><span class="identifier">size_type</span><span class="special">)</span> <span class="special">[</span><span class="identifier">with</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">int</span><span class="special">;</span> <span class="keyword">long</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">N</span> <span class="special">=</span> <span class="number">5ul</span><span class="special">]:</span> <span class="identifier">Assertion</span> <span class="char">'(i &lt; N)&amp;&amp;("out of range")'</span> <span class="identifier">failed</span><span class="special">.</span>
<span class="identifier">Aborted</span> <span class="special">(</span><span class="identifier">core</span> <span class="identifier">dumped</span><span class="special">)</span>
</pre>
<p>
That's not enough to locate the problem without debugger. There may be thousand
code lines in real world examples and hundred places where that assertion
could happen. Let's try to improve the assertions, and make them more informative:
</p>
<pre class="programlisting"><span class="comment">// BOOST_ENABLE_ASSERT_DEBUG_HANDLER is defined for the whole project</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">stdexcept</span><span class="special">&gt;</span> <span class="comment">// std::logic_error</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span> <span class="comment">// std::cerr</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stacktrace</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">void</span> <span class="identifier">assertion_failed_msg</span><span class="special">(</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">expr</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">msg</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">file</span><span class="special">,</span> <span class="keyword">long</span> <span class="identifier">line</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"Expression '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span> <span class="special">&lt;&lt;</span> <span class="string">"' is false in function '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">function</span> <span class="special">&lt;&lt;</span> <span class="string">"': "</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">msg</span> <span class="special">?</span> <span class="identifier">msg</span> <span class="special">:</span> <span class="string">"&lt;...&gt;"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">".\n"</span>
<span class="special">&lt;&lt;</span> <span class="string">"Backtrace:\n"</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
<span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">logic_error</span><span class="special">(</span><span class="string">"assertion"</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">assertion_failed</span><span class="special">(</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">expr</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">function</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">file</span><span class="special">,</span> <span class="keyword">long</span> <span class="identifier">line</span><span class="special">)</span> <span class="special">{</span>
<span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">assertion_failed_msg</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="number">0</span> <span class="comment">/*nullptr*/</span><span class="special">,</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">file</span><span class="special">,</span> <span class="identifier">line</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span> <span class="comment">// namespace boost</span>
</pre>
<p>
We've defined the <code class="computeroutput"><span class="identifier">BOOST_ENABLE_ASSERT_DEBUG_HANDLER</span></code>
macro for the whole project. Now all the <code class="computeroutput"><span class="identifier">BOOST_ASSERT</span></code>
and <code class="computeroutput"><span class="identifier">BOOST_ASSERT_MSG</span></code> will
call our functions <code class="computeroutput"><span class="identifier">assertion_failed</span></code>
and <code class="computeroutput"><span class="identifier">assertion_failed_msg</span></code>
in case of failure. In <code class="computeroutput"><span class="identifier">assertion_failed_msg</span></code>
we output information that was provided by the assertion macro and <code class="computeroutput"><a class="link" href="../boost/stacktrace/stacktrace.html" title="Class stacktrace">boost::stacktrace::stacktrace</a></code>:
</p>
<pre class="programlisting"><span class="identifier">Expression</span> <span class="char">'i &lt; N'</span> <span class="identifier">is</span> <span class="keyword">false</span> <span class="identifier">in</span> <span class="identifier">function</span> <span class="char">'T&amp; boost::array&lt;T, N&gt;::operator[](boost::array&lt;T, N&gt;::size_type) [with T = int; long unsigned int N = 5ul]'</span><span class="special">:</span> <span class="identifier">out</span> <span class="identifier">of</span> <span class="identifier">range</span><span class="special">.</span>
<span class="identifier">Backtrace</span><span class="special">:</span>
<span class="number">0</span><span class="special">#</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">assertion_failed_msg</span><span class="special">(</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*,</span> <span class="keyword">long</span><span class="special">)</span>
<span class="number">1</span><span class="special">#</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">5ul</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">[](</span><span class="keyword">unsigned</span> <span class="keyword">long</span><span class="special">)</span>
<span class="number">2</span><span class="special">#</span> <span class="identifier">oops</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">long</span><span class="special">)</span>
<span class="number">3</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">4</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">5</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">6</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">7</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">8</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">9</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">10</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">11</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">12</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">13</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">14</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">15</span><span class="special">#</span> <span class="identifier">main</span>
<span class="number">16</span><span class="special">#</span> <span class="identifier">__libc_start_main</span>
<span class="number">17</span><span class="special">#</span> <span class="identifier">_start</span>
<span class="number">18</span><span class="special">#</span> <span class="special">??</span>
</pre>
<p>
Now we do know the steps that led to the assertion and can find the error
without debugger.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stacktrace.getting_started.exceptions_with_stacktrace"></a><a class="link" href="getting_started.html#boost_stacktrace.getting_started.exceptions_with_stacktrace" title="Exceptions with Stacktrace">Exceptions
with Stacktrace</a>
</h3></div></div></div>
<p>
You can provide more information along with exception by embedding stacktraces
into the exception. For that we will need:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Basic class that holds the stacktrace:
</li></ul></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stacktrace</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">traced</span> <span class="special">{</span>
<span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">::</span><span class="identifier">stacktrace</span> <span class="identifier">trace</span><span class="special">;</span>
<span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">what</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">traced</span><span class="special">(){}</span>
<span class="special">};</span>
</pre>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Helper class for appending class <code class="computeroutput"><span class="identifier">traced</span></code>
to any exception:
</li></ul></div>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Exception</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">with_trace</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">Exception</span><span class="special">,</span> <span class="keyword">public</span> <span class="identifier">traced</span> <span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
<span class="identifier">with_trace</span><span class="special">(</span><span class="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span>
<span class="special">:</span> <span class="identifier">Exception</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Args</span><span class="special">&gt;(</span><span class="identifier">args</span><span class="special">)...)</span>
<span class="special">{}</span>
<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">what</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">Exception</span><span class="special">::</span><span class="identifier">what</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Throw <code class="computeroutput"><span class="identifier">with_trace</span><span class="special">&lt;</span><span class="identifier">Exception</span><span class="special">&gt;</span></code>
instead of just <code class="computeroutput"><span class="identifier">Exception</span></code>:
</li></ul></div>
<pre class="programlisting"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">&gt;=</span> <span class="number">4</span><span class="special">)</span>
<span class="keyword">throw</span> <span class="identifier">with_trace</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">out_of_range</span><span class="special">&gt;(</span><span class="string">"'i' must be less than 4 in oops()"</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">&lt;=</span> <span class="number">0</span><span class="special">)</span>
<span class="keyword">throw</span> <span class="identifier">with_trace</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">logic_error</span><span class="special">&gt;(</span><span class="string">"'i' must not be greater than zero in oops()"</span><span class="special">);</span>
</pre>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Catch exceptions by <code class="computeroutput"><span class="identifier">traced</span></code>:
</li></ul></div>
<pre class="programlisting"><span class="keyword">try</span> <span class="special">{</span>
<span class="identifier">foo</span><span class="special">(</span><span class="number">5</span><span class="special">);</span> <span class="comment">// testing assert handler</span>
<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">traced</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">e</span><span class="special">.</span><span class="identifier">trace</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"Backtrace:\n"</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">trace</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
Code from above will output:
</p>
<pre class="programlisting"><span class="char">'i'</span> <span class="identifier">must</span> <span class="identifier">be</span> <span class="identifier">less</span> <span class="identifier">than</span> <span class="number">4</span> <span class="identifier">in</span> <span class="identifier">oops</span><span class="special">()</span>
<span class="identifier">Backtrace</span><span class="special">:</span>
<span class="number">0</span><span class="special">#</span> <span class="identifier">with_trace</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">out_of_range</span><span class="special">&gt;::</span><span class="identifier">with_trace</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span> <span class="special">(&amp;)</span> <span class="special">[</span><span class="number">34</span><span class="special">]&gt;(</span><span class="keyword">char</span> <span class="keyword">const</span> <span class="special">(&amp;)</span> <span class="special">[</span><span class="number">34</span><span class="special">])</span>
<span class="number">1</span><span class="special">#</span> <span class="identifier">oops</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">long</span><span class="special">)</span>
<span class="number">2</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">3</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">4</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">5</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">6</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">7</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">8</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">9</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">10</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">11</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">12</span><span class="special">#</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">13</span><span class="special">#</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="number">14</span><span class="special">#</span> <span class="identifier">main</span>
<span class="number">15</span><span class="special">#</span> <span class="identifier">__libc_start_main</span>
<span class="number">16</span><span class="special">#</span> <span class="identifier">_start</span>
<span class="number">17</span><span class="special">#</span> <span class="special">??</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stacktrace.getting_started.enabling_and_disabling_stacktrac"></a><a class="link" href="getting_started.html#boost_stacktrace.getting_started.enabling_and_disabling_stacktrac" title="Enabling and Disabling stacktraces">Enabling
and Disabling stacktraces</a>
</h3></div></div></div>
<p>
At some point arises a requirement to easily enable/disable stacktraces for
a whole project. That could be easily achived.
</p>
<p>
Just define <span class="bold"><strong>BOOST_STACKTRACE_LINK</strong></span> for a
whole project. Now you can enable/disable stacktraces by just linking with
different backends:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
link with <code class="computeroutput"><span class="identifier">boost_stacktrace_noop</span></code>
to disable backtracing
</li>
<li class="listitem">
link with other backends to output backtraces
</li>
</ul></div>
<p>
See <a class="link" href="build_macros_and_backends.html" title="Build, Macros and Backends">section "Build,
Macros and Backends"</a> for more info.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stacktrace.getting_started.saving_stacktraces_by_specified_"></a><a class="link" href="getting_started.html#boost_stacktrace.getting_started.saving_stacktraces_by_specified_" title="Saving stacktraces by specified format">Saving
stacktraces by specified format</a>
</h3></div></div></div>
<p>
<code class="computeroutput"><a class="link" href="../boost/stacktrace/stacktrace.html" title="Class stacktrace">boost::stacktrace::stacktrace</a></code>
provides access to individual <code class="computeroutput"><a class="link" href="../boost/stacktrace/frame.html" title="Class frame">frames</a></code>
of the stacktrace, so that you could save stacktrace information in your
own format. Consider the example, that saves only function addresses of each
frame:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stacktrace</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span> <span class="comment">// std::cout</span>
<span class="keyword">namespace</span> <span class="identifier">bs</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">dump_compact</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bs</span><span class="special">::</span><span class="identifier">stacktrace</span><span class="special">&amp;</span> <span class="identifier">st</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">bs</span><span class="special">::</span><span class="identifier">frame</span> <span class="identifier">frame</span><span class="special">:</span> <span class="identifier">st</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">frame</span><span class="special">.</span><span class="identifier">address</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="char">','</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
Code from above will output:
</p>
<pre class="programlisting"><span class="number">0x401a25</span><span class="special">,</span><span class="number">0x401a25</span><span class="special">,</span><span class="number">0x401a25</span><span class="special">,</span><span class="number">0x401a25</span><span class="special">,</span><span class="number">0x401a25</span><span class="special">,</span><span class="number">0x401a25</span><span class="special">,</span><span class="number">0x4019cb</span><span class="special">,</span><span class="number">0x401a7f</span><span class="special">,</span><span class="number">0</span><span class="identifier">x7f9da8a46e50</span><span class="special">,</span><span class="number">0x4013e0</span><span class="special">,</span><span class="number">0</span><span class="special">,</span>
</pre>
</div>
<div class="footnotes">
<br><hr width="100" align="left">
<div class="footnote"><p><sup>[<a name="ftn.boost_stacktrace.getting_started.handle_terminates_and_segmentati.f0" href="#boost_stacktrace.getting_started.handle_terminates_and_segmentati.f0" class="para">1</a>] </sup>Strictly speaking this code is not async-signal-safe, but we have SIGSEGV already it could hardly become worse. <a class="link" href="build_macros_and_backends.html" title="Build, Macros and Backends">Section "Build, Macros and Backends"</a> describes async-signal-safe backends, so if you will use the noop backend code becomes absolutely valid as that backens always returns 0 frames and <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code> will be never called. </p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2016 Antony Polukhin<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="http://www.boost.org/doc/libs/1_61_0/doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="http://www.boost.org/doc/libs/1_61_0/doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="http://www.boost.org/doc/libs/1_61_0/doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="build_macros_and_backends.html"><img src="http://www.boost.org/doc/libs/1_61_0/doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>