Debugger is now called by exception handling.

Added 'pass' command to pass exceptions to the app.
This commit is contained in:
Alexandre Julliard 1999-06-18 18:23:11 +00:00
parent 1eeed68514
commit 410ae4f3e7
7 changed files with 92 additions and 136 deletions

View File

@ -482,7 +482,7 @@ BOOL DEBUG_ShouldContinue( enum exec_mode mode, int * count )
* If we are about to stop, then print out the source line if we
* have it.
*/
if( (mode != EXEC_CONT && mode != EXEC_FINISH) )
if ((mode != EXEC_CONT && mode != EXEC_PASS && mode != EXEC_FINISH))
{
DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &list);
if( list.sourcefile != NULL )
@ -497,7 +497,7 @@ BOOL DEBUG_ShouldContinue( enum exec_mode mode, int * count )
EIP_reg(&DEBUG_context)++;
/* no breakpoint, continue if in continuous mode */
return (mode == EXEC_CONT || mode == EXEC_FINISH);
return (mode == EXEC_CONT || mode == EXEC_PASS || mode == EXEC_FINISH);
}
@ -612,6 +612,7 @@ enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count )
switch(mode)
{
case EXEC_CONT: /* Continuous execution */
case EXEC_PASS: /* Continue, passing exception */
EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
DEBUG_SetBreakpoints( TRUE );
break;

View File

@ -70,7 +70,7 @@ extern void VIRTUAL_Dump(void); /* memory/virtual.c */
struct datatype * type;
}
%token tCONT tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN
%token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN
%token tENABLE tDISABLE tBREAK tDELETE tSET tMODE tPRINT tEXAM tABORT tDEBUGMSG
%token tCLASS tMAPS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL
%token tPROCESS tMODREF
@ -128,6 +128,8 @@ command:
| tHELP tINFO tEOL { DEBUG_HelpInfo(); }
| tCONT tEOL { dbg_exec_count = 1;
dbg_exec_mode = EXEC_CONT; return 0; }
| tPASS tEOL { dbg_exec_count = 1;
dbg_exec_mode = EXEC_PASS; return 0; }
| tCONT tNUM tEOL { dbg_exec_count = $2;
dbg_exec_mode = EXEC_CONT; return 0; }
| tSTEP tEOL { dbg_exec_count = 1;
@ -435,7 +437,7 @@ void mode_command(int newmode)
*
* Debugger main loop.
*/
static void DEBUG_Main( int signal )
static void DEBUG_Main( BOOL is_debug )
{
static int loaded_symbols = 0;
static BOOL frozen = FALSE;
@ -449,7 +451,7 @@ static void DEBUG_Main( int signal )
if (in_debugger)
{
fprintf( stderr, "Segmentation fault inside debugger, exiting.\n" );
fprintf( stderr, " inside debugger, exiting.\n" );
exit(1);
}
in_debugger = TRUE;
@ -457,6 +459,15 @@ static void DEBUG_Main( int signal )
DEBUG_SetBreakpoints( FALSE );
if (!is_debug)
{
if (IS_SELECTOR_SYSTEM(CS_reg(&DEBUG_context)))
fprintf( stderr, " in 32-bit code (0x%08lx).\n", EIP_reg(&DEBUG_context));
else
fprintf( stderr, " in 16-bit code (%04x:%04lx).\n",
(WORD)CS_reg(&DEBUG_context), EIP_reg(&DEBUG_context) );
}
if (!loaded_symbols)
{
loaded_symbols++;
@ -516,8 +527,7 @@ static void DEBUG_Main( int signal )
sleep(1);
#endif
if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( dbg_exec_mode,
&dbg_exec_count ))
if (!is_debug || !DEBUG_ShouldContinue( dbg_exec_mode, &dbg_exec_count ))
{
DBG_ADDR addr;
TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
@ -548,7 +558,7 @@ static void DEBUG_Main( int signal )
DEBUG_DoDisplay();
if (signal != SIGTRAP) /* This is a real crash, dump some info */
if (!is_debug) /* This is a real crash, dump some info */
{
DEBUG_InfoRegisters();
DEBUG_InfoStack();
@ -558,6 +568,7 @@ static void DEBUG_Main( int signal )
if (ES_reg(&DEBUG_context) != DS_reg(&DEBUG_context))
LDT_Print( SELECTOR_TO_ENTRY(ES_reg(&DEBUG_context)), 1 );
}
LDT_Print( SELECTOR_TO_ENTRY(FS_reg(&DEBUG_context)), 1 );
DEBUG_BackTrace();
}
else
@ -569,7 +580,7 @@ static void DEBUG_Main( int signal )
DEBUG_SilentBackTrace();
}
if ((signal != SIGTRAP) ||
if (!is_debug ||
(dbg_exec_mode == EXEC_STEPI_OVER) ||
(dbg_exec_mode == EXEC_STEPI_INSTR))
{
@ -604,7 +615,7 @@ static void DEBUG_Main( int signal )
* if it was used. Otherwise it would have been ignored.
* In any case, we don't mess with it any more.
*/
if( dbg_exec_mode == EXEC_CONT )
if ((dbg_exec_mode == EXEC_CONT) || (dbg_exec_mode == EXEC_PASS))
{
dbg_exec_count = 0;
@ -621,44 +632,72 @@ static void DEBUG_Main( int signal )
}
/***********************************************************************
* DebugBreak (KERNEL.203) (KERNEL32.181)
*/
void DebugBreak16( CONTEXT *regs )
DWORD wine_debugger( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
{
char module[10];
if (!GetModuleName16( GetCurrentTask(), module, sizeof(module) ))
strcpy( module, "???" );
fprintf( stderr, "%s called DebugBreak\n", module );
DEBUG_context = *regs;
DEBUG_Main( SIGTRAP );
}
BOOL is_debug = FALSE;
if (first_chance && !Options.debug) return 0; /* pass to app first */
void ctx_debug( int signal, CONTEXT *regs )
{
DEBUG_context = *regs;
DEBUG_Main( signal );
*regs = DEBUG_context;
}
switch(rec->ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
case EXCEPTION_SINGLE_STEP:
is_debug = TRUE;
break;
case CONTROL_C_EXIT:
if (!Options.debug) exit(0);
break;
}
void wine_debug( int signal, SIGCONTEXT *regs )
{
#if 0
DWORD *stack = (DWORD *)ESP_sig(regs);
*(--stack) = 0;
*(--stack) = 0;
*(--stack) = EH_NONCONTINUABLE;
*(--stack) = EXCEPTION_ACCESS_VIOLATION;
*(--stack) = EIP_sig(regs);
ESP_sig(regs) = (DWORD)stack;
EIP_sig(regs) = (DWORD)RaiseException;
#else
DEBUG_SetSigContext( regs );
DEBUG_Main( signal );
DEBUG_GetSigContext( regs );
#endif
if (!is_debug)
{
/* print some infos */
fprintf( stderr, "%s: ",
first_chance ? "First chance exception" : "Unhandled exception" );
switch(rec->ExceptionCode)
{
case EXCEPTION_INT_DIVIDE_BY_ZERO:
fprintf( stderr, "divide by zero" );
break;
case EXCEPTION_INT_OVERFLOW:
fprintf( stderr, "overflow" );
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
fprintf( stderr, "array bounds " );
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
fprintf( stderr, "illegal instruction" );
break;
case EXCEPTION_STACK_OVERFLOW:
fprintf( stderr, "stack overflow" );
break;
case EXCEPTION_PRIV_INSTRUCTION:
fprintf( stderr, "priviledged instruction" );
break;
case EXCEPTION_ACCESS_VIOLATION:
if (rec->NumberParameters == 2)
fprintf( stderr, "page fault on %s access to 0x%08lx",
rec->ExceptionInformation[0] ? "write" : "read",
rec->ExceptionInformation[1] );
else
fprintf( stderr, "page fault" );
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
fprintf( stderr, "Alignment" );
break;
case CONTROL_C_EXIT:
fprintf( stderr, "^C" );
break;
default:
fprintf( stderr, "%08lx", rec->ExceptionCode );
break;
}
}
DEBUG_context = *context;
DEBUG_Main( is_debug );
*context = DEBUG_context;
return (dbg_exec_mode == EXEC_PASS) ? 0 : DBG_CONTINUE;
}
int yyerror(char * s)

View File

@ -135,6 +135,7 @@ $gs { yylval.reg = REG_GS; return tREG; }
<INITIAL>where|wher|whe { BEGIN(NOCMD); return tBACKTRACE; }
<INITIAL>cont|con|co|c { BEGIN(NOCMD); return tCONT; }
<INITIAL>pass|pas|pa { BEGIN(NOCMD); return tPASS; }
<INITIAL>condition|conditio|conditi|condit|condi|cond { BEGIN(NOCMD); return tCOND; }
<INITIAL>step|ste|st|s { BEGIN(NOCMD); return tSTEP; }
<INITIAL>next|nex|ne|n { BEGIN(NOCMD); return tNEXT; }

View File

@ -124,11 +124,10 @@ void DEBUG_Help(void)
"The commands accepted by the Wine debugger are a reasonable",
"subset of the commands that gdb accepts.",
"The commands currently are:",
" help quit",
" break [*<addr>] delete break bpnum",
" disable bpnum enable bpnum",
" condition <bpnum> [<expr>]",
" help quit",
" condition <bpnum> [<expr>] pass",
" bt cont [N]",
" step [N] next [N]",
" stepi [N] nexti [N]",
@ -140,8 +139,6 @@ void DEBUG_Help(void)
" show dir dir <path>",
" display <expr> undisplay <disnum>",
" delete display <disnum> debugmsg <class>[-+]<type>\n",
"Wine-specific commands:",
" mode [16,32] walk [wnd,class,queue,module,",
" process,modref <pid>]",
" info (see 'help info' for options)\n",

View File

@ -126,77 +126,6 @@ int DEBUG_GetRegister( enum debug_regs reg )
}
/***********************************************************************
* DEBUG_SetSigContext
*
* Set the register values from a sigcontext.
*/
void DEBUG_SetSigContext( const SIGCONTEXT *sigcontext )
{
EAX_reg(&DEBUG_context) = EAX_sig(sigcontext);
EBX_reg(&DEBUG_context) = EBX_sig(sigcontext);
ECX_reg(&DEBUG_context) = ECX_sig(sigcontext);
EDX_reg(&DEBUG_context) = EDX_sig(sigcontext);
ESI_reg(&DEBUG_context) = ESI_sig(sigcontext);
EDI_reg(&DEBUG_context) = EDI_sig(sigcontext);
EBP_reg(&DEBUG_context) = EBP_sig(sigcontext);
EFL_reg(&DEBUG_context) = EFL_sig(sigcontext);
EIP_reg(&DEBUG_context) = EIP_sig(sigcontext);
ESP_reg(&DEBUG_context) = ESP_sig(sigcontext);
CS_reg(&DEBUG_context) = LOWORD(CS_sig(sigcontext));
DS_reg(&DEBUG_context) = LOWORD(DS_sig(sigcontext));
ES_reg(&DEBUG_context) = LOWORD(ES_sig(sigcontext));
SS_reg(&DEBUG_context) = LOWORD(SS_sig(sigcontext));
#ifdef FS_sig
FS_reg(&DEBUG_context) = LOWORD(FS_sig(sigcontext));
#else
GET_FS( FS_reg(&DEBUG_context) );
FS_reg(&DEBUG_context) &= 0xffff;
#endif
#ifdef GS_sig
GS_reg(&DEBUG_context) = LOWORD(GS_sig(sigcontext));
#else
GET_GS( GS_reg(&DEBUG_context) );
GS_reg(&DEBUG_context) &= 0xffff;
#endif
if (ISV86(&DEBUG_context))
V86BASE(&DEBUG_context) = (DWORD) DOSMEM_MemoryBase(0);
}
/***********************************************************************
* DEBUG_GetSigContext
*
* Build a sigcontext from the register values.
*/
void DEBUG_GetSigContext( SIGCONTEXT *sigcontext )
{
EAX_sig(sigcontext) = EAX_reg(&DEBUG_context);
EBX_sig(sigcontext) = EBX_reg(&DEBUG_context);
ECX_sig(sigcontext) = ECX_reg(&DEBUG_context);
EDX_sig(sigcontext) = EDX_reg(&DEBUG_context);
ESI_sig(sigcontext) = ESI_reg(&DEBUG_context);
EDI_sig(sigcontext) = EDI_reg(&DEBUG_context);
EBP_sig(sigcontext) = EBP_reg(&DEBUG_context);
EFL_sig(sigcontext) = EFL_reg(&DEBUG_context);
EIP_sig(sigcontext) = EIP_reg(&DEBUG_context);
ESP_sig(sigcontext) = ESP_reg(&DEBUG_context);
CS_sig(sigcontext) = CS_reg(&DEBUG_context);
DS_sig(sigcontext) = DS_reg(&DEBUG_context);
ES_sig(sigcontext) = ES_reg(&DEBUG_context);
SS_sig(sigcontext) = SS_reg(&DEBUG_context);
#ifdef FS_sig
FS_sig(sigcontext) = FS_reg(&DEBUG_context);
#else
SET_FS( FS_reg(&DEBUG_context) );
#endif
#ifdef GS_sig
GS_sig(sigcontext) = GS_reg(&DEBUG_context);
#else
SET_GS( GS_reg(&DEBUG_context) );
#endif
}
/***********************************************************************
* DEBUG_Flags
*

View File

@ -129,6 +129,7 @@ enum debug_regs
enum exec_mode
{
EXEC_CONT, /* Continuous execution */
EXEC_PASS, /* Continue, passing exception to app */
EXEC_STEP_OVER, /* Stepping over a call to next source line */
EXEC_STEP_INSTR, /* Step to next source line, stepping in if needed */
EXEC_STEPI_OVER, /* Stepping over a call */
@ -255,8 +256,6 @@ extern void DEBUG_SetRegister( enum debug_regs reg, int val );
extern int DEBUG_GetRegister( enum debug_regs reg );
extern void DEBUG_InfoRegisters(void);
extern BOOL DEBUG_ValidateRegisters(void);
extern void DEBUG_SetSigContext( const SIGCONTEXT *sigcontext );
extern void DEBUG_GetSigContext( SIGCONTEXT *sigcontext );
extern int DEBUG_PrintRegister(enum debug_regs reg);
/* debugger/stack.c */
@ -318,16 +317,7 @@ extern void DEBUG_NukePath(void);
extern void DEBUG_Disassemble( const DBG_ADDR *, const DBG_ADDR*, int offset );
/* debugger/dbg.y */
extern void ctx_debug( int signal, CONTEXT *regs );
extern void wine_debug( int signal, SIGCONTEXT *regs );
/* miscemu/instr.c */
extern BOOL INSTR_EmulateInstruction( SIGCONTEXT* );
/* loader/signal.c */
extern void (*fnWINE_Debugger)(int,SIGCONTEXT*);
extern void (*ctx_debug_call)( int, CONTEXT* );
extern BOOL (*fnINSTR_EmulateInstruction)( SIGCONTEXT* );
extern DWORD wine_debugger( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance );
/* Choose your allocator! */
#if 1

View File

@ -17,6 +17,7 @@
#include "thread.h"
#include "task.h"
#include "stackframe.h"
#include "wine/exception.h"
#include "debug.h"
static int MAIN_argc;
@ -139,10 +140,8 @@ int main( int argc, char *argv[] )
if (!MAIN_WineInit( &argc, argv )) return 1;
MAIN_argc = argc; MAIN_argv = argv;
/* Set up debugger/instruction emulation callback routines */
ctx_debug_call = ctx_debug;
fnWINE_Debugger = wine_debug;
fnINSTR_EmulateInstruction = INSTR_EmulateInstruction;
/* Set up debugger hook */
EXC_SetDebugEventHook( wine_debugger );
if (Options.debug)
TASK_AddTaskEntryBreakpoint = DEBUG_AddTaskEntryBreakpoint;