2012-03-27 23:13:14 +00:00
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2018-12-28 15:30:48 +00:00
<!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.
2012-03-27 23:13:14 +00:00
Support
2014-09-21 17:33:12 +00:00
< / 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 >
2012-03-27 23:13:14 +00:00
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:
2014-09-21 17:33:12 +00:00
< / p > < div class = "orderedlist" > < ol class = "orderedlist" type = "1" > < li class = "listitem" > < p >
2012-03-27 23:13:14 +00:00
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 (void);
extern "C or C++" void f2 (void);
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.
2014-09-21 17:33:12 +00:00
< / 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 >
2012-03-27 23:13:14 +00:00
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 > < 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 stderr. If the exception is derived from
< code class = "classname" > 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 abort.
< / 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)
2015-08-28 15:33:40 +00:00
throw argument_error("argc is greater than 5!");
2012-03-27 23:13:14 +00:00
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 comes from the call to
< code class = "function" > abort()< / code > , of course.
< / p > < p >
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
stderr. If your application closes stderr or redirects it to an
inappropriate location,
< code class = "function" > __verbose_terminate_handler< / code > will behave in
an unspecified manner.
2014-09-21 17:33:12 +00:00
< / 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.
2012-03-27 23:13:14 +00:00
Diagnostics
2014-09-21 17:33:12 +00:00
< / td > < / tr > < / table > < / div > < / body > < / html >