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 + -
显示快捷键?