server: Replace EXCEPTION_RECORD by an explicit definition in debug events.
authorAlexandre Julliard <julliard@winehq.org>
Fri, 2 Jan 2009 19:12:46 +0000 (20:12 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Fri, 2 Jan 2009 19:12:46 +0000 (20:12 +0100)
13 files changed:
dlls/kernel32/debugger.c
dlls/ntdll/exception.c
include/wine/server_protocol.h
server/context_alpha.c
server/context_i386.c
server/context_powerpc.c
server/context_sparc.c
server/context_x86_64.c
server/debugger.c
server/protocol.def
server/thread.c
server/thread.h
server/trace.c

index a6e1bbb72b3e85927dc7b51d1015ffdcf7a163af..6e7b4b1a4db826b80a96866cc7db1c514cba5852 100644 (file)
@@ -50,7 +50,7 @@ BOOL WINAPI WaitForDebugEvent(
     DWORD         timeout)
 {
     BOOL ret;
-    DWORD res;
+    DWORD i, res;
 
     for (;;)
     {
@@ -74,8 +74,14 @@ BOOL WINAPI WaitForDebugEvent(
             switch(data.code)
             {
             case EXCEPTION_DEBUG_EVENT:
-                event->u.Exception.ExceptionRecord = data.exception.record;
-                event->u.Exception.dwFirstChance   = data.exception.first;
+                event->u.Exception.dwFirstChance = data.exception.first;
+                event->u.Exception.ExceptionRecord.ExceptionCode    = data.exception.exc_code;
+                event->u.Exception.ExceptionRecord.ExceptionFlags   = data.exception.flags;
+                event->u.Exception.ExceptionRecord.ExceptionRecord  = wine_server_get_ptr( data.exception.record );
+                event->u.Exception.ExceptionRecord.ExceptionAddress = wine_server_get_ptr( data.exception.address );
+                event->u.Exception.ExceptionRecord.NumberParameters = data.exception.nb_params;
+                for (i = 0; i < data.exception.nb_params; i++)
+                    event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data.exception.params[i];
                 break;
             case CREATE_THREAD_DEBUG_EVENT:
                 event->u.CreateThread.hThread           = wine_server_ptr_handle( data.create_thread.handle );
index d948f84a6bac8ef44fcaeef2d9e5c657a0aeae72..c1c53c37be66199d5a3a4145a37f3931c3025aac 100644 (file)
@@ -188,15 +188,25 @@ void wait_suspend( CONTEXT *context )
 static NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context )
 {
     int ret;
+    DWORD i;
     HANDLE handle = 0;
+    client_ptr_t params[EXCEPTION_MAXIMUM_PARAMETERS];
 
     if (!NtCurrentTeb()->Peb->BeingDebugged) return 0;  /* no debugger present */
 
+    for (i = 0; i < min( rec->NumberParameters, EXCEPTION_MAXIMUM_PARAMETERS ); i++)
+        params[i] = rec->ExceptionInformation[i];
+
     SERVER_START_REQ( queue_exception_event )
     {
         req->first   = first_chance;
+        req->code    = rec->ExceptionCode;
+        req->flags   = rec->ExceptionFlags;
+        req->record  = wine_server_client_ptr( rec->ExceptionRecord );
+        req->address = wine_server_client_ptr( rec->ExceptionAddress );
+        req->len     = i * sizeof(params[0]);
+        wine_server_add_data( req, params, req->len );
         wine_server_add_data( req, context, sizeof(*context) );
-        wine_server_add_data( req, rec, sizeof(*rec) );
         if (!wine_server_call( req )) handle = wine_server_ptr_handle( reply->handle );
     }
     SERVER_END_REQ;
index 4c8ddf37aa7751cf544c9260f7cf3cea8eb0b36c..de80fc2908b75c5de6c0d66632472e03b014d15e 100644 (file)
@@ -61,7 +61,13 @@ typedef union
     {
         int              code;
         int              first;
-        EXCEPTION_RECORD record;
+        unsigned int     exc_code;
+        unsigned int     flags;
+        client_ptr_t     record;
+        client_ptr_t     address;
+        int              nb_params;
+        int              __pad;
+        client_ptr_t     params[15];
     } exception;
     struct
     {
@@ -1851,8 +1857,14 @@ struct wait_debug_event_reply
 struct queue_exception_event_request
 {
     struct request_header __header;
-    int              first;
-    /* VARARG(record,exc_event); */
+    int           first;
+    unsigned int  code;
+    unsigned int  flags;
+    client_ptr_t  record;
+    client_ptr_t  address;
+    data_size_t   len;
+    /* VARARG(params,uints64,len); */
+    /* VARARG(context,context); */
 };
 struct queue_exception_event_reply
 {
@@ -5058,6 +5070,6 @@ union generic_reply
     struct set_window_layered_info_reply set_window_layered_info_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 379
+#define SERVER_PROTOCOL_VERSION 380
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
index 29bd73e3850da57d4fc5c1babe44eb593c85ba14..3aed4f80d8fb97f24f9f8ee4d59c475433d142df 100644 (file)
@@ -327,9 +327,9 @@ void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
 }
 
 /* retrieve the current instruction pointer of a context */
-void *get_context_ip( const CONTEXT *context )
+client_ptr_t get_context_ip( const CONTEXT *context )
 {
-    return (void *)context->Fir;
+    return context->Fir;
 }
 
 /* return the context flag that contains the CPU id */
index 57709fe0491c2cc4c96b1d246008853c843950d1..458b04f316ea4e7b94003bb77735a82bd0f4dde5 100644 (file)
@@ -83,9 +83,9 @@ void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
 }
 
 /* retrieve the current instruction pointer of a context */
-void *get_context_ip( const CONTEXT *context )
+client_ptr_t get_context_ip( const CONTEXT *context )
 {
-    return (void *)context->Eip;
+    return context->Eip;
 }
 
 /* return the context flag that contains the CPU id */
index 5ce63648cd1c0a2e1d19a0e229daec440b4a088d..9825a4a9fb9e694cb57829f48038c4d0ab2665fa 100644 (file)
@@ -265,9 +265,9 @@ void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
 }
 
 /* retrieve the current instruction pointer of a context */
-void *get_context_ip( const CONTEXT *context )
+client_ptr_t get_context_ip( const CONTEXT *context )
 {
-    return (void *)context->Iar;
+    return context->Iar;
 }
 
 /* return the context flag that contains the CPU id */
index 5d70271d0e2aacb768408dfc0878e2c929b726fb..b94d917d53fef976db3850eab8cdb6100d663ae2 100644 (file)
@@ -163,9 +163,9 @@ void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
 }
 
 /* retrieve the current instruction pointer of a context */
-void *get_context_ip( const CONTEXT *context )
+client_ptr_t get_context_ip( const CONTEXT *context )
 {
-    return (void *)context->pc;
+    return context->pc;
 }
 
 /* return the context flag that contains the CPU id */
index e45cbc0e25132f44fd68f1c6a12d2097b95e06fa..264c549e20ba64eb3a99a4ac62c4e07fef961f45 100644 (file)
@@ -83,9 +83,9 @@ void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
 }
 
 /* retrieve the current instruction pointer of a context */
-void *get_context_ip( const CONTEXT *context )
+client_ptr_t get_context_ip( const CONTEXT *context )
 {
-    return (void *)context->Rip;
+    return context->Rip;
 }
 
 /* return the context flag that contains the CPU id */
index 3201d887b170cb97f112067379ca82f8c79a8758..9399cb302d8610ce33b126dc92ebee2e157a9855 100644 (file)
@@ -116,6 +116,7 @@ static int fill_exception_event( struct debug_event *event, const void *arg )
 {
     const debug_event_t *data = arg;
     event->data.exception = data->exception;
+    event->data.exception.nb_params = min( event->data.exception.nb_params, EXCEPTION_MAXIMUM_PARAMETERS );
     return 1;
 }
 
@@ -375,8 +376,7 @@ static int continue_debug_event( struct process *process, struct thread *thread,
 }
 
 /* alloc a debug event for a debugger */
-static struct debug_event *alloc_debug_event( struct thread *thread, int code,
-                                              const void *arg, const CONTEXT *context )
+static struct debug_event *alloc_debug_event( struct thread *thread, int code, const void *arg )
 {
     struct thread *debugger = thread->process->debugger;
     struct debug_event *event;
@@ -399,11 +399,6 @@ static struct debug_event *alloc_debug_event( struct thread *thread, int code,
         return NULL;
     }
     event->data.code = code;
-    if (context)
-    {
-        memcpy( &event->context, context, sizeof(event->context) );
-        thread->context = &event->context;
-    }
     return event;
 }
 
@@ -412,7 +407,7 @@ void generate_debug_event( struct thread *thread, int code, const void *arg )
 {
     if (thread->process->debugger)
     {
-        struct debug_event *event = alloc_debug_event( thread, code, arg, NULL );
+        struct debug_event *event = alloc_debug_event( thread, code, arg );
         if (event)
         {
             link_event( event );
@@ -638,18 +633,32 @@ DECL_HANDLER(queue_exception_event)
     {
         debug_event_t data;
         struct debug_event *event;
-        const CONTEXT *context = get_req_data();
-        const EXCEPTION_RECORD *rec = (const EXCEPTION_RECORD *)(context + 1);
 
-        if (get_req_data_size() < sizeof(*rec) + sizeof(*context))
+        if ((req->len % sizeof(client_ptr_t)) != 0 ||
+            req->len > get_req_data_size() ||
+            req->len > EXCEPTION_MAXIMUM_PARAMETERS * sizeof(client_ptr_t))
         {
             set_error( STATUS_INVALID_PARAMETER );
             return;
         }
-        data.exception.record = *rec;
-        data.exception.first  = req->first;
-        if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data, context )))
+        memset( &data, 0, sizeof(data) );
+        data.exception.first     = req->first;
+        data.exception.exc_code  = req->code;
+        data.exception.flags     = req->flags;
+        data.exception.record    = req->record;
+        data.exception.address   = req->address;
+        data.exception.nb_params = req->len / sizeof(client_ptr_t);
+        memcpy( data.exception.params, get_req_data(), req->len );
+
+        if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data )))
         {
+            const CONTEXT *context = (const CONTEXT *)((char *)get_req_data() + req->len);
+            data_size_t size = get_req_data_size() - req->len;
+
+            memset( &event->context, 0, sizeof(event->context) );
+            memcpy( &event->context, context, size );
+            current->context = &event->context;
+
             if ((reply->handle = alloc_handle( current->process, event, SYNCHRONIZE, 0 )))
             {
                 link_event( event );
index d13ea520f9f2de04e0baaec4b3d7b5515a827bf9..6d6be5bdc5c5ebcc3a77c42106bcbf6425ed0c72 100644 (file)
@@ -75,9 +75,15 @@ typedef union
     int code;   /* event code */
     struct
     {
-        int              code;     /* EXCEPTION_DEBUG_EVENT */
-        int              first;    /* first chance exception? */
-        EXCEPTION_RECORD record;   /* exception record */
+        int              code;       /* EXCEPTION_DEBUG_EVENT */
+        int              first;      /* first chance exception? */
+        unsigned int     exc_code;   /* exception code */
+        unsigned int     flags;      /* exception flags */
+        client_ptr_t     record;     /* exception record */
+        client_ptr_t     address;    /* exception address */
+        int              nb_params;  /* number of parameters */
+        int              __pad;
+        client_ptr_t     params[15]; /* parameters */
     } exception;
     struct
     {
@@ -1450,8 +1456,14 @@ enum char_info_mode
 
 /* Queue an exception event */
 @REQ(queue_exception_event)
-    int              first;    /* first chance exception? */
-    VARARG(record,exc_event);  /* thread context followed by exception record */
+    int           first;       /* first chance exception? */
+    unsigned int  code;        /* exception code */
+    unsigned int  flags;       /* exception flags */
+    client_ptr_t  record;      /* exception record */
+    client_ptr_t  address;     /* exception address */
+    data_size_t   len;         /* size of parameters */
+    VARARG(params,uints64,len);/* exception parameters */
+    VARARG(context,context);   /* thread context */
 @REPLY
     obj_handle_t     handle;   /* handle to the queued event */
 @END
index 6b58785009f386b0fdaa2436bb2a6fca628f0289..397ad9b695dbdcfe1030160248dea66908ef67cc 100644 (file)
@@ -936,12 +936,11 @@ void break_thread( struct thread *thread )
 
     assert( thread->context );
 
-    data.exception.record.ExceptionCode    = STATUS_BREAKPOINT;
-    data.exception.record.ExceptionFlags   = EXCEPTION_CONTINUABLE;
-    data.exception.record.ExceptionRecord  = NULL;
-    data.exception.record.ExceptionAddress = get_context_ip( thread->context );
-    data.exception.record.NumberParameters = 0;
-    data.exception.first = 1;
+    memset( &data, 0, sizeof(data) );
+    data.exception.first     = 1;
+    data.exception.exc_code  = STATUS_BREAKPOINT;
+    data.exception.flags     = EXCEPTION_CONTINUABLE;
+    data.exception.address   = get_context_ip( thread->context );
     generate_debug_event( thread, EXCEPTION_DEBUG_EVENT, &data );
     thread->debug_break = 0;
 }
index e28249988c1ea273320248f985eed4a5689c7ce7..1815f0b1ff82f79f212894a0ecfac312a69c3de1 100644 (file)
@@ -121,7 +121,7 @@ extern struct token *thread_get_impersonation_token( struct thread *thread );
 
 /* CPU context functions */
 extern void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags );
-extern void *get_context_ip( const CONTEXT *context );
+extern client_ptr_t get_context_ip( const CONTEXT *context );
 extern unsigned int get_context_cpu_flag(void);
 extern unsigned int get_context_system_regs( unsigned int flags );
 
index e9af47b40419d26c6a21137f9977211d0d48b382..e30517d67f6f3ecc091ababaf5730118a7a2aa15 100644 (file)
@@ -351,29 +351,30 @@ static void dump_context( const CONTEXT *context, data_size_t size )
 #endif
 }
 
