[PATCH 2/2] [WineDbg]: moved into a common function all code dealing with printing information about an exception, and use this function to implement new 'info exception' command

Eric Pouech eric.pouech at orange.fr
Sun Nov 21 15:19:40 CST 2010


(this should make Vincent Povirk happy, from the WineConf talks)

A+
---

 programs/winedbg/dbg.y        |    1 
 programs/winedbg/debugger.h   |    4 +
 programs/winedbg/info.c       |  157 ++++++++++++++++++++++++++++++++++++++++
 programs/winedbg/tgt_active.c |  160 +++--------------------------------------
 4 files changed, 173 insertions(+), 149 deletions(-)


diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y
index 3fec9b7..685ca6c 100644
--- a/programs/winedbg/dbg.y
+++ b/programs/winedbg/dbg.y
@@ -291,6 +291,7 @@ info_command:
     | tINFO tFRAME expr_rvalue  { info_win32_frame_exceptions($3); }
     | tINFO tMAPS               { info_win32_virtual(dbg_curr_pid); }
     | tINFO tMAPS expr_rvalue   { info_win32_virtual($3); }
+    | tINFO tEXCEPTION          { info_win32_exception(); }
     ;
 
 maintenance_command:
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 807a341..eb05cda 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -183,6 +183,9 @@ struct dbg_thread
     struct dbg_breakpoint	step_over_bp;
     char                        name[9];
     BOOL                        in_exception;   /* TRUE if thread stopped with an exception */
+    BOOL                        first_chance;   /* TRUE if thread stopped with a first chance exception
+                                                 *      - only valid when in_exception is TRUE
+                                                 */
     EXCEPTION_RECORD            excpt_record;   /* only valid when in_exception is TRUE */
     struct
     {
@@ -354,6 +357,7 @@ extern void             info_win32_threads(void);
 extern void             info_win32_frame_exceptions(DWORD tid);
 extern void             info_win32_virtual(DWORD pid);
 extern void             info_win32_segments(DWORD start, int length);
+extern void             info_win32_exception(void);
 extern void             info_wine_dbg_channel(BOOL add, const char* chnl, const char* name);
 
   /* memory.c */
diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c
index 844bcbc..8d91cc9 100644
--- a/programs/winedbg/info.c
+++ b/programs/winedbg/info.c
@@ -31,6 +31,7 @@
 #include "winuser.h"
 #include "tlhelp32.h"
 #include "wine/debug.h"
+#include "wine/exception.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
 
@@ -757,3 +758,159 @@ void info_wine_dbg_channel(BOOL turn_on, const char* cls, const char* name)
     if (!done) dbg_printf("Unable to find debug channel %s\n", name);
     else WINE_TRACE("Changed %d channel instances\n", done);
 }
