1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Termination</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><meta name="keywords" content="ISO C++, library" /><meta name="keywords" content="ISO C++, runtime, library" /><link rel="home" href="../index.html" title="The GNU C++ Library" /><link rel="up" href="support.html" title="Chapter 4. Support" /><link rel="prev" href="dynamic_memory.html" title="Dynamic Memory" /><link rel="next" href="diagnostics.html" title="Chapter 5. Diagnostics" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Termination</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="dynamic_memory.html">Prev</a> </td><th width="60%" align="center">Chapter 4.
Support
</th><td width="20%" align="right"> <a accesskey="n" href="diagnostics.html">Next</a></td></tr></table><hr /></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="std.support.termination"></a>Termination</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="support.termination.handlers"></a>Termination Handlers</h3></div></div></div><p>
Not many changes here to
<code class="filename"><cstdlib></code>.
You should note that the
<code class="function">abort()</code> function does not call the
destructors of automatic nor static objects, so if you're
depending on those to do cleanup, it isn't going to happen.
(The functions registered with <code class="function">atexit()</code>
don't get called either, so you can forget about that
possibility, too.)
</p><p>
The good old <code class="function">exit()</code> function can be a bit
funky, too, until you look closer. Basically, three points to
remember are:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
Static objects are destroyed in reverse order of their creation.
</p></li><li class="listitem"><p>
Functions registered with <code class="function">atexit()</code> are called in
reverse order of registration, once per registration call.
(This isn't actually new.)
</p></li><li class="listitem"><p>
The previous two actions are <span class="quote">“<span class="quote">interleaved,</span>”</span> that is,
given this pseudocode:
</p><pre class="programlisting">
extern "C or C++" void f1 ();
extern "C or C++" void f2 ();
static Thing obj1;
atexit(f1);
static Thing obj2;
atexit(f2);
</pre><p>
then at a call of <code class="function">exit()</code>,
<code class="varname">f2</code> will be called, then
<code class="varname">obj2</code> will be destroyed, then
<code class="varname">f1</code> will be called, and finally
<code class="varname">obj1</code> will be destroyed. If
<code class="varname">f1</code> or <code class="varname">f2</code> allow an
exception to propagate out of them, Bad Things happen.
</p></li></ol></div><p>
Note also that <code class="function">atexit()</code> is only required to store 32
functions, and the compiler/library might already be using some of
those slots. If you think you may run out, we recommend using
the <code class="function">xatexit</code>/<code class="function">xexit</code> combination
from <code class="literal">libiberty</code>, which has no such limit.
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="support.termination.verbose"></a>Verbose Terminate Handler</h3></div></div></div><p>
If you are having difficulty with uncaught exceptions and want a
little bit of help debugging the causes of the core dumps, you can
make use of a GNU extension, the verbose terminate handler.
</p><p>
The verbose terminate handler is only available for hosted environments
(see <a class="xref" href="configure.html" title="Configure">Configuring</a>) and will be used
by default unless the library is built with
<code class="option">--disable-libstdcxx-verbose</code>
or with exceptions disabled.
If you need to enable it explicitly you can do so by calling the
<code class="function">std::set_terminate</code> function.
</p><pre class="programlisting">
#include <exception>
int main()
{
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
...
throw <em class="replaceable"><code>anything</code></em>;
}
</pre><p>
The <code class="function">__verbose_terminate_handler</code> function
obtains the name of the current exception, attempts to demangle
it, and prints it to <code class="literal">stderr</code>.
If the exception is derived from
<code class="classname">std::exception</code> then the output from
<code class="function">what()</code> will be included.
</p><p>
Any replacement termination function is required to kill the
program without returning; this one calls <code class="function">std::abort</code>.
</p><p>
For example:
</p><pre class="programlisting">
#include <exception>
#include <stdexcept>
struct argument_error : public std::runtime_error
{
argument_error(const std::string& s): std::runtime_error(s) { }
};
int main(int argc)
{
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
if (argc > 5)
throw argument_error("argc is greater than 5!");
else
throw argc;
}
</pre><p>
With the verbose terminate handler active, this gives:
</p><pre class="screen">
<code class="computeroutput">
% ./a.out
terminate called after throwing a `int'
Aborted
% ./a.out f f f f f f f f f f f
terminate called after throwing an instance of `argument_error'
what(): argc is greater than 5!
Aborted
</code>
</pre><p>
The 'Aborted' line is printed by the shell after the process exits
by calling <code class="function">abort()</code>.
</p><p>
As this is the default termination handler, nothing need be done to
use it. To go back to the previous <span class="quote">“<span class="quote">silent death</span>”</span>
method, simply include
<code class="filename"><exception></code> and
<code class="filename"><cstdlib></code>, and call
</p><pre class="programlisting">
std::set_terminate(std::abort);
</pre><p>
After this, all calls to <code class="function">terminate</code> will use
<code class="function">abort</code> as the terminate handler.
</p><p>
Note: the verbose terminate handler will attempt to write to
<code class="literal">stderr</code>. If your application closes
<code class="literal">stderr</code> or redirects it to an inappropriate location,
<code class="function">__verbose_terminate_handler</code> will behave in
an unspecified manner.
</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dynamic_memory.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="support.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="diagnostics.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Dynamic Memory </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 5.
Diagnostics
</td></tr></table></div></body></html>
|