-static void dump_exc_record( const EXCEPTION_RECORD *rec )
+static void dump_varargs_ints( data_size_t size )
 {
-    unsigned int i;
-    fprintf( stderr, "{code=%x,flags=%x,rec=%p,addr=%p,params={",
-             rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionRecord,
-             rec->ExceptionAddress );
-    for (i = 0; i < min(rec->NumberParameters,EXCEPTION_MAXIMUM_PARAMETERS); i++)
+    const int *data = cur_data;
+    data_size_t len = size / sizeof(*data);
+
+    fputc( '{', stderr );
+    while (len > 0)
     {
-        if (i) fputc( ',', stderr );
-        fprintf( stderr, "%lx", rec->ExceptionInformation[i] );
+        fprintf( stderr, "%d", *data++ );
+        if (--len) fputc( ',', stderr );
     }
     fputc( '}', stderr );
+    remove_data( size );
 }
 
-static void dump_varargs_ints( data_size_t size )
+static void dump_varargs_uints64( data_size_t size )
 {
-    const int *data = cur_data;
+    const unsigned __int64 *data = cur_data;
     data_size_t len = size / sizeof(*data);
 
     fputc( '{', stderr );
     while (len > 0)
     {
-        fprintf( stderr, "%d", *data++ );
+        dump_uint64( data++ );
         if (--len) fputc( ',', stderr );
     }
     fputc( '}', stderr );
@@ -462,97 +463,92 @@ static void dump_varargs_context( data_size_t size )
     remove_data( min( size, sizeof(CONTEXT) ));
 }
 
