1 /* SPDX-License-Identifier: GPL-2.0-only or License-Ref-kk-custom */
2 /*
3  * Copyright (C) 2020 Kernkonzept GmbH.
4  * Author(s): Frank Mehnert <frank.mehnert@kernkonzept.com>
5  *
6  */
7 
8 #include <cstdlib>
9 #include <exception>
10 #include <bits/exception_defines.h>
11 #include <cxxabi.h>
12 #include <cstdio>
13 
14 #include <l4/cxx/exceptions>
15 
16 namespace std { namespace L4 {
17 
18 void terminate_handler();
19 
20 // Verbose terminate handler being aware of the std::L4 exceptions.
terminate_handler()21 void terminate_handler()
22 {
23   static bool terminating;
24   if (terminating)
25     {
26       fputs("terminate called recursively\n", stderr);
27       abort ();
28     }
29   terminating = true;
30 
31   // Make sure there was an exception; terminate is also called for an
32   // attempt to rethrow when there is no suitable exception.
33   type_info *t = __cxxabiv1::__cxa_current_exception_type();
34   if (t)
35     {
36       // Note that "name" is the mangled name.
37       char const *name = t->name();
38         {
39           int status = -1;
40           char *dem = 0;
41 
42           dem = __cxxabiv1::__cxa_demangle(name, 0, 0, &status);
43 
44           fputs("terminate called after throwing an instance of '", stderr);
45           if (status == 0)
46             fputs(dem, stderr);
47           else
48             fputs(name, stderr);
49           fputs("'\n", stderr);
50 
51           if (status == 0)
52             free(dem);
53         }
54 
55       // If the exception is derived from std::exception, we can
56       // give more information.
57       __try { __throw_exception_again; }
58       __catch (::L4::Runtime_error const &e)
59         {
60           char const *s = e.str();
61           char const *es = e.extra_str();
62           fputs("  what: ", stderr);
63           fputs(s, stderr);
64           fputs(": ", stderr);
65           fputs(es, stderr);
66           fputs("\n", stderr);
67         }
68       __catch (::L4::Base_exception const &e)
69         {
70           char const *s = e.str();
71           fputs("  what: ", stderr);
72           fputs(s, stderr);
73           fputs("\n", stderr);
74         }
75       __catch(::std::exception const &exc)
76         {
77           char const *w = exc.what();
78           fputs("  what():  ", stderr);
79           fputs(w, stderr);
80           fputs("\n", stderr);
81         }
82       __catch(...) { }
83     }
84   else
85     fputs("terminate called without an active exception\n", stderr);
86 
87   abort();
88 }
89 
90 } }
91