⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fault.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <windows.h>
#include <stdio.h>
#include "drwatcom.h"
#include "srchmsg.h"
#include "mem.h"
#include "intdlg.h"
#include "jdlg.h"
#include "madrtn.h"
#include "malloc.h"
#include "madsys.h"


msglist ExceptionMsgs[] = {
    EXCEPTION_ACCESS_VIOLATION,         (char *)STR_ACCESS_VIOLATION,
    EXCEPTION_BREAKPOINT,               (char *)STR_NADA,
    EXCEPTION_DATATYPE_MISALIGNMENT,    (char *)STR_DATA_MISALIGNMENT,
    EXCEPTION_SINGLE_STEP,              (char *)STR_NADA,
    EXCEPTION_ARRAY_BOUNDS_EXCEEDED,    (char *)STR_ARRAY_BNDS_EXCEEDED,
    EXCEPTION_FLT_DENORMAL_OPERAND,     (char *)STR_DENORMAL_FLOAT,
    EXCEPTION_FLT_DIVIDE_BY_ZERO,       (char *)STR_FLT_DIV_BY_ZERO,
    EXCEPTION_FLT_INEXACT_RESULT,       (char *)STR_FLT_INEXACT_RESULT,
    EXCEPTION_FLT_INVALID_OPERATION,    (char *)STR_FLT_INV_OP,
    EXCEPTION_FLT_OVERFLOW,             (char *)STR_FLT_PT_OVERFLOW,
    EXCEPTION_FLT_STACK_CHECK,          (char *)STR_FLT_STACK_CHECK,
    EXCEPTION_FLT_UNDERFLOW,            (char *)STR_FLT_UNDERFLOW,
    EXCEPTION_INT_DIVIDE_BY_ZERO,       (char *)STR_INT_DIV_BY_ZERO,
    EXCEPTION_INT_OVERFLOW,             (char *)STR_INT_OVERFLOW,
    EXCEPTION_PRIV_INSTRUCTION,         (char *)STR_INV_INSTRUCTION,
    STATUS_NONCONTINUABLE_EXCEPTION,    (char *)STR_NADA,
    0,                                  (char *)-1
};

#ifdef __NT__

static void setProcessHdl( HANDLE hdl ) {
    ProcessHdl = hdl;
}
#endif

/*
 * FormatException
 */
void FormatException( char *buf, DWORD code ) {

    char        *str;

    str = SrchMsg( code, ExceptionMsgs, NULL );
    if( str == NULL ) {
        str = buf;
        RCsprintf( buf, STR_UNKNOWN_EXCEPTION_X, code );
    } else {
        strcpy( buf, str );
    }
}

#define FNAME_BUFLEN    50
/*
 * fillExceptionDlg
 */
#define BUF_SIZE        100

ExceptDlgInfo * FaultGetExceptDlgInfo( HWND fault )
{
    return( (ExceptDlgInfo *)GetWindowLong( fault, DWL_USER ) );

}

static void SetIp( HWND hwnd, address *addr ) {
    mad_type_info   host;
    mad_type_info   mti;
    void            *item;
    char            buf[BUF_SIZE];
    unsigned        max;

    max = BUF_SIZE - 1;
    MADTypeInfoForHost( MTK_ADDRESS, sizeof( address ), &host );
    MADTypeInfo( MADTypeDefault( MTK_ADDRESS, MAF_FULL, NULL, addr ), &mti );
    item = alloca( ( mti.b.bits / BITS_PER_BYTE ) + 1);
    MADTypeConvert( &host, addr, &mti, item, 0 );
    MADTypeToString( 16, &mti, item, &max, buf );
    SetDlgItemText( hwnd, INT_CS_IP, buf );
}