-static void dump_varargs_exc_event( data_size_t size )
-{
-    const CONTEXT *ptr = cur_data;
-
-    if (!size)
-    {
-        fprintf( stderr, "{}" );
-        return;
-    }
-    fprintf( stderr, "{context=" );
-    dump_context( ptr, size );
-    if (size > sizeof(CONTEXT))
-    {
-        fprintf( stderr, ",rec=" );
-        dump_exc_record( (const EXCEPTION_RECORD *)(ptr + 1) );
-    }
-    fputc( '}', stderr );
-    remove_data( size );
-}
-
 static void dump_varargs_debug_event( data_size_t size )
 {
-    const debug_event_t *event = cur_data;
+    debug_event_t event;
+    unsigned int i;
 
     if (!size)
     {
         fprintf( stderr, "{}" );
         return;
     }
-    switch(event->code)
+    size = min( size, sizeof(event) );
+    memset( &event, 0, sizeof(event) );
+    memcpy( &event, cur_data, size );
+
+    switch(event.code)
     {
     case EXCEPTION_DEBUG_EVENT:
-        fprintf( stderr, "{exception," );
-        dump_exc_record( &event->exception.record );
-        fprintf( stderr, ",first=%d}", event->exception.first );
+        fprintf( stderr, "{exception,first=%d,exc_code=%08x,flags=%08x,record=",
+                 event.exception.first, event.exception.exc_code, event.exception.flags );
+        dump_uint64( &event.exception.record );
+        fprintf( stderr, ",address=" );
+        dump_uint64( &event.exception.address );
+        fprintf( stderr, ",params={" );
+        event.exception.nb_params = min( event.exception.nb_params, EXCEPTION_MAXIMUM_PARAMETERS );
+        for (i = 0; i < event.exception.nb_params; i++)
+        {
+            dump_uint64( &event.exception.params[i] );
+            if (i < event.exception.nb_params) fputc( ',', stderr );
+        }
+        fprintf( stderr, "}}" );
         break;
     case CREATE_THREAD_DEBUG_EVENT:
-        fprintf( stderr, "{create_thread,thread=%04x,teb=", event->create_thread.handle );
-        dump_uint64( &event->create_thread.teb );
+        fprintf( stderr, "{create_thread,thread=%04x,teb=", event.create_thread.handle );
+        dump_uint64( &event.create_thread.teb );
         fprintf( stderr, ",start=" );
-        dump_uint64( &event->create_thread.start );
+        dump_uint64( &event.create_thread.start );
         fputc( '}', stderr );
         break;
     case CREATE_PROCESS_DEBUG_EVENT:
         fprintf( stderr, "{create_process,file=%04x,process=%04x,thread=%04x,base=",
-                 event->create_process.file, event->create_process.process,
-                 event->create_process.thread );
-        dump_uint64( &event->create_process.base );
+                 event.create_process.file, event.create_process.process,
+                 event.create_process.thread );
+        dump_uint64( &event.create_process.base );
         fprintf( stderr, ",offset=%d,size=%d,teb=",
-                 event->create_process.dbg_offset, event->create_process.dbg_size );
-        dump_uint64( &event->create_process.teb );
+                 event.create_process.dbg_offset, event.create_process.dbg_size );
+        dump_uint64( &event.create_process.teb );
         fprintf( stderr, ",start=" );
