Commit ea0d028a authored by Alexandre Julliard's avatar Alexandre Julliard

Added specific routines for OUTPUT_DEBUG_STRING and EXCEPTION debug events.

Generate a breakpoint event on process attach. Misc cleanups in request handling.
parent ebd01a94
...@@ -13,9 +13,10 @@ ...@@ -13,9 +13,10 @@
#include "wine/exception.h" #include "wine/exception.h"
#include "stackframe.h" #include "stackframe.h"
#include "miscemu.h" #include "miscemu.h"
#include "server.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(seh) DEFAULT_DEBUG_CHANNEL(seh);
/* Exception record for handling exceptions happening inside exception handlers */ /* Exception record for handling exceptions happening inside exception handlers */
typedef struct typedef struct
...@@ -84,6 +85,22 @@ static DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame, ...@@ -84,6 +85,22 @@ static DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame,
} }
/**********************************************************************
* EXC_SendEvent
*
* Send an EXCEPTION_DEBUG_EVENT event to the debugger.
*/
static inline int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context )
{
struct exception_event_request *req = get_req_buffer();
req->record = *rec;
req->first = first_chance;
req->context = *context;
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *context = req->context;
return req->status;
}
/******************************************************************* /*******************************************************************
* EXC_DefaultHandling * EXC_DefaultHandling
* *
...@@ -91,8 +108,7 @@ static DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame, ...@@ -91,8 +108,7 @@ static DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame,
*/ */
static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context ) static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context )
{ {
if (DEBUG_SendExceptionEvent( rec, FALSE, context ) == DBG_CONTINUE) if (send_debug_event( rec, FALSE, context ) == DBG_CONTINUE) return; /* continue execution */
return; /* continue execution */
if (rec->ExceptionFlags & EH_STACK_INVALID) if (rec->ExceptionFlags & EH_STACK_INVALID)
ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); ERR("Exception frame is not in stack limits => unable to dispatch exception.\n");
...@@ -117,8 +133,7 @@ void WINAPI EXC_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context ) ...@@ -117,8 +133,7 @@ void WINAPI EXC_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context )
TRACE( "code=%lx flags=%lx\n", rec->ExceptionCode, rec->ExceptionFlags ); TRACE( "code=%lx flags=%lx\n", rec->ExceptionCode, rec->ExceptionFlags );
if (DEBUG_SendExceptionEvent( rec, TRUE, context ) == DBG_CONTINUE) if (send_debug_event( rec, TRUE, context ) == DBG_CONTINUE) return; /* continue execution */
return; /* continue execution */
frame = NtCurrentTeb()->except; frame = NtCurrentTeb()->except;
nested_frame = NULL; nested_frame = NULL;
......
...@@ -31,14 +31,8 @@ typedef WCHAR path_t[MAX_PATH+1]; ...@@ -31,14 +31,8 @@ typedef WCHAR path_t[MAX_PATH+1];
/* definitions of the event data depending on the event code */ /* definitions of the event data depending on the event code */
struct debug_event_exception struct debug_event_exception
{ {
int code; /* exception code */ EXCEPTION_RECORD record; /* exception record */
int flags; /* exception flags */ int first; /* first chance exception? */
void *record; /* exception record ptr */
void *addr; /* exception address */
int nb_params; /* exceptions parameters */
int params[15];
int first_chance; /* first chance to handle it? */
CONTEXT context; /* thread context */
}; };
struct debug_event_create_thread struct debug_event_create_thread
{ {
...@@ -813,11 +807,22 @@ struct wait_debug_event_request ...@@ -813,11 +807,22 @@ struct wait_debug_event_request
}; };
/* Send a debug event */ /* Send an exception event */
struct send_debug_event_request struct exception_event_request
{ {
OUT int status; /* event continuation status */ IN EXCEPTION_RECORD record; /* exception record */
IN debug_event_t event; /* debug event data */ IN int first; /* first chance exception? */
IN CONTEXT context; /* thread context */
OUT int status; /* event continuation status */
};
/* Send an output string to the debugger */
struct output_debug_string_request
{
IN void* string; /* string to display (in debugged process address space) */
IN int unicode; /* is it Unicode? */
IN int length; /* string length */
}; };
...@@ -1164,7 +1169,8 @@ enum request ...@@ -1164,7 +1169,8 @@ enum request
REQ_CREATE_SNAPSHOT, REQ_CREATE_SNAPSHOT,
REQ_NEXT_PROCESS, REQ_NEXT_PROCESS,
REQ_WAIT_DEBUG_EVENT, REQ_WAIT_DEBUG_EVENT,
REQ_SEND_DEBUG_EVENT, REQ_EXCEPTION_EVENT,
REQ_OUTPUT_DEBUG_STRING,
REQ_CONTINUE_DEBUG_EVENT, REQ_CONTINUE_DEBUG_EVENT,
REQ_DEBUG_PROCESS, REQ_DEBUG_PROCESS,
REQ_READ_PROCESS_MEMORY, REQ_READ_PROCESS_MEMORY,
...@@ -1196,7 +1202,7 @@ enum request ...@@ -1196,7 +1202,7 @@ enum request
REQ_NB_REQUESTS REQ_NB_REQUESTS
}; };
#define SERVER_PROTOCOL_VERSION 2 #define SERVER_PROTOCOL_VERSION 3
/* ### make_requests end ### */ /* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */ /* Everything above this line is generated automatically by tools/make_requests */
......
...@@ -7,39 +7,12 @@ ...@@ -7,39 +7,12 @@
#include <string.h> #include <string.h>
#include "winerror.h" #include "winerror.h"
#include "process.h"
#include "server.h" #include "server.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(debugstr); DEFAULT_DEBUG_CHANNEL(debugstr);
/**********************************************************************
* DEBUG_SendExceptionEvent
*
* Send an EXCEPTION_DEBUG_EVENT event to the current process debugger.
*/
DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance, CONTEXT *context )
{
int i;
struct send_debug_event_request *req = get_req_buffer();
req->event.code = EXCEPTION_DEBUG_EVENT;
req->event.info.exception.code = rec->ExceptionCode;
req->event.info.exception.flags = rec->ExceptionFlags;
req->event.info.exception.record = rec->ExceptionRecord;
req->event.info.exception.addr = rec->ExceptionAddress;
req->event.info.exception.nb_params = rec->NumberParameters;
req->event.info.exception.first_chance = first_chance;
req->event.info.exception.context = *context;
for (i = 0; i < req->event.info.exception.nb_params; i++)
req->event.info.exception.params[i] = rec->ExceptionInformation[i];
if (!server_call_noerr( REQ_SEND_DEBUG_EVENT ))
*context = req->event.info.exception.context;
return req->status;
}
/****************************************************************************** /******************************************************************************
* WaitForDebugEvent (KERNEL32.720) * WaitForDebugEvent (KERNEL32.720)
* *
...@@ -54,7 +27,6 @@ DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance, CONTEX ...@@ -54,7 +27,6 @@ DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance, CONTEX
BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout ) BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout )
{ {
struct wait_debug_event_request *req = get_req_buffer(); struct wait_debug_event_request *req = get_req_buffer();
int i;
req->timeout = timeout; req->timeout = timeout;
if (server_call( REQ_WAIT_DEBUG_EVENT )) return FALSE; if (server_call( REQ_WAIT_DEBUG_EVENT )) return FALSE;
...@@ -70,14 +42,8 @@ BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout ) ...@@ -70,14 +42,8 @@ BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout )
SetLastError( ERROR_SEM_TIMEOUT ); SetLastError( ERROR_SEM_TIMEOUT );
return FALSE; return FALSE;
case EXCEPTION_DEBUG_EVENT: case EXCEPTION_DEBUG_EVENT:
event->u.Exception.ExceptionRecord.ExceptionCode = req->event.info.exception.code; event->u.Exception.ExceptionRecord = req->event.info.exception.record;
event->u.Exception.ExceptionRecord.ExceptionFlags = req->event.info.exception.flags; event->u.Exception.dwFirstChance = req->event.info.exception.first;
event->u.Exception.ExceptionRecord.ExceptionRecord = req->event.info.exception.record;
event->u.Exception.ExceptionRecord.ExceptionAddress = req->event.info.exception.addr;
event->u.Exception.ExceptionRecord.NumberParameters = req->event.info.exception.nb_params;
for (i = 0; i < req->event.info.exception.nb_params; i++)
event->u.Exception.ExceptionRecord.ExceptionInformation[i] = req->event.info.exception.params[i];
event->u.Exception.dwFirstChance = req->event.info.exception.first_chance;
break; break;
case CREATE_THREAD_DEBUG_EVENT: case CREATE_THREAD_DEBUG_EVENT:
event->u.CreateThread.hThread = req->event.info.create_thread.handle; event->u.CreateThread.hThread = req->event.info.create_thread.handle;
...@@ -158,12 +124,11 @@ BOOL WINAPI DebugActiveProcess( DWORD pid ) ...@@ -158,12 +124,11 @@ BOOL WINAPI DebugActiveProcess( DWORD pid )
*/ */
void WINAPI OutputDebugStringA( LPCSTR str ) void WINAPI OutputDebugStringA( LPCSTR str )
{ {
struct send_debug_event_request *req = get_req_buffer(); struct output_debug_string_request *req = get_req_buffer();
req->event.code = OUTPUT_DEBUG_STRING_EVENT; req->string = (void *)str;
req->event.info.output_string.string = (void *)str; req->unicode = 0;
req->event.info.output_string.unicode = 0; req->length = strlen(str) + 1;
req->event.info.output_string.length = strlen(str) + 1; server_call_noerr( REQ_OUTPUT_DEBUG_STRING );
server_call_noerr( REQ_SEND_DEBUG_EVENT );
TRACE("%s\n", str); TRACE("%s\n", str);
} }
...@@ -173,12 +138,11 @@ void WINAPI OutputDebugStringA( LPCSTR str ) ...@@ -173,12 +138,11 @@ void WINAPI OutputDebugStringA( LPCSTR str )
*/ */
void WINAPI OutputDebugStringW( LPCWSTR str ) void WINAPI OutputDebugStringW( LPCWSTR str )
{ {
struct send_debug_event_request *req = get_req_buffer(); struct output_debug_string_request *req = get_req_buffer();
req->event.code = OUTPUT_DEBUG_STRING_EVENT; req->string = (void *)str;
req->event.info.output_string.string = (void *)str; req->unicode = 1;
req->event.info.output_string.unicode = 1; req->length = (lstrlenW(str) + 1) * sizeof(WCHAR);
req->event.info.output_string.length = (lstrlenW(str) + 1) * sizeof(WCHAR); server_call_noerr( REQ_OUTPUT_DEBUG_STRING );
server_call_noerr( REQ_SEND_DEBUG_EVENT );
TRACE("%s\n", debugstr_w(str)); TRACE("%s\n", debugstr_w(str));
} }
......
...@@ -457,13 +457,12 @@ static void copy_context( CONTEXT *to, CONTEXT *from, int flags ) ...@@ -457,13 +457,12 @@ static void copy_context( CONTEXT *to, CONTEXT *from, int flags )
DECL_HANDLER(get_thread_context) DECL_HANDLER(get_thread_context)
{ {
struct thread *thread; struct thread *thread;
CONTEXT *context;
if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT )))
{ {
if ((context = get_debug_context( thread ))) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( &req->context, context, req->flags ); copy_context( &req->context, thread->context, req->flags );
} }
else else
{ {
...@@ -481,13 +480,12 @@ DECL_HANDLER(get_thread_context) ...@@ -481,13 +480,12 @@ DECL_HANDLER(get_thread_context)
DECL_HANDLER(set_thread_context) DECL_HANDLER(set_thread_context)
{ {
struct thread *thread; struct thread *thread;
CONTEXT *context;
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
{ {
if ((context = get_debug_context( thread ))) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( context, &req->context, req->flags ); copy_context( thread->context, &req->context, req->flags );
} }
else else
{ {
......
...@@ -468,15 +468,17 @@ DECL_HANDLER(alloc_file_handle) ...@@ -468,15 +468,17 @@ DECL_HANDLER(alloc_file_handle)
struct file *file; struct file *file;
req->handle = -1; req->handle = -1;
if ((fd = dup(fd)) != -1) if (current->pass_fd != -1)
{ {
if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 ))) if ((file = create_file_for_fd( current->pass_fd, req->access,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0 )))
{ {
req->handle = alloc_handle( current->process, file, req->access, 0 ); req->handle = alloc_handle( current->process, file, req->access, 0 );
release_object( file ); release_object( file );
} }
current->pass_fd = -1;
} }
else file_set_error(); else set_error( STATUS_INVALID_PARAMETER );
} }
/* get a Unix fd to read from a file */ /* get a Unix fd to read from a file */
......
...@@ -60,7 +60,6 @@ static void sigterm_handler() ...@@ -60,7 +60,6 @@ static void sigterm_handler()
/* initialize signal handling */ /* initialize signal handling */
static void signal_init(void) static void signal_init(void)
{ {
#if 0
if (!debug_level) if (!debug_level)
{ {
switch(fork()) switch(fork())
...@@ -74,7 +73,6 @@ static void signal_init(void) ...@@ -74,7 +73,6 @@ static void signal_init(void)
exit(0); exit(0);
} }
} }
#endif
signal( SIGPIPE, SIG_IGN ); signal( SIGPIPE, SIG_IGN );
signal( SIGHUP, sigterm_handler ); signal( SIGHUP, sigterm_handler );
signal( SIGINT, sigterm_handler ); signal( SIGINT, sigterm_handler );
......
...@@ -153,11 +153,10 @@ extern int free_console( struct process *process ); ...@@ -153,11 +153,10 @@ extern int free_console( struct process *process );
/* debugger functions */ /* debugger functions */
extern int debugger_attach( struct process *process, struct thread *debugger ); extern int set_process_debugger( struct process *process, struct thread *debugger );
extern void generate_debug_event( struct thread *thread, int code, void *arg ); extern void generate_debug_event( struct thread *thread, int code, void *arg );
extern void generate_startup_debug_events( struct process *process ); extern void generate_startup_debug_events( struct process *process );
extern void debug_exit_thread( struct thread *thread ); extern void debug_exit_thread( struct thread *thread );
extern CONTEXT *get_debug_context( struct thread *thread );
/* mapping functions */ /* mapping functions */
......
...@@ -201,9 +201,9 @@ struct thread *create_process( int fd, struct process *parent, ...@@ -201,9 +201,9 @@ struct thread *create_process( int fd, struct process *parent,
/* attach to the debugger if requested */ /* attach to the debugger if requested */
if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
debugger_attach( process, current ); set_process_debugger( process, current );
else if (parent && parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS)) else if (parent && parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
debugger_attach( process, parent->debugger ); set_process_debugger( process, parent->debugger );
release_object( process ); release_object( process );
return thread; return thread;
......
...@@ -127,16 +127,16 @@ static void fatal_perror( const char *err, ... ) ...@@ -127,16 +127,16 @@ static void fatal_perror( const char *err, ... )
} }
/* call a request handler */ /* call a request handler */
static void call_req_handler( struct thread *thread, enum request req, int fd ) static inline void call_req_handler( struct thread *thread, enum request req )
{ {
current = thread; current = thread;
clear_error(); clear_error();
if (debug_level) trace_request( req, fd ); if (debug_level) trace_request( req );
if (req < REQ_NB_REQUESTS) if (req < REQ_NB_REQUESTS)
{ {
req_handlers[req].handler( current->buffer, fd ); req_handlers[req]( current->buffer );
if (current && !current->wait) send_reply( current ); if (current && !current->wait) send_reply( current );
current = NULL; current = NULL;
return; return;
...@@ -186,10 +186,8 @@ void read_request( struct thread *thread ) ...@@ -186,10 +186,8 @@ void read_request( struct thread *thread )
if (ret == sizeof(req)) if (ret == sizeof(req))
{ {
int pass_fd = thread->pass_fd; call_req_handler( thread, req );
thread->pass_fd = -1; thread->pass_fd = -1;
call_req_handler( thread, req, pass_fd );
if (pass_fd != -1) close( pass_fd );
return; return;
} }
if (ret == -1) if (ret == -1)
......
...@@ -126,6 +126,7 @@ struct thread *create_thread( int fd, struct process *process, int suspend ) ...@@ -126,6 +126,7 @@ struct thread *create_thread( int fd, struct process *process, int suspend )
if (!(thread = alloc_object( &thread_ops, fd ))) return NULL; if (!(thread = alloc_object( &thread_ops, fd ))) return NULL;
thread->unix_pid = 0; /* not known yet */ thread->unix_pid = 0; /* not known yet */
thread->context = NULL;
thread->teb = NULL; thread->teb = NULL;
thread->mutex = NULL; thread->mutex = NULL;
thread->debug_ctx = NULL; thread->debug_ctx = NULL;
......
...@@ -47,6 +47,7 @@ struct thread ...@@ -47,6 +47,7 @@ struct thread
int attached; /* is thread attached with ptrace? */ int attached; /* is thread attached with ptrace? */
int exit_code; /* thread exit code */ int exit_code; /* thread exit code */
int unix_pid; /* Unix pid of client */ int unix_pid; /* Unix pid of client */
CONTEXT *context; /* current context if in an exception handler */
void *teb; /* TEB address (in client address space) */ void *teb; /* TEB address (in client address space) */
void *entry; /* thread entry point (in client address space) */ void *entry; /* thread entry point (in client address space) */
int priority; /* priority level */ int priority; /* priority level */
......
...@@ -79,23 +79,28 @@ static void dump_context( const CONTEXT *context ) ...@@ -79,23 +79,28 @@ static void dump_context( const CONTEXT *context )
#endif #endif
} }
static void dump_debug_event_t( const debug_event_t *event ) static void dump_exc_record( const EXCEPTION_RECORD *rec )
{ {
int i; int i;
fprintf( stderr, "{code=%lx,flags=%lx,rec=%p,addr=%p,params={",
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionRecord,
rec->ExceptionAddress );
for (i = 0; i < rec->NumberParameters; i++)
{
if (i) fputc( ',', stderr );
fprintf( stderr, "%lx", rec->ExceptionInformation[i] );
}
fputc( '}', stderr );
}
static void dump_debug_event_t( const debug_event_t *event )
{
switch(event->code) switch(event->code)
{ {
case EXCEPTION_DEBUG_EVENT: case EXCEPTION_DEBUG_EVENT:
fprintf( stderr, "{exception,code=%x,flags=%x,rec=%p,addr=%p,params={", fprintf( stderr, "{exception," );
event->info.exception.code, event->info.exception.flags, dump_exc_record( &event->info.exception.record );
event->info.exception.record, event->info.exception.addr ); fprintf( stderr, ",first=%d}", event->info.exception.first );
for (i = 0; i < event->info.exception.nb_params; i++)
{
if (i) fputc( ',', stderr );
fprintf( stderr, "%x", event->info.exception.params[i] );
}
fprintf( stderr, "},first_chance=%d,context=", event->info.exception.first_chance );
dump_context( &event->info.exception.context );
fputc( '}', stderr );
break; break;
case CREATE_THREAD_DEBUG_EVENT: case CREATE_THREAD_DEBUG_EVENT:
fprintf( stderr, "{create_thread,thread=%d,teb=%p,start=%p}", fprintf( stderr, "{create_thread,thread=%d,teb=%p,start=%p}",
...@@ -927,17 +932,28 @@ static void dump_wait_debug_event_reply( const struct wait_debug_event_request * ...@@ -927,17 +932,28 @@ static void dump_wait_debug_event_reply( const struct wait_debug_event_request *
dump_debug_event_t( &req->event ); dump_debug_event_t( &req->event );
} }
static void dump_send_debug_event_request( const struct send_debug_event_request *req ) static void dump_exception_event_request( const struct exception_event_request *req )
{ {
fprintf( stderr, " event=" ); fprintf( stderr, " record=" );
dump_debug_event_t( &req->event ); dump_exc_record( &req->record );
fprintf( stderr, "," );
fprintf( stderr, " first=%d,", req->first );
fprintf( stderr, " context=" );
dump_context( &req->context );
} }
static void dump_send_debug_event_reply( const struct send_debug_event_request *req ) static void dump_exception_event_reply( const struct exception_event_request *req )
{ {
fprintf( stderr, " status=%d", req->status ); fprintf( stderr, " status=%d", req->status );
} }
static void dump_output_debug_string_request( const struct output_debug_string_request *req )
{
fprintf( stderr, " string=%p,", req->string );
fprintf( stderr, " unicode=%d,", req->unicode );
fprintf( stderr, " length=%d", req->length );
}
static void dump_continue_debug_event_request( const struct continue_debug_event_request *req ) static void dump_continue_debug_event_request( const struct continue_debug_event_request *req )
{ {
fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " pid=%p,", req->pid );
...@@ -1310,7 +1326,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -1310,7 +1326,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_snapshot_request, (dump_func)dump_create_snapshot_request,
(dump_func)dump_next_process_request, (dump_func)dump_next_process_request,
(dump_func)dump_wait_debug_event_request, (dump_func)dump_wait_debug_event_request,
(dump_func)dump_send_debug_event_request, (dump_func)dump_exception_event_request,
(dump_func)dump_output_debug_string_request,
(dump_func)dump_continue_debug_event_request, (dump_func)dump_continue_debug_event_request,
(dump_func)dump_debug_process_request, (dump_func)dump_debug_process_request,
(dump_func)dump_read_process_memory_request, (dump_func)dump_read_process_memory_request,
...@@ -1411,7 +1428,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -1411,7 +1428,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_snapshot_reply, (dump_func)dump_create_snapshot_reply,
(dump_func)dump_next_process_reply, (dump_func)dump_next_process_reply,
(dump_func)dump_wait_debug_event_reply, (dump_func)dump_wait_debug_event_reply,
(dump_func)dump_send_debug_event_reply, (dump_func)dump_exception_event_reply,
(dump_func)0,
(dump_func)0, (dump_func)0,
(dump_func)0, (dump_func)0,
(dump_func)dump_read_process_memory_reply, (dump_func)dump_read_process_memory_reply,
...@@ -1512,7 +1530,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -1512,7 +1530,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_snapshot", "create_snapshot",
"next_process", "next_process",
"wait_debug_event", "wait_debug_event",
"send_debug_event", "exception_event",
"output_debug_string",
"continue_debug_event", "continue_debug_event",
"debug_process", "debug_process",
"read_process_memory", "read_process_memory",
...@@ -1546,7 +1565,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -1546,7 +1565,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
/* ### make_requests end ### */ /* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */ /* Everything above this line is generated automatically by tools/make_requests */
void trace_request( enum request req, int fd ) void trace_request( enum request req )
{ {
current->last_req = req; current->last_req = req;
if (req < REQ_NB_REQUESTS) if (req < REQ_NB_REQUESTS)
...@@ -1556,7 +1575,7 @@ void trace_request( enum request req, int fd ) ...@@ -1556,7 +1575,7 @@ void trace_request( enum request req, int fd )
} }
else else
fprintf( stderr, "%08x: %d(", (unsigned int)current, req ); fprintf( stderr, "%08x: %d(", (unsigned int)current, req );
if (fd != -1) fprintf( stderr, " ) fd=%d\n", fd ); if (current->pass_fd != -1) fprintf( stderr, " ) fd=%d\n", current->pass_fd );
else fprintf( stderr, " )\n" ); else fprintf( stderr, " )\n" );
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"path_t" => "&dump_path_t", "path_t" => "&dump_path_t",
"debug_event_t" => "&dump_debug_event_t", "debug_event_t" => "&dump_debug_event_t",
"CONTEXT" => "&dump_context", "CONTEXT" => "&dump_context",
"EXCEPTION_RECORD" => "&dump_exc_record",
"char[1]" => "\\\"%s\\\"", "char[1]" => "\\\"%s\\\"",
"WCHAR[1]" => "&dump_unicode_string" "WCHAR[1]" => "&dump_unicode_string"
); );
...@@ -80,13 +81,11 @@ my @request_lines = (); ...@@ -80,13 +81,11 @@ my @request_lines = ();
foreach $req (@requests) { push @request_lines, "DECL_HANDLER($req);\n"; } foreach $req (@requests) { push @request_lines, "DECL_HANDLER($req);\n"; }
push @request_lines, "\n#ifdef WANT_REQUEST_HANDLERS\n\n"; push @request_lines, "\n#ifdef WANT_REQUEST_HANDLERS\n\n";
push @request_lines, "static const struct handler {\n"; push @request_lines, "typedef void (*req_handler)( void *req );\n";
push @request_lines, " void (*handler)( void *req, int fd );\n"; push @request_lines, "static const req_handler req_handlers[REQ_NB_REQUESTS] =\n{\n";
push @request_lines, " unsigned int min_size;\n";
push @request_lines, "} req_handlers[REQ_NB_REQUESTS] = {\n";
foreach $req (@requests) foreach $req (@requests)
{ {
push @request_lines, " { (void(*)())req_$req, sizeof(struct ${req}_request) },\n"; push @request_lines, " (req_handler)req_$req,\n";
} }
push @request_lines, "};\n#endif /* WANT_REQUEST_HANDLERS */\n"; push @request_lines, "};\n#endif /* WANT_REQUEST_HANDLERS */\n";
......
...@@ -34,9 +34,10 @@ ...@@ -34,9 +34,10 @@
#include "process.h" #include "process.h"
#include "thread.h" #include "thread.h"
#include "stackframe.h" #include "stackframe.h"
#include "server.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(seh) DEFAULT_DEBUG_CHANNEL(seh);
/******************************************************************* /*******************************************************************
...@@ -69,12 +70,16 @@ void WINAPI RaiseException( DWORD code, DWORD flags, DWORD nbargs, const LPDWORD ...@@ -69,12 +70,16 @@ void WINAPI RaiseException( DWORD code, DWORD flags, DWORD nbargs, const LPDWORD
*/ */
DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers) DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
{ {
struct exception_event_request *req = get_req_buffer();
char message[80]; char message[80];
PDB *pdb = PROCESS_Current(); PDB *pdb = PROCESS_Current();
if (DEBUG_SendExceptionEvent( epointers->ExceptionRecord, FALSE, /* send a last chance event to the debugger */
epointers->ContextRecord ) == DBG_CONTINUE) req->record = *epointers->ExceptionRecord;
return EXCEPTION_CONTINUE_EXECUTION; req->first = 0;
req->context = *epointers->ContextRecord;
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *epointers->ContextRecord = req->context;
if (req->status == DBG_CONTINUE) return EXCEPTION_CONTINUE_EXECUTION;
if (pdb->top_filter) if (pdb->top_filter)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment