stubdb.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 826 行 · 第 1/2 页

C
826
字号
/****************************************************************************
*
*                            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:  Debugger stub functions.
*
****************************************************************************/


#include "windows.h"
#include "dbgdefn.h"
#include "dbgmem.h"
#include "dbginfo.h"
#include "bool.h"
#include "ambigsym.h"
#include "dbgtoggl.h"
#include "dbglit.h"
#include "mad.h"
#include "dui.h"
#include "dbgvar.h"

#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <process.h>

extern void             FlushEOC(void);
extern char             *DupStr(char*);
extern void             DoCmd(char*);
extern bool             InsMemRef( mad_disasm_data *dd );
extern address          GetCodeDot();
extern void             *WndAsmInspect(address addr);
extern void             DebugMain();
extern void             DebugFini();
extern void             DoInput(void);
extern void             DlgCmd( void );
extern void             UnAsm( address addr, unsigned max, char *buff );
extern address          GetCodeDot();
extern char             *DupStr(char*);
extern bool             DUIGetSourceLine( cue_handle *ch, char *buff, unsigned len );
extern void             ExecTrace( trace_cmd_type type, debug_level level );
extern unsigned         Go( bool );
extern void             *OpenSrcFile(cue_handle *);
extern int              FReadLine(void   *,int ,int ,char *,int );
extern void             FDoneSource(void         *);


extern debug_level      DbgLevel;
extern char             *TxtBuff;
extern unsigned char    CurrRadix;
static char             *CmdData;
static bool             Done;
extern char             *TrpFile;


void WndMemInit( void )
{
}

void InitScreen( void )
{
}

void FiniScreen( void )
{
}

unsigned ConfigScreen( void )
{
    return( 0 );
}

bool DUIClose()
{
    Done = TRUE;
    return( TRUE );
}

char *GetCmdArg( int num )
{
    if( num != 0 ) return( NULL );
    return( CmdData );
}

void SetCmdArgStart( int num, char far *ptr )
{
    num = num;
    CmdData = ptr;
}

var_info        Locals;
HANDLE          Requestsem;
HANDLE          Requestdonesem;

static void DumpLocals()
{
#if 0
    address     addr;
    int         row;
    int         depth;
    var_node    *v;

    if( !_IsOn( SW_TASK_RUNNING ) ) {
        VarErrState();
        VarInfoRefresh( VAR_LOCALS, &Locals, &addr, NULL );
        VarOkToCache( &Locals, TRUE );
    }
    for( row = 0;; ++row ) {
        v = VarGetDisplayPiece( &Locals, row, VAR_PIECE_GADGET, &depth );
        if( v == NULL ) break;
        v = VarGetDisplayPiece( &Locals, row, VAR_PIECE_NAME, &depth );
        v = VarGetDisplayPiece( &Locals, row, VAR_PIECE_VALUE, &depth );
        switch( v->gadget ) {
        case VARGADGET_NONE:
            printf( "  " );
            break;
        case VARGADGET_OPEN:
            printf( "+ " );
            break;
        case VARGADGET_CLOSE:
            printf( "- " );
            break;
        case VARGADGET_POINTS:
            printf( "->" );
            break;
        case VARGADGET_UNPOINTS:
            printf( "<-" );
            break;
        }
        VarBuildName( v, TRUE );
        printf( " %-20s %s\n", TxtBuff, v->value );
    }
    if( !_IsOn( SW_TASK_RUNNING ) ) {
        VarOkToCache( &Locals, FALSE );
        VarOldErrState();
    }
#endif
}

static void DumpSource()
{
    char        buff[256];
    DIPHDL( cue, ch );

    if( _IsOn( SW_TASK_RUNNING ) ) {
        printf( "I don't know where the task is.  It's running\n" );
    }
    if( DeAliasAddrCue( NO_MOD, GetCodeDot(), ch ) == SR_NONE ||
        !DUIGetSourceLine( ch, buff, sizeof( buff ) ) ) {
        UnAsm( GetCodeDot(), sizeof( buff ), buff );
    }
    printf( "%s\n", buff );
}

enum {
    REQ_NONE,
    REQ_BYE,
    REQ_GO,
    REQ_TRACE_OVER,
    REQ_TRACE_INTO
} Req = REQ_NONE;

bool RequestDone;

DWORD WINAPI ControlFunc( void *parm )
{
    parm = parm;
    do {
        WaitForSingleObject( Requestsem, INFINITE ); // wait for Request
        switch( Req ) {
        case REQ_GO:
            Go( TRUE );
            break;
        case REQ_TRACE_OVER:
            ExecTrace( TRACE_OVER, DbgLevel );
            break;
        case REQ_TRACE_INTO:
            ExecTrace( TRACE_INTO, DbgLevel );
            break;
        }
        DoInput();
        _SwitchOff( SW_TASK_RUNNING );
        ReleaseSemaphore( Requestdonesem, 1, NULL ); // signal req done
    } while( Req != REQ_BYE );
    return( 0 ); // thread over!
}

