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