+
+void info_win32_exception(void)
+{
+    const EXCEPTION_RECORD*     rec;
+    ADDRESS64                   addr;
+    char                        hexbuf[MAX_OFFSET_TO_STR_LEN];
+
+    if (!dbg_curr_thread->in_exception)
+    {
+        dbg_printf("Thread isn't in an exception\n");
+        return;
+    }
+    rec = &dbg_curr_thread->excpt_record;
+    memory_get_current_pc(&addr);
+
+    /* print some infos */
+    dbg_printf("%s: ",
+               dbg_curr_thread->first_chance ? "First chance exception" : "Unhandled exception");
+    switch (rec->ExceptionCode)
+    {
+    case EXCEPTION_BREAKPOINT:
+        dbg_printf("breakpoint");
+        break;
+    case EXCEPTION_SINGLE_STEP:
+        dbg_printf("single step");
+        break;
+    case EXCEPTION_INT_DIVIDE_BY_ZERO:
+        dbg_printf("divide by zero");
+        break;
+    case EXCEPTION_INT_OVERFLOW:
+        dbg_printf("overflow");
+        break;
+    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+        dbg_printf("array bounds");
+        break;
+    case EXCEPTION_ILLEGAL_INSTRUCTION:
+        dbg_printf("illegal instruction");
+        break;
+    case EXCEPTION_STACK_OVERFLOW:
+        dbg_printf("stack overflow");
+        break;
+    case EXCEPTION_PRIV_INSTRUCTION:
+        dbg_printf("privileged instruction");
+        break;
+    case EXCEPTION_ACCESS_VIOLATION:
+        if (rec->NumberParameters == 2)
+            dbg_printf("page fault on %s access to 0x%08lx",
+                       rec->ExceptionInformation[0] == EXCEPTION_WRITE_FAULT ? "write" :
+                       rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT ? "execute" : "read",
+                       rec->ExceptionInformation[1]);
+        else
+            dbg_printf("page fault");
+        break;
+    case EXCEPTION_DATATYPE_MISALIGNMENT:
+        dbg_printf("Alignment");
+        break;
+    case DBG_CONTROL_C:
+        dbg_printf("^C");
+        break;
+    case CONTROL_C_EXIT:
+        dbg_printf("^C");
+        break;
+    case STATUS_POSSIBLE_DEADLOCK:
+        {
+            ADDRESS64       recaddr;
+
+            recaddr.Mode   = AddrModeFlat;
+            recaddr.Offset = rec->ExceptionInformation[0];
+
+            dbg_printf("wait failed on critical section ");
+            print_address(&recaddr, FALSE);
+        }
+        break;
+    case EXCEPTION_WINE_STUB:
+        {
+            char dll[32], name[64];
+            memory_get_string(dbg_curr_process,
+                              (void*)rec->ExceptionInformation[0], TRUE, FALSE,
+                              dll, sizeof(dll));
+            if (HIWORD(rec->ExceptionInformation[1]))
+                memory_get_string(dbg_curr_process,
+                                  (void*)rec->ExceptionInformation[1], TRUE, FALSE,
+                                  name, sizeof(name));
+            else
+                sprintf( name, "%ld", rec->ExceptionInformation[1] );
+            dbg_printf("unimplemented function %s.%s called", dll, name);
+        }
+        break;
+    case EXCEPTION_WINE_ASSERTION:
+        dbg_printf("assertion failed");
+        break;
+    case EXCEPTION_VM86_INTx:
+        dbg_printf("interrupt %02lx in vm86 mode", rec->ExceptionInformation[0]);
+        break;
+    case EXCEPTION_VM86_STI:
+        dbg_printf("sti in vm86 mode");
+        break;
+    case EXCEPTION_VM86_PICRETURN:
+        dbg_printf("PIC return in vm86 mode");
+        break;
+    case EXCEPTION_FLT_DENORMAL_OPERAND:
+        dbg_printf("denormal float operand");
+        break;
+    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+        dbg_printf("divide by zero");
+        break;
+    case EXCEPTION_FLT_INEXACT_RESULT:
+        dbg_printf("inexact float result");
+        break;
+    case EXCEPTION_FLT_INVALID_OPERATION:
+        dbg_printf("invalid float operation");
+        break;
+    case EXCEPTION_FLT_OVERFLOW:
+        dbg_printf("floating point overflow");
+        break;
+    case EXCEPTION_FLT_UNDERFLOW:
+        dbg_printf("floating point underflow");
+        break;
+    case EXCEPTION_FLT_STACK_CHECK:
+        dbg_printf("floating point stack check");
+        break;
+    case CXX_EXCEPTION:
+        if(rec->NumberParameters == 3 && rec->ExceptionInformation[0] == CXX_FRAME_MAGIC)
+            dbg_printf("C++ exception(object = 0x%08lx, type = 0x%08lx)",
+                       rec->ExceptionInformation[1], rec->ExceptionInformation[2]);
+        else
+            dbg_printf("C++ exception with strange parameter count %d or magic 0x%08lx",
+                       rec->NumberParameters, rec->ExceptionInformation[0]);
+        break;
+    default:
+        dbg_printf("0x%08x", rec->ExceptionCode);
+        break;
+    }
+    if (rec->ExceptionFlags & EH_STACK_INVALID)
+        dbg_printf(", invalid program stack");
+
+    switch (addr.Mode)
+    {
+    case AddrModeFlat:
+        dbg_printf(" in %d-bit code (%s)",
+                   be_cpu->pointer_size * 8,
+                   memory_offset_to_string(hexbuf, addr.Offset, 0));
+        break;
+    case AddrModeReal:
+        dbg_printf(" in vm86 code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset);
+        break;
+    case AddrMode1616:
+        dbg_printf(" in 16-bit code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset);
+        break;
+    case AddrMode1632:
+        dbg_printf(" in segmented 32-bit code (%04x:%08lx)", addr.Segment, (unsigned long) addr.Offset);
+        break;
+    default: dbg_printf(" bad address");
+    }
+    dbg_printf(".\n");
+}
diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c
index eb25329..376ee22 100644
--- a/programs/winedbg/tgt_active.c
+++ b/programs/winedbg/tgt_active.c
@@ -118,44 +118,18 @@ static unsigned dbg_fetch_context(void)
  * or exception is silently continued(return FALSE)
  * is_debug means the exception is a breakpoint or single step exception
  */
-static unsigned dbg_exception_prolog(BOOL is_debug, BOOL first_chance, const EXCEPTION_RECORD* rec)
+static unsigned dbg_exception_prolog(BOOL is_debug, const EXCEPTION_RECORD* rec)
 {
     ADDRESS64   addr;
     BOOL        is_break;
-    char        hexbuf[MAX_OFFSET_TO_STR_LEN];
 
     memory_get_current_pc(&addr);
     break_suspend_execution();
-    dbg_curr_thread->excpt_record = *rec;
-    dbg_curr_thread->in_exception = TRUE;
-
-    if (!is_debug)
-    {
-        switch (addr.Mode)
-        {
-        case AddrModeFlat:
-            dbg_printf(" in %d-bit code (%s)",
-                       be_cpu->pointer_size * 8,
-                       memory_offset_to_string(hexbuf, addr.Offset, 0));
-            break;
-        case AddrModeReal:
-            dbg_printf(" in vm86 code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset);
-            break;
-        case AddrMode1616:
-            dbg_printf(" in 16-bit code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset);
-            break;
-        case AddrMode1632:
-            dbg_printf(" in segmented 32-bit code (%04x:%08lx)", addr.Segment, (unsigned long) addr.Offset);
-            break;
-        default: dbg_printf(" bad address");
-        }
-	dbg_printf(".\n");
-    }
 
     /* this will resynchronize builtin dbghelp's internal ELF module list */
     SymLoadModule(dbg_curr_process->handle, 0, 0, 0, 0, 0);
 
-    if (is_debug) break_adjust_pc(&addr, rec->ExceptionCode, first_chance, &is_break);
+    if (is_debug) break_adjust_pc(&addr, rec->ExceptionCode, dbg_curr_thread->first_chance, &is_break);
     /*
      * Do a quiet backtrace so that we have an idea of what the situation
      * is WRT the source files.
@@ -285,131 +259,19 @@ static DWORD dbg_handle_exception(const EXCEPTION_RECORD* rec, BOOL first_chance
         return DBG_EXCEPTION_NOT_HANDLED;
     }
 
-    if (!is_debug)
-    {
-        /* print some infos */
-        dbg_printf("%s: ",
-                   first_chance ? "First chance exception" : "Unhandled exception");
-        switch (rec->ExceptionCode)
-        {
-        case EXCEPTION_INT_DIVIDE_BY_ZERO:
-            dbg_printf("divide by zero");
-            break;
-        case EXCEPTION_INT_OVERFLOW:
-            dbg_printf("overflow");
-            break;
-        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
-            dbg_printf("array bounds");
-            break;
-        case EXCEPTION_ILLEGAL_INSTRUCTION:
-            dbg_printf("illegal instruction");
-            break;
-        case EXCEPTION_STACK_OVERFLOW:
-            dbg_printf("stack overflow");
-            break;
-        case EXCEPTION_PRIV_INSTRUCTION:
-            dbg_printf("privileged instruction");
-            break;
-        case EXCEPTION_ACCESS_VIOLATION:
-            if (rec->NumberParameters == 2)
-                dbg_printf("page fault on %s access to 0x%08lx",
-                           rec->ExceptionInformation[0] == EXCEPTION_WRITE_FAULT ? "write" :
-                           rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT ? "execute" : "read",
-                           rec->ExceptionInformation[1]);
-            else
-                dbg_printf("page fault");
-            break;
-        case EXCEPTION_DATATYPE_MISALIGNMENT:
-            dbg_printf("Alignment");
-            break;
-	case DBG_CONTROL_C:
-            dbg_printf("^C");
-            break;
-        case CONTROL_C_EXIT:
-            dbg_printf("^C");
-            break;
-        case STATUS_POSSIBLE_DEADLOCK:
-        {
-            ADDRESS64       addr;
+    dbg_curr_thread->excpt_record = *rec;
+    dbg_curr_thread->in_exception = TRUE;
+    dbg_curr_thread->first_chance = first_chance;
 
-            addr.Mode   = AddrModeFlat;
-            addr.Offset = rec->ExceptionInformation[0];
+    if (!is_debug) info_win32_exception();
 
-            dbg_printf("wait failed on critical section ");
-            print_address(&addr, FALSE);
-        }
-        if (!DBG_IVAR(BreakOnCritSectTimeOut))
-        {
-            dbg_printf("\n");
-            return DBG_EXCEPTION_NOT_HANDLED;
-        }
-        break;
-        case EXCEPTION_WINE_STUB:
-        {
-            char dll[32], name[64];
-            memory_get_string(dbg_curr_process,
-                              (void*)rec->ExceptionInformation[0], TRUE, FALSE,
-                              dll, sizeof(dll));
-            if (HIWORD(rec->ExceptionInformation[1]))
-                memory_get_string(dbg_curr_process,
-                                  (void*)rec->ExceptionInformation[1], TRUE, FALSE,
-                                  name, sizeof(name));
-            else
-                sprintf( name, "%ld", rec->ExceptionInformation[1] );
-            dbg_printf("unimplemented function %s.%s called", dll, name);
-        }
-        break;
-        case EXCEPTION_WINE_ASSERTION:
-            dbg_printf("assertion failed");
-            break;
-        case EXCEPTION_VM86_INTx:
-            dbg_printf("interrupt %02lx in vm86 mode", rec->ExceptionInformation[0]);
-            break;
-        case EXCEPTION_VM86_STI:
-            dbg_printf("sti in vm86 mode");
-            break;
-        case EXCEPTION_VM86_PICRETURN:
-            dbg_printf("PIC return in vm86 mode");
-            break;
-	case EXCEPTION_FLT_DENORMAL_OPERAND:
-            dbg_printf("denormal float operand");
-            break;
-	case EXCEPTION_FLT_DIVIDE_BY_ZERO:
-            dbg_printf("divide by zero");
-            break;
-	case EXCEPTION_FLT_INEXACT_RESULT:
-            dbg_printf("inexact float result");
-            break;
-	case EXCEPTION_FLT_INVALID_OPERATION:
-            dbg_printf("invalid float operation");
-            break;
-	case EXCEPTION_FLT_OVERFLOW:
-            dbg_printf("floating point overflow");
-            break;
-	case EXCEPTION_FLT_UNDERFLOW:
-            dbg_printf("floating point underflow");
-            break;
-	case EXCEPTION_FLT_STACK_CHECK:
-            dbg_printf("floating point stack check");
-            break;
-        case CXX_EXCEPTION:
-            if(rec->NumberParameters == 3 && rec->ExceptionInformation[0] == CXX_FRAME_MAGIC)
-                dbg_printf("C++ exception(object = 0x%08lx, type = 0x%08lx)",
-                           rec->ExceptionInformation[1], rec->ExceptionInformation[2]);
-            else
-                dbg_printf("C++ exception with strange parameter count %d or magic 0x%08lx",
-                           rec->NumberParameters, rec->ExceptionInformation[0]);
-            break;
-        default:
-            dbg_printf("0x%08x", rec->ExceptionCode);
-            break;
-        }
-    }
-    if( (rec->ExceptionFlags & EH_STACK_INVALID) ) {
-        dbg_printf( ", invalid program stack" );
+    if (rec->ExceptionCode == STATUS_POSSIBLE_DEADLOCK && !DBG_IVAR(BreakOnCritSectTimeOut))
+    {
+        dbg_curr_thread->in_exception = FALSE;
+        return DBG_EXCEPTION_NOT_HANDLED;
     }
 
-    if (dbg_exception_prolog(is_debug, first_chance, rec))
+    if (dbg_exception_prolog(is_debug, rec))
     {
 	dbg_interactiveP = TRUE;
         return 0;






More information about the wine-patches mailing list