excptwnt.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 512 行 · 第 1/2 页
C
512 行
if( context->ContextFlags & CONTEXT_SEGMENTS ) {
fmt_hex( buff, "DS =0x00000000 ", (void *)context->SegDs );
fmt_hex( buff, "ES =0x00000000 ", (void *)context->SegEs );
fmt_hex( buff, "FS =0x00000000 ", (void *)context->SegFs );
fmt_hex( buff, "GS =0x00000000\n", (void *)context->SegGs );
}
WriteFile( NT_STDERR_FILENO, buff, strlen(buff), &written, NULL );
buff[0] = '\0';
if( context->ContextFlags & CONTEXT_CONTROL ) {
sp = (DWORD *)context->Esp;
fmt_hex( buff, "Stack dump (SS:ESP)\n", 0 );
for( i = 1; i <= 72; i++) {
if(( (long)sp & 0x0000FFFF ) == 0 ) {
fmt_hex( buff, "-stack end\n", 0 );
} else {
fmt_hex( buff, "0x00000000 ", GetFromSS( sp ) );
}
if(( i % 6 ) == 0 ) {
fmt_hex( buff, "\n", 0 );
}
WriteFile( NT_STDERR_FILENO, buff, strlen( buff ), &written, NULL );
buff[0] = '\0';
if(( (long)sp & 0x0000FFFF ) == 0 )
break;
sp++;
}
}
#endif
return( EXCEPTION_EXECUTE_HANDLER );
}
void __DefaultExceptionHandler( void )
{
LPTOP_LEVEL_EXCEPTION_FILTER top_filter;
// This routine is called whenever a new process begins.
// Install an exception handler and then check to see if we already
// have one. If we did, set it back to the previous one. This ensures
// we always have one set up and permits apps to install their own.
top_filter = SetUnhandledExceptionFilter( __ReportException );
if( top_filter != NULL ) {
SetUnhandledExceptionFilter( top_filter );
}
}
// Note: this needs to be cdecl for Win32s and Windows 95
// Windows NT doesn't care if it is cdecl or stdcall
int __cdecl __ExceptionFilter( LPEXCEPTION_RECORD ex,
LPVOID establisher_frame,
LPCONTEXT context,
LPVOID dispatch_context )
{
int sig;
int fpe;
#if defined( _M_IX86 )
char *eip;
status_word sw;
DWORD tw;
#endif
EXCEPTION_POINTERS rec;
LONG rv;
/*
* unused parms
*/
dispatch_context = dispatch_context;
establisher_frame = establisher_frame;
/*
* Test some conditions we can immediately resolve.
*/
if( ex->ExceptionFlags & UNWINDING )
return( ExceptionContinueSearch );
/*
* Lets see what caused the exception.
*/
switch( ex->ExceptionCode ) {
#if defined( _M_IX86 )
case STATUS_FLOAT_STACK_CHECK:
if( context->FloatSave.StatusWord & SW_C1 ) {
fpe = FPE_STACKOVERFLOW;
} else {
fpe = FPE_STACKUNDERFLOW;
}
break;
#elif defined( __AXP__ )
// no alpha specific floating point exceptions
#elif defined( __PPC__ )
// no ppc specific floating point exceptions
#else
#error *** Platform Not Supported ***
#endif
case STATUS_FLOAT_DENORMAL_OPERAND:
fpe = FPE_DENORMAL;
break;
case STATUS_FLOAT_DIVIDE_BY_ZERO:
fpe = FPE_ZERODIVIDE;
break;
case STATUS_FLOAT_INEXACT_RESULT:
fpe = FPE_INEXACT;
break;
case STATUS_FLOAT_OVERFLOW:
fpe = FPE_OVERFLOW;
break;
case STATUS_FLOAT_UNDERFLOW:
fpe = FPE_UNDERFLOW;
break;
case STATUS_FLOAT_INVALID_OPERATION:
fpe = FPE_INVALID;
#if defined( _M_IX86 )
eip = (unsigned char *)context->FloatSave.ErrorOffset;
if( *(unsigned short *)eip == 0xfad9 ) { // caused by "fsqrt"
fpe = FPE_SQRTNEG;
} else if( *(unsigned short *)eip == 0xf1d9 ) { // caused by "fyl2x"
fpe = FPE_LOGERR;
} else if( *(unsigned short *)eip == 0xf8d9 ) { // caused by "fprem"
fpe = FPE_MODERR;
} else if( *(unsigned short *)eip == 0xf5d9 ) { // caused by "fprem1"
fpe = FPE_MODERR;
} else {
if(( eip[0] == 0xdb ) || ( eip[0] == 0xdf )) {
if(( eip[1] & 0x30 ) == 0x10 ) { // caused by "fist(p)"
fpe = FPE_IOVERFLOW;
}
}
if( !( eip[0] & 0x01 ) ) {
if(( eip[1] & 0x30 ) == 0x30 ) { // "fdiv" or "fidiv"
tw = context->FloatSave.TagWord & 0x0000ffff;
sw.sw = context->FloatSave.StatusWord & 0x0000ffff;
if((( tw >> (sw.b.st << 1) ) & 0x01 ) == 0x01 ) {
fpe = FPE_ZERODIVIDE;
}
}
}
}
#endif
break;
default:
fpe = -1;
break;
}
/*
* If fpe != -1 then we have an identified floating point exception.
* If there is a handler, invoke it.
*/
if( fpe != -1 ) {
__ExceptionHandled = 1;
_ClearFPE();
if( __sigfpe_handler( fpe ) != -1 ) {
if( __ExceptionHandled ) {
#if defined( _M_IX86 )
context->FloatSave.StatusWord &=
~( SW_BUSY | SW_XCPT_FLAGS | SW_IREQ );
#elif defined( __AXP__ )
((unsigned long *)&context->Fpcr)[1] &=
~(FPCR_SUMMARY_BIT | FPCR_XCPT_FLAGS);
#elif defined( __PPC__ )
// Can we do something here?
#else
#error *** Platform Not Supported ***
#endif
return( ExceptionContinueExecution );
}
}
} else if( __raise_func ) {
/*
* If the signal handling code is linked in then we need to see if the
* user has installed a signal handler.
*/
__sig_func func;
for( sig = 1; sig <= __SIGLAST; sig++ ) {
func = __oscode_check_func( sig, ex->ExceptionCode );
if( func != NULL ) {
if(( func == SIG_IGN ) || ( func == SIG_DFL ) || ( func == SIG_ERR )) {
break;
}
__ExceptionHandled = 1;
(*__raise_func)( sig );
if( __ExceptionHandled ) { // User has fixed up state
return( ExceptionContinueExecution );
}
}
}
}
rec.ExceptionRecord = ex;
rec.ContextRecord = context;
__ReportInvoked = 0; // indicate our own last-chance handler has not run
// Call __ReportException or an application-installed handler.
// NOTE: if running under a debugger, the handler will NOT be called
// and it returns EXCEPTION_CONTINUE_SEARCH
//
// Possible rv values:
// -1 => EXCEPTION_CONTINUE_EXECUTION
// 0 => EXCEPTION_CONTINUE_SEARCH
// +1 => EXCEPTION_EXECUTE_HANDLER
//
rv = UnhandledExceptionFilter( &rec );
if( rv == EXCEPTION_EXECUTE_HANDLER ) {
ExitProcess( -1 );
} else if( rv == EXCEPTION_CONTINUE_EXECUTION ) {
return( ExceptionContinueExecution );
}
return( ExceptionContinueSearch );
}
void __NewExceptionFilter( REGISTRATION_RECORD *rr )
{
// This routine is called whenever a new process/thread begins.
__XCPTHANDLER = rr;
#if defined( __386__ )
rr->RegistrationRecordPrev = (LPVOID)GetFromFS( 0 );
rr->RegistrationRecordFilter = __ExceptionFilter;
PutToFS( (DWORD)rr, 0 );
#elif defined( __AXP__ )
// __ExceptionFilter() installed in __NTMain()'s pdata
#elif defined( __PPC__ )
// No idea yet.
#endif
}
void __DoneExceptionFilter( void )
{
#if defined( __386__ )
REGISTRATION_RECORD *rr;
rr = __XCPTHANDLER;
if( rr ) {
PutToFS( (DWORD)rr->RegistrationRecordPrev, 0 );
}
#elif defined( __AXP__ )
// Nothing to do
#elif defined( __PPC__ )
// No idea yet.
#endif
__XCPTHANDLER = NULL;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?