static void fillExceptionDlg( HWND hwnd, ExceptDlgInfo *info ) {

    char                buf[BUF_SIZE];
    char                fname[ FNAME_BUFLEN ];
    DWORD               line;
    ProcStats           stats;
    HWND                ctl;
    address             addr;

    GetCurrAddr(&addr,info->regs);
    SetDlgCourierFont( hwnd, INT_TASK_NAME );
    SetDlgCourierFont( hwnd, INT_TASK_PATH );
    SetDlgCourierFont( hwnd, INT_FAULT_TYPE );
    SetDlgCourierFont( hwnd, INT_CS_IP );
    SetDlgCourierFont( hwnd, INT_SOURCE_INFO );
    SetDlgCourierFont( hwnd, INT_SOURCE_INFO2 );

    RCsprintf( buf, STR_EXCEPTION_ENCOUNTERED, AppName );
    SetWindowText( hwnd, buf );

    CopyRCString( STR_PROCESS_NAME, buf, BUF_SIZE );
    SetDlgItemText( hwnd, INT_TASK_NAME_TEXT, buf );

    if( !info->dbinfo->u.Exception.dwFirstChance ) {
        if( ConfigData.exception_action == INT_CHAIN_TO_NEXT ) {
            ConfigData.exception_action = INT_TERMINATE;
        }
        ctl = GetDlgItem( hwnd, INT_CHAIN_TO_NEXT );
        EnableWindow( ctl, FALSE );
    }
    CheckDlgButton( hwnd, ConfigData.exception_action, TRUE );
    CopyRCString( STR_PROCESS_ID, buf, BUF_SIZE );
    SetDlgItemText( hwnd, INT_TASK_PATH_TEXT, buf );

    while( !GetProcessInfo( info->procinfo->procid, &stats ) ) {
        Sleep( 100 );
        RefreshInfo();
    }
    SetDlgItemText( hwnd, INT_TASK_NAME, stats.name );

    sprintf( buf, "%08lX", info->procinfo->procid );
    SetDlgItemText( hwnd, INT_TASK_PATH, buf );

    FormatException( buf, info->dbinfo->u.Exception.ExceptionRecord.ExceptionCode );
    SetDlgItemText( hwnd, INT_FAULT_TYPE, buf );

    if( info->threadinfo != NULL ) {
        strcpy( buf, "Fault " );
        MADRegSpecialName( MSR_IP, info->regs, MAF_FULL, BUF_SIZE - 7, buf+6 );
        SetDlgItemText( hwnd, INT_IP_NAME, buf );
        SetIp( hwnd, &addr );
    }
    if( info->got_dbginfo && GetLineNum( &addr,fname, FNAME_BUFLEN, &line ) ) {
        RCsprintf( buf, STR_LINE_X_OF, line );
        SetDlgItemText( hwnd, INT_SOURCE_INFO, buf );
        SetDlgItemText( hwnd, INT_SOURCE_INFO2, fname );
    } else {
        CopyRCString( STR_N_A, buf, BUF_SIZE );
        SetDlgItemText( hwnd, INT_SOURCE_INFO, buf );
        SetDlgItemText( hwnd, INT_SOURCE_INFO2, "" );
    }
}

static void centerDialog( HWND hwnd ) {

    RECT        area;
    int         screen_width;
    int         screen_hite;
    int         xpos;
    int         ypos;
    WORD        xsize;
    WORD        ysize;

    GetWindowRect( hwnd, &area );
    screen_width = GetSystemMetrics( SM_CXSCREEN );
    screen_hite = GetSystemMetrics( SM_CYSCREEN );
    xsize = area.right - area.left;
    ysize = area.bottom - area.top;
    xpos = ( screen_width - xsize ) / 2;
    ypos = ( screen_hite - ysize ) / 2;
    MoveWindow( hwnd, xpos, ypos, xsize, ysize, TRUE );
}

/*
 * ExceptionProc
 */
