Example #1
0
[[noreturn]] void terminate_handler() noexcept {
	// immediately unset this handler, to avoid endless recursions if
	// terminate() is accidentially triggered from here.
	std::set_terminate(old_terminate_handler);

	std::cout << "\n\x1b[31;1mFATAL: terminate has been called\x1b[m" << std::endl;

	if(std::exception_ptr e_ptr = std::current_exception()) {
		std::cout << "\n\x1b[33muncaught exception\x1b[m\n" << std::endl;

		try {
			std::rethrow_exception(e_ptr);
		} catch (Error &exc) {
			std::cout << exc << std::endl;
		} catch (std::exception &exc) {
			std::cout <<
				"std::exception of type " <<
				util::demangle(typeid(exc).name()) <<
				": " << exc.what() << std::endl;
		} catch (...) {
			std::cout << "non-standard exception object" << std::endl;
		}
	}

	std::cout << "\n\x1b[33mcurrent stack\x1b[m\n" << std::endl;

	StackAnalyzer backtrace;
	backtrace.analyze();
	std::cout << backtrace << std::endl;

	// call the original handler, to enable debugger functionality,
	// and maybe print some additional useful info that we forgot about.
	std::cout << "\x1b[33mstandard terminate handler\x1b[m\n" << std::endl;
	std::terminate();
}
Example #2
0
void StackAnalyzer::trim_to_current_stack_frame() {
	StackAnalyzer current;
	current.analyze();

	while (not current.stack_addrs.empty() and not this->stack_addrs.empty()) {
		if (this->stack_addrs.back() != current.stack_addrs.back()) {
			break;
		}

		this->stack_addrs.pop_back();
		current.stack_addrs.pop_back();
	}
}