-        dump_uint64( &event->create_process.start );
+        dump_uint64( &event.create_process.start );
         fprintf( stderr, ",name=" );
-        dump_uint64( &event->create_process.name );
-        fprintf( stderr, ",unicode=%d}", event->create_process.unicode );
+        dump_uint64( &event.create_process.name );
+        fprintf( stderr, ",unicode=%d}", event.create_process.unicode );
         break;
     case EXIT_THREAD_DEBUG_EVENT:
-        fprintf( stderr, "{exit_thread,code=%d}", event->exit.exit_code );
+        fprintf( stderr, "{exit_thread,code=%d}", event.exit.exit_code );
         break;
     case EXIT_PROCESS_DEBUG_EVENT:
-        fprintf( stderr, "{exit_process,code=%d}", event->exit.exit_code );
+        fprintf( stderr, "{exit_process,code=%d}", event.exit.exit_code );
         break;
     case LOAD_DLL_DEBUG_EVENT:
-        fprintf( stderr, "{load_dll,file=%04x,base", event->load_dll.handle );
-        dump_uint64( &event->load_dll.base );
+        fprintf( stderr, "{load_dll,file=%04x,base", event.load_dll.handle );
+        dump_uint64( &event.load_dll.base );
         fprintf( stderr, ",offset=%d,size=%d,name=",
-                 event->load_dll.dbg_offset, event->load_dll.dbg_size );
-        dump_uint64( &event->load_dll.name );
-        fprintf( stderr, ",unicode=%d}", event->load_dll.unicode );
+                 event.load_dll.dbg_offset, event.load_dll.dbg_size );
+        dump_uint64( &event.load_dll.name );
+        fprintf( stderr, ",unicode=%d}", event.load_dll.unicode );
         break;
     case UNLOAD_DLL_DEBUG_EVENT:
         fputs( "{unload_dll,base=", stderr );
