diff --git a/debugger/dbg.y b/debugger/dbg.y index 9cd6849259f..2c18c2bf31e 100644 --- a/debugger/dbg.y +++ b/debugger/dbg.y @@ -52,7 +52,7 @@ int yyerror(char *); %token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN %token tENABLE tDISABLE tBREAK tWATCH tDELETE tSET tMODE tPRINT tEXAM tABORT tVM86 -%token tCLASS tMAPS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL +%token tCLASS tMAPS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL tEXCEPTION %token tPROCESS tTHREAD tMODREF tEOL tEOF %token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE %token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS tSOURCE @@ -248,6 +248,8 @@ walk_command: | tWALK tWND tNUM tEOL { DEBUG_WalkWindows( (HWND)$3, 0 ); } | tWALK tPROCESS tEOL { DEBUG_WalkProcess(); } | tWALK tTHREAD tEOL { DEBUG_WalkThreads(); } + | tWALK tEXCEPTION tEOL { DEBUG_WalkExceptions(DEBUG_CurrTid); } + | tWALK tEXCEPTION tNUM tEOL { DEBUG_WalkExceptions($3); } | tWALK tMODREF expr_value tEOL { DEBUG_WalkModref( $3 ); DEBUG_FreeExprMem(); } ; diff --git a/debugger/debug.l b/debugger/debug.l index c3e09cf6aa6..e8b3212b63e 100644 --- a/debugger/debug.l +++ b/debugger/debug.l @@ -148,6 +148,7 @@ STRING \"[^\n"]+\" process|proces|proce|proc { return tPROCESS; } threads|thread|threa|thre|thr|th { return tTHREAD; } modref|modre|modr { return tMODREF; } +exception|except|exc|ex { return tEXCEPTION; } registers|regs|reg|re { return tREGS; } segments|segment|segm|seg|se { return tSEGMENTS; } stack|stac|sta|st { return tSTACK; } diff --git a/debugger/debugger.h b/debugger/debugger.h index 31da4a8a4e7..5dc26599fc1 100644 --- a/debugger/debugger.h +++ b/debugger/debugger.h @@ -405,6 +405,7 @@ extern void DEBUG_DumpModule(DWORD mod); extern void DEBUG_WalkModules(void); extern void DEBUG_WalkProcess(void); extern void DEBUG_WalkThreads(void); +extern void DEBUG_WalkExceptions(DWORD tid); extern void DEBUG_DumpQueue(DWORD q); extern void DEBUG_WalkQueues(void); extern void DEBUG_InfoSegments(DWORD s, int v); diff --git a/debugger/info.c b/debugger/info.c index 7a450ad92d1..29b3c16da9b 100644 --- a/debugger/info.c +++ b/debugger/info.c @@ -543,6 +543,59 @@ void DEBUG_WalkModref(DWORD p) DEBUG_Printf(DBG_CHN_MESG, "No longer walking module references list\n"); } +/*********************************************************************** + * DEBUG_WalkExceptions + * + * Walk the exception frames of a given thread. + */ +void DEBUG_WalkExceptions(DWORD tid) +{ + DBG_THREAD * thread; + void *next_frame; + + DEBUG_Printf( DBG_CHN_MESG, "Exception frames:\n" ); + + if (tid == DEBUG_CurrTid) thread = DEBUG_CurrThread; + else + { + thread = DEBUG_GetThread(DEBUG_CurrProcess, tid); + + if (!thread) + { + DEBUG_Printf( DBG_CHN_MESG, "Unknown thread id (0x%08lx) in current process\n", tid); + return; + } + if (SuspendThread( thread->handle ) == -1) + { + DEBUG_Printf( DBG_CHN_MESG, "Can't suspend thread id (0x%08lx)\n", tid); + return; + } + } + + if (!DEBUG_READ_MEM(thread->teb, &next_frame, sizeof(next_frame))) + { + DEBUG_Printf( DBG_CHN_MESG, "Can't read TEB:except_frame\n"); + return; + } + + while (next_frame != (void *)-1) + { + EXCEPTION_FRAME frame; + + DEBUG_Printf( DBG_CHN_MESG, "%p: ", next_frame ); + if (!DEBUG_READ_MEM(next_frame, &frame, sizeof(frame))) + { + DEBUG_Printf( DBG_CHN_MESG, "Invalid frame address\n" ); + break; + } + DEBUG_Printf( DBG_CHN_MESG, "prev=%p handler=%p\n", frame.Prev, frame.Handler ); + next_frame = frame.Prev; + } + + if (tid != DEBUG_CurrTid) ResumeThread( thread->handle ); +} + + void DEBUG_InfoSegments(DWORD start, int length) { char flags[3];