excptwnt.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 512 行 · 第 1/2 页
C
512 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Default Win32 exception handlers.
*
****************************************************************************/
#include "variety.h"
#include <windows.h>
#include <excpt.h>
#include <float.h>
#include <signal.h>
#include <unistd.h>
#include "iomode.h"
#include "rtdata.h"
#include "sigtab.h"
#include "sigfunc.h"
#include "fpusig.h"
#include "excptwnt.h"
#include "clearfpe.h"
__sig_func (*__oscode_check_func)( int, long ) = NULL;
int (*__raise_func)( int ) = NULL;
unsigned char __ExceptionHandled;
unsigned char __ReportInvoked;
static int _my_GetActiveWindow( void ) {
HANDLE hdl;
typedef HWND (__stdcall *gaw_type)( void );
gaw_type gaw;
HWND rc = 0;
hdl = LoadLibrary( "USER32.DLL" );
if( hdl != 0 ) {
gaw = (gaw_type) GetProcAddress( hdl, "GetActiveWindow" );
if( gaw != 0 ) {
rc = (*gaw)();
}
}
return( rc != 0 );
}
static void fmt_hex( char *buf, char *fmt, void *hex ) {
static char alpha[] = "0123456789abcdef";
char *ptr = NULL;
unsigned long value;
/*
* find the end of the buffer
*/
while( *buf != '\0' ) {
buf++;
}
/*
* copy the format string into the buffer
*/
for( ;; ) {
*buf = *fmt;
if( *fmt == '\0' ) break;
if( *fmt == '0' && *(fmt+1) == 'x' ) {
/* memorize the location of the hex field */
ptr = buf+9;
}
buf++;
fmt++;
}
/*
* format the hex value, if a location was found
*/
if( ptr != NULL ) {
value = (unsigned long)hex;
while( value ) {
*ptr = alpha[ value & 0xf ];
value = value >> 4;
ptr--;
}
}
}
/*
* Make function external so we can set it manually
*/
LONG WINAPI __ReportException( EXCEPTION_POINTERS *rec )
{
EXCEPTION_RECORD *ex = rec->ExceptionRecord;
#if defined( _M_IX86 )
CONTEXT *context = rec->ContextRecord;
DWORD *sp;
int i;
#endif
char buff[256];
DWORD written;
// if we are active then we've done crashed ourselves.
if( __ReportInvoked )
return( EXCEPTION_CONTINUE_SEARCH );
__ReportInvoked = 1; // indicate that we ran
/*
* Test to see if there is an active window.
*/
if( _my_GetActiveWindow() || ( __NTConsoleOutput() == (HANDLE)-1 )) {
return( EXCEPTION_CONTINUE_SEARCH );
}
/*
* prepare the mesage buffer
*/
buff[0] = '\0';
/*
* Lets see what caused the exception.
*/
switch( ex->ExceptionCode ) {
#if defined( _M_IX86 )
case STATUS_FLOAT_STACK_CHECK:
if( context->FloatSave.StatusWord & SW_C1 ) {
fmt_hex( buff, "The instruction at 0x00000000 caused a "
"stack overflow floating point\nexception.\n",
ex->ExceptionAddress );
} else {
fmt_hex( buff, "The instruction at 0x00000000 caused a "
"stack underflow floating point\nexception.\n",
ex->ExceptionAddress );
}
break;
#elif defined( __AXP__ )
// no alpha specific floating point exceptions
#elif defined( __PPC__ )
// no ppc specific floating point exceptions
#endif
case STATUS_FLOAT_DENORMAL_OPERAND:
fmt_hex( buff, "The instruction at 0x00000000 caused a denormal "
"operand floating point\nexception.\n",
ex->ExceptionAddress );
break;
case STATUS_FLOAT_DIVIDE_BY_ZERO:
fmt_hex( buff, "The instruction at 0x00000000 caused a division "
"by zero floating point\nexception.\n",
ex->ExceptionAddress );
break;
case STATUS_FLOAT_INEXACT_RESULT:
fmt_hex( buff, "The instruction at 0x00000000 caused an inexact "
"value floating point\nexception.\n",
ex->ExceptionAddress );
break;
case STATUS_FLOAT_OVERFLOW:
fmt_hex( buff, "The instruction at 0x00000000 caused an overflow "
"floating point exception.\n",
ex->ExceptionAddress );
break;
case STATUS_FLOAT_UNDERFLOW:
fmt_hex( buff, "The instruction at 0x00000000 caused an underflow "
"floating point exception.\n",
ex->ExceptionAddress );
break;
case STATUS_FLOAT_INVALID_OPERATION:
fmt_hex( buff, "The instruction at 0x00000000 caused an invalid "
"operation floating point\nexception.\n",
ex->ExceptionAddress );
break;
#if defined( __AXP__ )
case STATUS_DATATYPE_MISALIGNMENT:
fmt_hex( buff, "The instruction at 0x00000000 tried to reference ",
ex->ExceptionAddress );
fmt_hex( buff, "unaligned data at 0x00000000.\n",
(void *)(ex->ExceptionInformation[2]) );
break;
#endif
case STATUS_ACCESS_VIOLATION:
fmt_hex( buff, "The instruction at 0x00000000 referenced memory ",
ex->ExceptionAddress );
fmt_hex( buff, "at 0x00000000.\nThe memory could not be ",
(void *)(ex->ExceptionInformation[1]) );
if( ex->ExceptionInformation[0] == 0 ) {
fmt_hex( buff, "read.\n", 0 );
} else {
fmt_hex( buff, "written.\n", 0 );
}
break;
case STATUS_PRIVILEGED_INSTRUCTION:
fmt_hex( buff, "A privileged instruction was executed at "
"address 0x00000000.\n", ex->ExceptionAddress );
break;
case STATUS_ILLEGAL_INSTRUCTION:
fmt_hex( buff, "An illegal instruction was executed at "
"address 0x00000000.\n", ex->ExceptionAddress );
break;
case STATUS_INTEGER_DIVIDE_BY_ZERO:
fmt_hex( buff, "An integer divide by zero was encountered at "
"address 0x00000000.\n", ex->ExceptionAddress );
break;
case STATUS_STACK_OVERFLOW:
fmt_hex( buff, "A stack overflow was encountered at address "
"0x00000000.\n", ex->ExceptionAddress );
break;
default:
fmt_hex( buff, "The program encountered exception 0x00000000 at ",
(void *)ex->ExceptionCode );
fmt_hex( buff, "address 0x00000000 and\ncannot continue.\n",
ex->ExceptionAddress );
break;
}
WriteFile( NT_STDERR_FILENO, buff, strlen( buff ), &written, NULL );
#if defined( _M_IX86 )
buff[0] = '\0';
fmt_hex( buff, "Exception fielded by 0x00000000\n", __ReportException );
WriteFile( NT_STDERR_FILENO, buff, strlen(buff), &written, NULL );
buff[0] = '\0';
if( context->ContextFlags & CONTEXT_INTEGER ) {
fmt_hex( buff, "EAX=0x00000000 ", (void *)context->Eax );
fmt_hex( buff, "EBX=0x00000000 ", (void *)context->Ebx );
fmt_hex( buff, "ECX=0x00000000 ", (void *)context->Ecx );
fmt_hex( buff, "EDX=0x00000000\n", (void *)context->Edx );
fmt_hex( buff, "ESI=0x00000000 ", (void *)context->Esi );
fmt_hex( buff, "EDI=0x00000000 ", (void *)context->Edi );
}
if( context->ContextFlags & CONTEXT_CONTROL ) {
fmt_hex( buff, "EBP=0x00000000 ", (void *)context->Ebp );
fmt_hex( buff, "ESP=0x00000000\n", (void *)context->Esp );
fmt_hex( buff, "EIP=0x00000000 ", (void *)context->Eip );
fmt_hex( buff, "EFL=0x00000000 ", (void *)context->EFlags );
fmt_hex( buff, "CS =0x00000000 ", (void *)context->SegCs );
fmt_hex( buff, "SS =0x00000000\n", (void *)context->SegSs );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?