2020-02-28 00:34:34 -07:00
# include "module.h"
2018-12-22 13:05:01 -05:00
# include <sstream>
namespace
{
char * GetCppExceptionInfo ( EXCEPTION_POINTERS * exception )
{
// See https://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273
// Not very reliable so use __try
__try { return ( ( char * * * * ) exception - > ExceptionRecord - > ExceptionInformation [ 2 ] ) [ 3 ] [ 1 ] [ 1 ] + 8 ; }
__except ( EXCEPTION_EXECUTE_HANDLER ) { return " Could not find " ; }
}
2019-02-18 22:17:56 -05:00
const char * GetCppExceptionMessage ( EXCEPTION_POINTERS * exception )
{
__try { return ( ( std : : exception * ) exception - > ExceptionRecord - > ExceptionInformation [ 1 ] ) - > what ( ) ; }
__except ( EXCEPTION_EXECUTE_HANDLER ) { return " Could not find " ; }
}
2018-12-22 13:05:01 -05:00
thread_local std : : wstring lastError = L " Unknown error " ;
__declspec ( noreturn ) void Terminate ( )
{
2021-02-21 14:15:59 -07:00
WaitForSingleObject ( CreateThread ( nullptr , 0 , [ ] ( void * lastError ) - > DWORD
2020-03-01 23:41:27 -07:00
{
MessageBoxW ( NULL , ( wchar_t * ) lastError , L " Textractor ERROR " , MB_ICONERROR ) ; // might fail to display if called in main thread and exception was in main event loop
abort ( ) ;
2021-02-21 14:15:59 -07:00
} , lastError . data ( ) , 0 , nullptr ) , INFINITE ) ;
2018-12-22 13:05:01 -05:00
}
LONG WINAPI ExceptionLogger ( EXCEPTION_POINTERS * exception )
{
2019-02-18 22:17:56 -05:00
thread_local static auto _ = set_terminate ( Terminate ) ;
2018-12-22 13:05:01 -05:00
MEMORY_BASIC_INFORMATION info = { } ;
VirtualQuery ( exception - > ExceptionRecord - > ExceptionAddress , & info , sizeof ( info ) ) ;
std : : wstringstream errorMsg ;
errorMsg < < std : : uppercase < < std : : hex < <
L " Error code: " < < exception - > ExceptionRecord - > ExceptionCode < < std : : endl < <
L " Error address: " < < exception - > ExceptionRecord - > ExceptionAddress < < std : : endl < <
2020-02-28 00:34:34 -07:00
L " Error in module: " < < GetModuleFilename ( ( HMODULE ) info . AllocationBase ) . value_or ( L " Could not find " ) < < std : : endl < <
2018-12-22 13:05:01 -05:00
L " Additional info: " < < info . AllocationBase < < std : : endl ;
if ( exception - > ExceptionRecord - > ExceptionCode = = 0xE06D7363 )
2019-02-18 22:17:56 -05:00
{
if ( char * info = GetCppExceptionInfo ( exception ) ) errorMsg < < L " Additional info: " < < info < < std : : endl ;
if ( const char * info = GetCppExceptionMessage ( exception ) ) errorMsg < < L " Additional info: " < < info < < std : : endl ;
}
2018-12-22 13:05:01 -05:00
for ( int i = 0 ; i < exception - > ExceptionRecord - > NumberParameters ; + + i )
errorMsg < < L " Additional info: " < < exception - > ExceptionRecord - > ExceptionInformation [ i ] < < std : : endl ;
lastError = errorMsg . str ( ) ;
return EXCEPTION_CONTINUE_SEARCH ;
}
2019-01-20 09:52:35 -05:00
auto _ = ( AddVectoredExceptionHandler ( FALSE , ExceptionLogger ) , SetUnhandledExceptionFilter ( [ ] ( auto ) - > LONG { Terminate ( ) ; } ) ) ;
2018-12-27 00:18:05 -05:00
}