BOOL CALLBACK ExceptionProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
    WORD                cmd;
    ExceptDlgInfo       *info;
    ProcNode            *procinfo;
    WORD                tmp;
    address             addr;

    info = FaultGetExceptDlgInfo( hwnd );
    switch( msg ) {
    case WM_INITDIALOG:
        /* make sure this dialog always comes up on top of everything else */
        SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
                        SWP_NOSIZE | SWP_NOMOVE );
        SetWindowPos( hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
                        SWP_NOSIZE | SWP_NOMOVE );
        centerDialog( hwnd );
        info = MemAlloc( sizeof( ExceptDlgInfo ) );
        info->dbinfo = (DEBUG_EVENT *)lparam;
        info->rc = 0;
        info->action = 0;
        SetWindowLong( hwnd, DWL_USER, (DWORD)info );
        info->procinfo = FindProcess( info->dbinfo->dwProcessId );
        info->threadinfo = FindThread( info->procinfo,
                                       info->dbinfo->dwThreadId );
        info->module = ModuleFromAddr( info->procinfo,
               info->dbinfo->u.Exception.ExceptionRecord.ExceptionAddress );
        if( info->threadinfo != NULL ) {
            AllocMadRegisters( &(info->regs) );
            LoadMADRegisters( info->regs, info->threadinfo->threadhdl );
            GetCurrAddr( &( info->init_ip ), info->regs );
        }
        if( info->module == NULL ) {
            info->got_dbginfo = FALSE;
        } else {
            if( !LoadDbgInfo( info->module ) ) {
                info->got_dbginfo = FALSE;
            } else {
                info->got_dbginfo = TRUE;
            }
        }
        if( LogData.autolog ) {         //Just create the log and exit
            tmp = ConfigData.exception_action;
            CheckDlgButton( hwnd, INT_TERMINATE, TRUE );
            SendMessage( hwnd, WM_COMMAND,
                        MAKELONG( INT_ACT_AND_LOG, BN_CLICKED ),
                        (LONG)GetDlgItem( hwnd, INT_ACT_AND_LOG ) );
            ConfigData.exception_action = tmp;
        } else {
            fillExceptionDlg( hwnd, info );
        }
        setProcessHdl( info->procinfo->prochdl );
        break;
    case WM_COMMAND:
        cmd = LOWORD( wparam );
        switch( cmd ) {
        case INT_ACT_AND_LOG:
            MakeLog( info );
            /* fall through */
        case INT_ACT:
            if( IsDlgButtonChecked( hwnd, INT_TERMINATE ) ) {
                ConfigData.exception_action = INT_TERMINATE;
//              hp = OpenProcess( PROCESS_TERMINATE, FALSE,
//                                info->dbinfo->dwProcessId );
                procinfo = FindProcess( info->dbinfo->dwProcessId );
                if( procinfo == NULL ) {
                    RCMessageBox( hwnd, STR_CANT_TERMINATE_APP,
                                  AppName, MB_OK | MB_ICONEXCLAMATION );
                } else {
                    TerminateProcess( procinfo->prochdl, -1 );
//                  CloseHandle( hp );
                    info->rc = DBG_CONTINUE;
                    info->action = INT_TERMINATE;
                    SendMessage( hwnd, WM_CLOSE, 0, 0L );
                }
            } else if( IsDlgButtonChecked( hwnd, INT_CHAIN_TO_NEXT ) ) {
                ConfigData.exception_action = INT_CHAIN_TO_NEXT;
                info->rc = DBG_EXCEPTION_NOT_HANDLED;
                info->action = INT_CHAIN_TO_NEXT;
                SendMessage( hwnd, WM_CLOSE, 0, 0L );
            } else if( IsDlgButtonChecked( hwnd, INT_RESTART ) ) {
                ConfigData.exception_action = INT_RESTART;
                info->rc = DBG_CONTINUE;
                info->action = INT_RESTART;
                SendMessage( hwnd, WM_CLOSE, 0, 0L );
            }
            break;
        case INT_REGISTERS:
            SetDisasmInfo( info->procinfo->prochdl, info->module );
            StatShowSymbols = TRUE;
            if ( DoStatDialog( hwnd ) == 1 ){
                StoreMADRegisters( info->regs, info->threadinfo->threadhdl );
                GetCurrAddr(&addr,info->regs);
                SetIp( hwnd, &addr );
            }
            LoadMADRegisters( info->regs, info->threadinfo->threadhdl );
            break;
        case INT_LOG_OPTIONS:
            SetLogOptions( hwnd );
            break;
        }
        break;
    case WM_CLOSE:
        if( info->rc == 0 ) {
            SendMessage( hwnd, WM_COMMAND, INT_ACT, 0L );
        } else {
            if( info->got_dbginfo ) {
                UnloadDbgInfo( info->module );
            }
            EndDialog( hwnd, info->rc );
        }
        break;
    case WM_DESTROY:
        DeAllocMadRegisters( info->regs );
        MemFree( info );
        break;
    default:
        return( FALSE );
        break;
    }
    return( TRUE );
}

/*
 * HandleException
 */
int HandleException( DEBUG_EVENT *dbinfo ) {

    int         ret;

    RefreshCostlyInfo();
    ret = JDialogBoxParam( Instance, "INTERRUPT", MainHwnd, ExceptionProc,
                    (DWORD)dbinfo );
    return( ret );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -