SEH logging

Francois Gouget fgouget at free.fr
Mon Apr 16 17:13:31 CDT 2001


   This patch modifies the SEH code so that when an SEH occurs, detailed
description is printed in the log. This is very useful when the SEH code
then goes in an infinite loop (I'm sure Andreas will agree with me), or
the exception is handled by the app but you still want to know what's
up, or no debugger is configured, or if for some reason you don't want
to use the debugger.

   In this implementation exception.c reuses format_exception_msg()
which is normally used to display the dialog box asking whether to debug
the exception or not. Since this is all in ntdll it works.
   I did not feel confortable doing sprintfs in a fixed size buffer
especially in the WINE_STUB case. So I modified format_exception_msg to
do snprintfs instead. Also I consider EXCEPTION_WINE_STUB's to be ERRs,
not just TRACEs. That way you don't have to turn on +seh and rerun your
application if that happens.


Changelog:

 * dlls/ntdll/exception.c,
   win32/except.c
   SEH: Use format_exception_msg to log a description of the exception
   format_exception_msg: Use snprintf to make sure there won't be a
buffer overflow


--
Francois Gouget         fgouget at free.fr        http://fgouget.free.fr/
                         "Utilisateur" (nom commun) :
        Mot utilisé par les informaticiens en lieu et place d'"idiot".

-------------- next part --------------
Index: dlls/ntdll/exception.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/exception.c,v
retrieving revision 1.33
diff -u -r1.33 exception.c
--- dlls/ntdll/exception.c	2001/02/27 02:09:17	1.33
+++ dlls/ntdll/exception.c	2001/04/16 21:48:22
@@ -160,6 +160,8 @@
 }
 
 
+extern int format_exception_msg( const EXCEPTION_POINTERS *ptr, char *buffer, int size );
+
 /***********************************************************************
  *            EXC_RtlRaiseException / RtlRaiseException (NTDLL.464)
  */