void RunRequest( int req )
{
    if( _IsOn( SW_TASK_RUNNING ) ) return;
    WaitForSingleObject( Requestdonesem, INFINITE ); // wait for last request to finish
    Req = req;
    _SwitchOn( SW_TASK_RUNNING );
    ReleaseSemaphore( Requestsem, 1, NULL ); // tell worker to go
}

int main( int argc, char **argv )
{
    char        buff[256];
    DWORD       tid;
    HANDLE      hThread;

    MemInit();
    SetErrorMode( SEM_FAILCRITICALERRORS );
    getcmd( buff );
    CmdData = buff;
    DebugMain();
    _SwitchOff( SW_ERROR_STARTUP );
    DoInput();
    VarInitInfo( &Locals );
    Requestsem = CreateSemaphore( NULL, 0, 1, NULL );
    Requestdonesem = CreateSemaphore( NULL, 0, 1, NULL );
    ReleaseSemaphore( Requestdonesem, 1, NULL ); // signal req done
    hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)ControlFunc, NULL, 0, &tid );
    if (hThread == NULL) {
        MessageBox( NULL, "Error creating thread!", "Stubugger", MB_APPLMODAL+MB_OK );
    }
    while( !Done ) {
        DlgCmd();
    }
    CloseHandle( Requestsem );
    CloseHandle( Requestdonesem );
    DebugFini();
    RunRequest( REQ_BYE );
    MemFini();
    return( 0 );
}

void DlgCmd()
{
    char        buff[256];

    printf( "DBG>" );
    fflush( stdout );
    gets( buff );
    if( buff[0] != '\0' && buff[1] == '\0' ) {
        switch( tolower( buff[0] ) ) {
        case 'u':
            WndAsmInspect( GetCodeDot() );
            break;
        case 's':
            DumpSource();
            break;
        case 'l':
            DumpLocals();
            break;
        case 'i':
            RunRequest( REQ_TRACE_INTO );
            break;
        case 'o':
            RunRequest( REQ_TRACE_OVER );
            break;
        case 'g':
            RunRequest( REQ_GO );
            break;
        case 'x':
            if( _IsOn( SW_REMOTE_LINK ) ) {
                printf( "Can't break remote task!\n" );
            } else {
                HANDLE hmod;
                FARPROC proc;
                hmod = GetModuleHandle( TrpFile );
                proc = GetProcAddress( hmod, (LPSTR)5 );
                if( proc != NULL ) proc();
                CloseHandle( hmod );
            }
            // break the task
            break;
        default:
            printf( "Error - unrecognized command\n" );
        }
    } else {
        DoCmd( DupStr( buff ) );
        DoInput();
    }
}

extern char *DUILoadString( int id )
{
    char        buff[256];
    char        *ret;
    int         size;

    size = LoadString( GetModuleHandle( NULL ), id, buff, sizeof( buff ) );
    buff[size]='\0';
    ret = DbgAlloc( size+1 );
    strcpy( ret, buff );
    return( ret );
}

void DUIMsgBox( char *text )
{
    printf( "MSG %s\n", text );
}

bool DUIDlgTxt( char *text )
{
    printf( "DLG %s\n", text );
    return( TRUE );
}

void DUIInfoBox( char *text )
{
    printf( "INF %s\n", text );
}

void DUIErrorBox( char *text )
{
    printf( "ERR %s\n", text );
}

void DUIStatusText( char *text )
{
    printf( "STA %s\n", text );
}

bool DlgGivenAddr( char *title, address *value )
{
    // needed when segment's don't map (from new/sym command)
    return( FALSE );
}
void DlgNewWithSym( char *text, char *buff, int buff_len )
{
    // used by print command with no arguments
}
bool DlgUpTheStack()
{
    // used when trying to trace, but we've unwound the stack a bit
    return( FALSE );
}
bool DlgAreYouNuts( unsigned long mult )
{
    // used when too many break on write points are set
    return( FALSE );
}
bool DlgBackInTime()
{
    // used when trying to trace, but we've backed up over a call or asynch
    return( FALSE );
}
bool DlgIncompleteUndo()
{
    // used when trying to trace, but we've backed up over a call or asynch
    return( FALSE );
}
bool DlgBreak( address addr )
{
    // used when an error occurs in the break point expression or it is entered wrong
    return( FALSE );
}

bool DUIInfoRelease()
{
    // used when we're low on memory
    return( FALSE );
}
void DUIUpdate( update_list flags )
{
    // flags indicates what conditions have changed.  They should be saved
    // until an appropriate time, then windows updated accordingly
}
void DUIStop()
{
    // close down the UI - we're about to change modes.
}
void DUIFini()
{
    // finish up the UI
}
void DUIInit()
{
    // Init the UI
}
extern void DUIFreshAll()
{
    // refresh all screens - initialization has been done
}
extern bool DUIStopRefresh( bool stop )
{
    // temporarily turn off/on screen refreshing, cause we're going to run a
    // big command file and we don't want flashing.
    return( FALSE );
}
extern void DUIShow()
{
    // show the main screen - the splash page has been closed
}
extern void DUIWndUser()
{
    // switch to the program screen
}

⌨️ 快捷键说明

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