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
137
138
139
140
141
142
143
144
145
146
147
|
/* -*- c++ -*- */
/*
* Copyright 2018 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <pmt/pmt.h>
#include <boost/thread.hpp>
#include <exception>
#include <iostream>
#include <regex>
#include <stdexcept>
#include <cxxabi.h>
#ifdef HAVE_LIBUNWIND
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <cstdio>
#include <cstdlib>
#endif
namespace gr {
#ifdef HAVE_LIBUNWIND
void print_backtrace()
{
unw_cursor_t cursor;
unw_context_t context;
// Initialize cursor to current frame for local unwinding.
unw_getcontext(&context);
unw_init_local(&cursor, &context);
// Unwind frames one by one, going up the frame stack.
while (unw_step(&cursor) > 0) {
unw_word_t offset, pc;
unw_get_reg(&cursor, UNW_REG_IP, &pc);
if (pc == 0) {
break;
}
std::fprintf(stderr, "0x%lx:", pc);
char sym[256];
if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) {
char* nameptr = sym;
int status;
char* demangled = abi::__cxa_demangle(sym, nullptr, nullptr, &status);
if (status == 0) {
nameptr = demangled;
}
std::fprintf(stderr, " (%s+0x%lx)\n", nameptr, offset);
std::free(demangled);
} else {
std::fprintf(stderr,
" -- error: unable to obtain symbol name for this frame\n");
}
}
}
#endif
void terminate_handler_impl()
{
std::cerr << "terminate reached from thread id: " << boost::this_thread::get_id();
try {
std::exception_ptr eptr = std::current_exception();
if (eptr) {
std::rethrow_exception(eptr);
}
} catch (const std::out_of_range& e) {
std::cerr << "Got std::out_of_range" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::length_error& e) {
std::cerr << "Got std::length_error" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::domain_error& e) {
std::cerr << "Got std::domain_error" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::invalid_argument& e) {
std::cerr << "Got std::invalid_argument" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const pmt::exception& e) {
std::cerr << "Got pmt::exception" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::logic_error& e) {
std::cerr << "Got std::logic_error" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::ios_base::failure& e) {
std::cerr << "Got std::ios_base::falure" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::system_error& e) {
std::cerr << "Got std::system_error" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::regex_error& e) {
std::cerr << "Got std::regex_error" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::underflow_error& e) {
std::cerr << "Got std::underflow_error" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::overflow_error& e) {
std::cerr << "Got std::overflow_error" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::range_error& e) {
std::cerr << "Got std::range_error" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::runtime_error& e) {
std::cerr << "Got std::runtime_error" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::bad_typeid& e) {
std::cerr << "Got std::bad_typeid" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::bad_cast& e) {
std::cerr << "Got std::bad_cast" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::bad_weak_ptr& e) {
std::cerr << "Got std::bad_weak_ptr" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::bad_function_call& e) {
std::cerr << "Got std::bad_function_call" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::bad_array_new_length& e) {
std::cerr << "Got std::bad_array_new_length" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::bad_alloc& e) {
std::cerr << "Got std::bad_alloc" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::bad_exception& e) {
std::cerr << "Got std::bad_exception" << std::endl;
std::cerr << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Got std::exception" << std::endl;
std::cerr << e.what() << std::endl;
} catch (...) {
std::cerr << "Got unknown exception" << std::endl;
}
#ifdef HAVE_LIBUNWIND
// Use libunwind to print a backtrace
print_backtrace();
#endif
std::abort();
}
void install_terminate_handler() { std::set_terminate(&terminate_handler_impl); }
} // namespace gr
|