@@ -168,9 +170,17 @@
 {
     PEXCEPTION_FRAME frame, dispatch, nested_frame;
     EXCEPTION_RECORD newrec;
+    EXCEPTION_POINTERS epointers;
+    char buffer[256];
     DWORD res;
 
-    TRACE( "code=%lx flags=%lx\n", rec->ExceptionCode, rec->ExceptionFlags );
+    epointers.ExceptionRecord=rec;
+    epointers.ContextRecord=context;
+    format_exception_msg(&epointers,buffer,sizeof(buffer));
+    if (rec->ExceptionCode == EXCEPTION_WINE_STUB)
+        ERR("%s\n",buffer);
+    else
+        TRACE("%s\n",buffer);
 
     if (send_debug_event( rec, TRUE, context ) == DBG_CONTINUE) return;  /* continue execution */
 
Index: win32/except.c
===================================================================
RCS file: /home/wine/wine/win32/except.c,v
retrieving revision 1.43
diff -u -r1.43 except.c
--- win32/except.c	2001/03/20 02:01:10	1.43
+++ win32/except.c	2001/04/16 21:48:49
@@ -69,75 +69,83 @@
 /*******************************************************************
  *         format_exception_msg
  */
-static void format_exception_msg( const EXCEPTION_POINTERS *ptr, char *buffer )
+int format_exception_msg( const EXCEPTION_POINTERS *ptr, char *buffer, int size )
 {
     const EXCEPTION_RECORD *rec = ptr->ExceptionRecord;
+    int len,len2;
 
     switch(rec->ExceptionCode)
     {
     case EXCEPTION_INT_DIVIDE_BY_ZERO:
-        sprintf( buffer, "Unhandled division by zero" );
+        len = snprintf( buffer, size, "Unhandled division by zero" );
         break;
     case EXCEPTION_INT_OVERFLOW:
-        sprintf( buffer, "Unhandled overflow" );
+        len = snprintf( buffer, size, "Unhandled overflow" );
         break;
     case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
-        sprintf( buffer, "Unhandled array bounds" );
+        len = snprintf( buffer, size, "Unhandled array bounds" );
         break;
     case EXCEPTION_ILLEGAL_INSTRUCTION:
-        sprintf( buffer, "Unhandled illegal instruction" );
+        len = snprintf( buffer, size, "Unhandled illegal instruction" );
         break;
     case EXCEPTION_STACK_OVERFLOW:
-        sprintf( buffer, "Unhandled stack overflow" );
+        len = snprintf( buffer, size, "Unhandled stack overflow" );
         break;
     case EXCEPTION_PRIV_INSTRUCTION:
-        sprintf( buffer, "Unhandled priviledged instruction" );
+        len = snprintf( buffer, size, "Unhandled priviledged instruction" );
         break;
     case EXCEPTION_ACCESS_VIOLATION:
         if (rec->NumberParameters == 2)
-            sprintf( buffer, "Unhandled page fault on %s access to 0x%08lx",
+            len = snprintf( buffer, size, "Unhandled page fault on %s access to 0x%08lx",
                      rec->ExceptionInformation[0] ? "write" : "read",
                      rec->ExceptionInformation[1]);
         else
-            sprintf( buffer, "Unhandled page fault");
+            len = snprintf( buffer, size, "Unhandled page fault");
         break;
     case EXCEPTION_DATATYPE_MISALIGNMENT:
-        sprintf( buffer, "Unhandled alignment" );
+        len = snprintf( buffer, size, "Unhandled alignment" );
         break;
     case CONTROL_C_EXIT:
-        sprintf( buffer, "Unhandled ^C");
+        len = snprintf( buffer, size, "Unhandled ^C");
         break;
     case EXCEPTION_CRITICAL_SECTION_WAIT:
-        sprintf( buffer, "Critical section %08lx wait failed",
+        len = snprintf( buffer, size, "Critical section %08lx wait failed",
                  rec->ExceptionInformation[0]);
         break;
     case EXCEPTION_WINE_STUB:
-        sprintf( buffer, "Unimplemented function %s.%s called",
+        len = snprintf( buffer, size, "Unimplemented function %s.%s called",
                  (char *)rec->ExceptionInformation[0], (char *)rec->ExceptionInformation[1] );
         break;
     case EXCEPTION_VM86_INTx:
-        sprintf( buffer, "Unhandled interrupt %02lx in vm86 mode",
+        len = snprintf( buffer, size, "Unhandled interrupt %02lx in vm86 mode",
                  rec->ExceptionInformation[0]);
         break;
     case EXCEPTION_VM86_STI:
-        sprintf( buffer, "Unhandled sti in vm86 mode");
+        len = snprintf( buffer, size, "Unhandled sti in vm86 mode");
         break;
     case EXCEPTION_VM86_PICRETURN:
-        sprintf( buffer, "Unhandled PIC return in vm86 mode");
+        len = snprintf( buffer, size, "Unhandled PIC return in vm86 mode");
         break;
     default:
-        sprintf( buffer, "Unhandled exception 0x%08lx", rec->ExceptionCode);
+        len = snprintf( buffer, size, "Unhandled exception 0x%08lx", rec->ExceptionCode);
         break;
     }
+    if ((len<0) || (len>=size))
+        return -1;
 #ifdef __i386__
     if (ptr->ContextRecord->SegCs != __get_cs())
-        sprintf( buffer+strlen(buffer), " at address 0x%04lx:0x%08lx.\n",
-                 ptr->ContextRecord->SegCs, (DWORD)ptr->ExceptionRecord->ExceptionAddress );
+        len2 = snprintf(buffer+len, size-len,
+                        " at address 0x%04lx:0x%08lx.",
+                        ptr->ContextRecord->SegCs,
+                        (DWORD)ptr->ExceptionRecord->ExceptionAddress);
     else
 #endif
-    sprintf( buffer+strlen(buffer), " at address 0x%08lx.\n",
-             (DWORD)ptr->ExceptionRecord->ExceptionAddress );
-    strcat( buffer, "Do you wish to debug it ?" );
+        len2 = snprintf(buffer+len, size-len,
+                        " at address 0x%08lx.",
+                        (DWORD)ptr->ExceptionRecord->ExceptionAddress);
+    if ((len2<0) || (len>=size-len))
+        return -1;
+    return len+len2;
 }
 
 
@@ -252,8 +260,11 @@
         if (mod) pMessageBoxA = (MessageBoxA_funcptr)GetProcAddress( mod, "MessageBoxA" );
         if (pMessageBoxA)
         {
-            format_exception_msg( epointers, buffer );
-            if (pMessageBoxA( 0, buffer, "Error", MB_YESNO | MB_ICONHAND ) == IDNO)
+            int len;
+            len = format_exception_msg( epointers, buffer, sizeof(buffer) );
+            if (len>0)
+                snprintf(buffer+len,sizeof(buffer)-len,"\nDo you want to debug it?");
+            if (pMessageBoxA( 0, buffer, "Exception raised", MB_YESNO | MB_ICONHAND ) == IDNO)
             {
                 TRACE("Killing process\n");
                 return EXCEPTION_EXECUTE_HANDLER;


More information about the wine-patches mailing list