-        dump_uint64( &event->unload_dll.base );
+        dump_uint64( &event.unload_dll.base );
         fputc( '}', stderr );
         break;
     case OUTPUT_DEBUG_STRING_EVENT:
         fprintf( stderr, "{output_string,string=" );
-        dump_uint64( &event->output_string.string );
+        dump_uint64( &event.output_string.string );
         fprintf( stderr, ",unicode=%d,len=%u}",
-                 event->output_string.unicode, event->output_string.length );
+                 event.output_string.unicode, event.output_string.length );
         break;
     case RIP_EVENT:
         fprintf( stderr, "{rip,err=%d,type=%d}",
-                 event->rip_info.error, event->rip_info.type );
+                 event.rip_info.error, event.rip_info.type );
         break;
     case 0:  /* zero is the code returned on timeouts */
         fprintf( stderr, "{}" );
         break;
     default:
-        fprintf( stderr, "{code=??? (%d)}", event->code );
+        fprintf( stderr, "{code=??? (%d)}", event.code );
         break;
     }
     remove_data( size );
@@ -1975,8 +1971,20 @@ static void dump_wait_debug_event_reply( const struct wait_debug_event_reply *re
 static void dump_queue_exception_event_request( const struct queue_exception_event_request *req )
 {
     fprintf( stderr, " first=%d,", req->first );
+    fprintf( stderr, " code=%08x,", req->code );
+    fprintf( stderr, " flags=%08x,", req->flags );
     fprintf( stderr, " record=" );
-    dump_varargs_exc_event( cur_size );
+    dump_uint64( &req->record );
+    fprintf( stderr, "," );
+    fprintf( stderr, " address=" );
+    dump_uint64( &req->address );
+    fprintf( stderr, "," );
+    fprintf( stderr, " len=%u,", req->len );
+    fprintf( stderr, " params=" );
+    dump_varargs_uints64( min(cur_size,req->len) );
+    fputc( ',', stderr );
+    fprintf( stderr, " context=" );
+    dump_varargs_context( cur_size );
 }
 
 static void dump_queue_exception_event_reply( const struct queue_exception_event_reply *req )