mirror of
https://github.com/boostorg/core.git
synced 2025-07-29 20:37:22 +02:00
Add core/verbose_terminate_handler.hpp
This commit is contained in:
87
include/boost/core/verbose_terminate_handler.hpp
Normal file
87
include/boost/core/verbose_terminate_handler.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
|
||||
#define BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <exception>
|
||||
#include <typeinfo>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
BOOST_NORETURN void verbose_terminate_handler()
|
||||
{
|
||||
std::set_terminate( 0 );
|
||||
|
||||
#if defined(BOOST_NO_EXCEPTIONS)
|
||||
|
||||
std::fputs( "std::terminate called with exceptions disabled", stderr );
|
||||
|
||||
#else
|
||||
|
||||
try
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch( std::exception const& x )
|
||||
{
|
||||
#if defined(BOOST_NO_RTTI)
|
||||
|
||||
char const * typeid_name = "unknown (RTTI is disabled)";
|
||||
|
||||
#else
|
||||
|
||||
char const * typeid_name = typeid( x ).name();
|
||||
|
||||
boost::core::scoped_demangled_name typeid_demangled_name( typeid_name );
|
||||
|
||||
if( typeid_demangled_name.get() != 0 )
|
||||
{
|
||||
typeid_name = typeid_demangled_name.get();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
std::fprintf( stderr,
|
||||
"std::terminate called after throwing an exception:\n"
|
||||
" type: %s\n"
|
||||
" what(): %s\n"
|
||||
" location: %s:%lu:%lu in function '%s'\n",
|
||||
|
||||
typeid_name,
|
||||
x.what(),
|
||||
loc.file_name(), static_cast<unsigned long>( loc.line() ),
|
||||
static_cast<unsigned long>( loc.column() ), loc.function_name()
|
||||
);
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
std::fputs( "std::terminate called after throwing an unknown exception", stderr );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
std::abort();
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
|
@ -331,5 +331,10 @@ run as_writable_bytes_test.cpp ;
|
||||
run splitmix64_test.cpp
|
||||
: : : $(pedantic-errors) ;
|
||||
|
||||
run-fail verbose_terminate_handler_fail.cpp ;
|
||||
run-fail verbose_terminate_handler_fail.cpp : : : <exception-handling>off : verbose_terminate_handler_fail_nx ;
|
||||
run-fail verbose_terminate_handler_fail.cpp : : : <rtti>off : verbose_terminate_handler_fail_nr ;
|
||||
run-fail verbose_terminate_handler_fail.cpp : : : <exception-handling>off <rtti>off : verbose_terminate_handler_fail_nxr ;
|
||||
|
||||
use-project /boost/core/swap : ./swap ;
|
||||
build-project ./swap ;
|
||||
|
48
test/verbose_terminate_handler_fail.cpp
Normal file
48
test/verbose_terminate_handler_fail.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
#include <boost/core/verbose_terminate_handler.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <exception>
|
||||
#include <stdlib.h>
|
||||
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
|
||||
# include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER > 1310)
|
||||
// disable message boxes on assert(), abort()
|
||||
::_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
|
||||
#endif
|
||||
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
|
||||
// disable message boxes on iterator debugging violations
|
||||
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
|
||||
#endif
|
||||
|
||||
std::set_terminate( boost::core::verbose_terminate_handler );
|
||||
|
||||
boost::throw_with_location( std::exception() );
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_EXCEPTIONS)
|
||||
|
||||
void boost::throw_exception( std::exception const& x )
|
||||
{
|
||||
std::fprintf( stderr, "throw_exception: %s\n\n", x.what() );
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
void boost::throw_exception( std::exception const& x, boost::source_location const& )
|
||||
{
|
||||
std::fprintf( stderr, "throw_exception: %s\n\n", x.what() );
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user