/* -*- 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> #ifdef HAVE_LIBUNWIND #define UNW_LOCAL_ONLY #include <cxxabi.h> #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::failure" << 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