stubdb.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 976 行 · 第 1/2 页
C
976 行
/****************************************************************************
*
* 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.
*
****************************************************************************/
#define INCL_DOS
#include <os2.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 "dbgstk.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( void );
extern void *WndAsmInspect( address addr );
extern void DebugMain( void );
extern void DebugFini( void );
extern void DoInput( void );
extern void UnAsm( address addr, unsigned max, char *buff );
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 void ExprValue( stack_entry * );
extern debug_level DbgLevel;
extern char *TxtBuff;
extern unsigned char CurrRadix;
static bool Done;
extern char *TrpFile;
extern char *CmdData;
extern stack_entry *ExprSP;
unsigned NumLines;
unsigned NumColumns;
char *_LITDOS_invalid_function = "invalid function";
char *_LITDOS_file_not_found = "file not found";
char *_LITDOS_path_not_found = "path not found";
char *_LITDOS_too_many_open_files = "too many open files";
char *_LITDOS_access_denied = "access denied";
char *_LITDOS_invalid_handle = "invalid handle";
char *_LITDOS_memory_control = "memory control";
char *_LITDOS_insufficient_memory = "insufficient memory";
char *_LITDOS_invalid_address = "invalid address";
char *_LITDOS_invalid_environment = "invalid environment";
char *_LITDOS_invalid_format = "invalid format";
char *_LITDOS_invalid_access_code = "invalid access code";
char *_LITDOS_invalid_data = "invalid data";
char *_LITDOS_invalid_drive = "invalid drive";
char *_LITDOS_remove_cd = "remove cd";
char *_LITDOS_not_same_device = "not same device";
void WndMemInit( void )
{
}
void InitScreen( void )
{
}
void FiniScreen( void )
{
}
unsigned ConfigScreen( void )
{
return( 0 );
}
bool DUIClose( void )
{
Done = TRUE;
return( TRUE );
}
// The following routine is cut & pasted verbatim from dbgwvar.c
// (which we really don't want to drag in here)
var_node *VarGetDisplayPiece( var_info *i, int row, int piece, int *pdepth, int *pinherit )
{
var_node *row_v;
var_node *v;
if( piece >= VAR_PIECE_LAST ) return( NULL );
if( VarFirstNode( i ) == NULL ) return( NULL );
if( row >= VarRowTotal( i ) ) return( NULL );
row_v = VarFindRowNode( i, row );
if( !row_v->value_valid ) {
VarSetValue( row_v, LIT( Quest_Marks ) );
row_v->value_valid = FALSE;
}
if( !row_v->gadget_valid ) {
VarSetGadget( row_v, VARGADGET_NONE );
row_v->gadget_valid = FALSE;
}
v = row_v;
if( piece == VAR_PIECE_NAME ||
( piece == VAR_PIECE_GADGET && row_v->gadget_valid ) ||
( piece == VAR_PIECE_VALUE && row_v->value_valid ) ) {
VarError = FALSE;
} else if( !_IsOn( SW_TASK_RUNNING ) ) {
if( row == i->exprsp_cacherow && i->exprsp_cache != NULL ) {
VarError = FALSE;
v = i->exprsp_cache;
} else if( row == i->exprsp_cacherow && i->exprsp_cache_is_error ) {
VarError = TRUE;
v = NULL;
} else {
VarErrState();
v = VarFindRow( i, row );
VarOldErrState();
i->exprsp_cacherow = row;
i->exprsp_cache = v;
i->exprsp_cache_is_error = VarError;
}
if( v == NULL ) {
if( !VarError ) return( NULL );
v = row_v;
}
VarNodeInvalid( v );
VarErrState();
ExprValue( ExprSP );
VarSetGadget( v, VarGetGadget( v ) );
VarSetOnTop( v, VarGetOnTop( v ) );
VarSetValue( v, VarGetValue( i, v ) );
VarOldErrState();
VarDoneRow( i );
}
VarGetDepths( i, v, pdepth, pinherit );
return( v );
}
var_info Locals;
HEV Requestsem;
HEV Requestdonesem;
static void DumpLocals( void )
{
address addr;
int row;
int depth;
int inherit;
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, &inherit );
if( v == NULL ) break;
v = VarGetDisplayPiece( &Locals, row, VAR_PIECE_NAME, &depth, &inherit );
v = VarGetDisplayPiece( &Locals, row, VAR_PIECE_VALUE, &depth, &inherit );
switch( v->gadget ) {
case VARGADGET_NONE:
printf( " " );
break;
case VARGADGET_OPEN:
printf( "+ " );
break;
case VARGADGET_CLOSED:
printf( "- " );
break;
case VARGADGET_POINTS:
printf( "->" );
break;
case VARGADGET_UNPOINTS:
printf( "<-" );
break;
}
VarBuildName( &Locals, v, TRUE );
printf( " %-20s %s\n", TxtBuff, v->value );
}
if( !_IsOn( SW_TASK_RUNNING ) ) {
VarOkToCache( &Locals, FALSE );
VarOldErrState();
}
}
static void DumpSource( void )
{
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;
VOID APIENTRY ControlFunc( ULONG parm )
{
ULONG ulCount;
parm = parm;
do {
DosWaitEventSem( Requestsem, SEM_INDEFINITE_WAIT ); // wait for Request
DosResetEventSem( Requestsem, &ulCount );
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 );
DosPostEventSem( Requestdonesem );
} while( Req != REQ_BYE );
return; // thread over!
}
void RunRequest( int req )
{
ULONG ulCount;
if( _IsOn( SW_TASK_RUNNING ) ) return;
DosWaitEventSem( Requestdonesem, SEM_INDEFINITE_WAIT ); // wait for last request to finish
DosResetEventSem( Requestdonesem, &ulCount );
Req = req;
_SwitchOn( SW_TASK_RUNNING );
DosPostEventSem( Requestsem ); // tell worker to go
}
void DlgCmd( void )
{
char buff[256];
printf( "DBG>" );
fflush( stdout ); // not really necessary
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 {
HMODULE hmod;
PFN proc = NULL;
DosQueryModuleHandle( TrpFile, &hmod );
DosQueryProcAddr( hmod, 5, 0, &proc );
// if( proc != NULL )
// proc();
}
// break the task
break;
default:
printf( "Error - unrecognized command\n" );
}
} else {
DoCmd( DupStr( buff ) );
DoInput();
}
}
int main( int argc, char **argv )
{
char buff[256];
TID tid;
APIRET rc;
MemInit();
getcmd( buff );
CmdData = buff;
DebugMain();
_SwitchOff( SW_ERROR_STARTUP );
DoInput();
VarInitInfo( &Locals );
DosCreateEventSem( NULL, &Requestsem, 0, FALSE );
DosCreateEventSem( NULL, &Requestdonesem, 0, FALSE );
DosPostEventSem( Requestdonesem ); // signal req done
rc = DosCreateThread( &tid, ControlFunc, 0, 0, 32768 );
if( rc != 0 ) {
printf( "Stubugger: Error creating thread!\n" );
}
while( !Done ) {
DlgCmd();
}
DosCloseEventSem( Requestsem );
DosCloseEventSem( Requestdonesem );
DebugFini();
RunRequest( REQ_BYE );
MemFini();
return( 0 );
}
// Minimalist DUI callback routines
extern char *DUILoadString( int id )
{
char buff[256];
char *ret;
int size;
size = WinLoadString( 0, NULLHANDLE, id, sizeof( buff ), buff );
// 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( void )
{
// 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( void )
{
// used when trying to trace, but we've backed up over a call or asynch
return( FALSE );
}
bool DlgIncompleteUndo( void )
{
// 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( void )
{
// 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( void )
{
// close down the UI - we're about to change modes.
}
void DUIFini( void )
{
// finish up the UI
}
void DUIInit( void )
{
// Init the UI
}
extern void DUIFreshAll( void )
{
// 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 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?