diff --git a/include/process.h b/include/process.h index 249d16f9ae9..045bd78eddb 100644 --- a/include/process.h +++ b/include/process.h @@ -170,8 +170,6 @@ extern void PROCESS_WalkProcess( void ); /* scheduler/debugger.c */ extern DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance, CONTEXT *ctx ); -extern DWORD DEBUG_SendCreateProcessEvent( HFILE file, HMODULE module, void *entry ); -extern DWORD DEBUG_SendCreateThreadEvent( void *entry ); extern DWORD DEBUG_SendLoadDLLEvent( HFILE file, HMODULE module, LPSTR *name ); extern DWORD DEBUG_SendUnloadDLLEvent( HMODULE module ); diff --git a/include/server.h b/include/server.h index 6eb99c356f9..2c5f91cc611 100644 --- a/include/server.h +++ b/include/server.h @@ -165,7 +165,8 @@ struct init_process_request /* Signal the end of the process initialization */ struct init_process_done_request { - IN int dummy; + IN void* module; /* main module base address */ + IN void* entry; /* process entry point */ }; @@ -174,9 +175,7 @@ struct init_thread_request { IN int unix_pid; /* Unix pid of new thread */ IN void* teb; /* TEB of new thread (in thread address space) */ - OUT void* pid; /* process id of the new thread's process */ - OUT void* tid; /* thread id of the new thread */ - OUT int boot; /* is this the boot thread? */ + IN void* entry; /* thread entry point (in thread address space) */ }; @@ -185,7 +184,9 @@ struct init_thread_request /* created thread gets (without having to request it) */ struct get_thread_buffer_request { - IN int dummy; + OUT void* pid; /* process id of the new thread's process */ + OUT void* tid; /* thread id of the new thread */ + OUT int boot; /* is this the boot thread? */ }; diff --git a/scheduler/client.c b/scheduler/client.c index bd097f8c211..27d4d1b06ea 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -453,6 +453,7 @@ int CLIENT_InitServer(void) */ int CLIENT_InitThread(void) { + struct get_thread_buffer_request *first_req; struct init_thread_request *req; TEB *teb = NtCurrentTeb(); int fd; @@ -463,16 +464,17 @@ int CLIENT_InitThread(void) teb->buffer = mmap( 0, teb->buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); close( fd ); if (teb->buffer == (void*)-1) server_perror( "mmap" ); + first_req = teb->buffer; + teb->process->server_pid = first_req->pid; + teb->tid = first_req->tid; + if (first_req->boot) boot_thread_id = teb->tid; + else if (boot_thread_id == teb->tid) boot_thread_id = 0; - req = get_req_buffer(); + req = teb->buffer; req->unix_pid = getpid(); req->teb = teb; - if (server_call( REQ_INIT_THREAD )) return -1; - teb->process->server_pid = req->pid; - teb->tid = req->tid; - if (req->boot) boot_thread_id = req->tid; - else if (boot_thread_id == req->tid) boot_thread_id = 0; - return 0; + req->entry = teb->entry_point; + return server_call_noerr( REQ_INIT_THREAD ); } /*********************************************************************** diff --git a/scheduler/debugger.c b/scheduler/debugger.c index 8a094850dba..f8357d1e78e 100644 --- a/scheduler/debugger.c +++ b/scheduler/debugger.c @@ -6,8 +6,8 @@ #include +#include "winerror.h" #include "process.h" -#include "thread.h" #include "server.h" #include "debugtools.h" @@ -22,7 +22,6 @@ DEFAULT_DEBUG_CHANNEL(debugstr); DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance, CONTEXT *context ) { int i; - DWORD ret = 0; struct send_debug_event_request *req = get_req_buffer(); req->event.code = EXCEPTION_DEBUG_EVENT; @@ -35,58 +34,9 @@ DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance, CONTEX 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( REQ_SEND_DEBUG_EVENT )) - { - ret = req->status; + if (!server_call_noerr( REQ_SEND_DEBUG_EVENT )) *context = req->event.info.exception.context; - } - return ret; -} - - -/********************************************************************** - * DEBUG_SendCreateProcessEvent - * - * Send an CREATE_PROCESS_DEBUG_EVENT event to the current process debugger. - * Must be called from the context of the new process. - */ -DWORD DEBUG_SendCreateProcessEvent( HFILE file, HMODULE module, void *entry ) -{ - DWORD ret = 0; - struct send_debug_event_request *req = get_req_buffer(); - - req->event.code = CREATE_PROCESS_DEBUG_EVENT; - req->event.info.create_process.file = file; - req->event.info.create_process.process = 0; /* will be filled by server */ - req->event.info.create_process.thread = 0; /* will be filled by server */ - req->event.info.create_process.base = (void *)module; - req->event.info.create_process.dbg_offset = 0; /* FIXME */ - req->event.info.create_process.dbg_size = 0; /* FIXME */ - req->event.info.create_process.teb = NtCurrentTeb(); - req->event.info.create_process.start = entry; - req->event.info.create_process.name = 0; /* FIXME */ - req->event.info.create_process.unicode = 0; /* FIXME */ - if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status; - return ret; -} - -/********************************************************************** - * DEBUG_SendCreateThreadEvent - * - * Send an CREATE_THREAD_DEBUG_EVENT event to the current process debugger. - * Must be called from the context of the new thread. - */ -DWORD DEBUG_SendCreateThreadEvent( void *entry ) -{ - DWORD ret = 0; - struct send_debug_event_request *req = get_req_buffer(); - - req->event.code = CREATE_THREAD_DEBUG_EVENT; - req->event.info.create_thread.handle = 0; /* will be filled by server */ - req->event.info.create_thread.teb = NtCurrentTeb(); - req->event.info.create_thread.start = entry; - if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status; - return ret; + return req->status; } @@ -97,7 +47,6 @@ DWORD DEBUG_SendCreateThreadEvent( void *entry ) */ DWORD DEBUG_SendLoadDLLEvent( HFILE file, HMODULE module, LPSTR *name ) { - DWORD ret = 0; struct send_debug_event_request *req = get_req_buffer(); req->event.code = LOAD_DLL_DEBUG_EVENT; @@ -107,8 +56,8 @@ DWORD DEBUG_SendLoadDLLEvent( HFILE file, HMODULE module, LPSTR *name ) req->event.info.load_dll.dbg_size = 0; /* FIXME */ req->event.info.load_dll.name = name; req->event.info.load_dll.unicode = 0; - if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status; - return ret; + server_call_noerr( REQ_SEND_DEBUG_EVENT ); + return req->status; } @@ -119,13 +68,12 @@ DWORD DEBUG_SendLoadDLLEvent( HFILE file, HMODULE module, LPSTR *name ) */ DWORD DEBUG_SendUnloadDLLEvent( HMODULE module ) { - DWORD ret = 0; struct send_debug_event_request *req = get_req_buffer(); req->event.code = UNLOAD_DLL_DEBUG_EVENT; req->event.info.unload_dll.base = (void *)module; - if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status; - return ret; + server_call_noerr( REQ_SEND_DEBUG_EVENT ); + return req->status; } @@ -155,6 +103,9 @@ BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout ) event->dwThreadId = (DWORD)req->tid; switch(req->event.code) { + case 0: /* timeout */ + SetLastError( ERROR_SEM_TIMEOUT ); + return FALSE; case EXCEPTION_DEBUG_EVENT: event->u.Exception.ExceptionRecord.ExceptionCode = req->event.info.exception.code; event->u.Exception.ExceptionRecord.ExceptionFlags = req->event.info.exception.flags; diff --git a/scheduler/process.c b/scheduler/process.c index 56167a65d16..a1b68f70eb6 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -26,7 +26,6 @@ #include "server.h" #include "options.h" #include "callback.h" -#include "debugger.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(process) @@ -371,6 +370,7 @@ BOOL PROCESS_Init( BOOL win32 ) */ void PROCESS_Start(void) { + struct init_process_done_request *req = get_req_buffer(); UINT cmdShow = SW_SHOWNORMAL; LPTHREAD_START_ROUTINE entry = NULL; PDB *pdb = PROCESS_Current(); @@ -452,16 +452,15 @@ void PROCESS_Start(void) PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0, 0 ); /* Signal the parent process to continue */ + req->module = (void *)pModule->module32; + req->entry = entry; server_call( REQ_INIT_PROCESS_DONE ); /* Send all required start-up debugger events */ if ( type == PROC_WIN32 && (pdb->flags & PDB32_DEBUGGED) ) { EnterCriticalSection( &pdb->crit_section ); - - DEBUG_SendCreateProcessEvent( -1 /*FIXME*/, pModule->module32, entry ); MODULE_SendLoadDLLEvents(); - LeaveCriticalSection( &pdb->crit_section ); } @@ -479,10 +478,6 @@ void PROCESS_Start(void) LeaveCriticalSection( &pdb->crit_section ); } - /* If requested, add entry point breakpoint */ - if ( Options.debug || (pdb->flags & PDB32_DEBUGGED) ) - DEBUG_AddTaskEntryBreakpoint( pdb->task ); - /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */ if ( type != PROC_WIN16 && (pdb->flags & PDB32_CONSOLE_PROC)) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0, 0 ); diff --git a/scheduler/thread.c b/scheduler/thread.c index 17310beca75..9082cb874d4 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -276,9 +276,6 @@ static void THREAD_Start(void) PROCESS_CallUserSignalProc( USIG_THREAD_INIT, (DWORD)NtCurrentTeb()->tid, 0 ); PE_InitTls(); MODULE_DllThreadAttach( NULL ); - - if (NtCurrentTeb()->process->flags & PDB32_DEBUGGED) DEBUG_SendCreateThreadEvent( func ); - ExitThread( func( NtCurrentTeb()->entry_arg ) ); } diff --git a/server/debugger.c b/server/debugger.c index 01ce211eb3b..b62d0d393db 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -97,30 +97,43 @@ static int fill_debug_event( struct thread *debugger, struct thread *thread, /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */ THREAD_ALL_ACCESS, FALSE )) == -1) return 0; + event->data.info.create_thread.teb = thread->teb; + event->data.info.create_thread.start = thread->entry; break; case CREATE_PROCESS_DEBUG_EVENT: - if ((handle = event->data.info.create_process.file) != -1) - { - if ((handle = duplicate_handle( thread->process, handle, debugger->process, - GENERIC_READ, FALSE, 0 )) == -1) - return 0; - event->data.info.create_process.file = handle; - } - if ((event->data.info.create_process.process = alloc_handle( debugger->process, thread->process, - /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */ - PROCESS_ALL_ACCESS, FALSE )) == -1) - { - if (handle != -1) close_handle( debugger->process, handle ); + if ((handle = alloc_handle( debugger->process, thread->process, + /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */ + PROCESS_ALL_ACCESS, FALSE )) == -1) return 0; - } - if ((event->data.info.create_process.thread = alloc_handle( debugger->process, thread, + event->data.info.create_process.process = handle; + + if ((handle = alloc_handle( debugger->process, thread, /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */ - THREAD_ALL_ACCESS, FALSE )) == -1) + THREAD_ALL_ACCESS, FALSE )) == -1) { - if (handle != -1) close_handle( debugger->process, handle ); close_handle( debugger->process, event->data.info.create_process.process ); return 0; } + event->data.info.create_process.thread = handle; + + handle = -1; + if (thread->process->exe_file && + ((handle = alloc_handle( debugger->process, thread->process->exe_file, + /* the doc says write access too, but this doesn't seem a good idea */ + GENERIC_READ, FALSE )) == -1)) + { + close_handle( debugger->process, event->data.info.create_process.process ); + close_handle( debugger->process, event->data.info.create_process.thread ); + return 0; + } + event->data.info.create_process.file = handle; + event->data.info.create_process.teb = thread->teb; + event->data.info.create_process.base = thread->process->module; + event->data.info.create_process.start = thread->entry; + event->data.info.create_process.dbg_offset = 0; + event->data.info.create_process.dbg_size = 0; + event->data.info.create_process.name = 0; + event->data.info.create_process.unicode = 0; break; case LOAD_DLL_DEBUG_EVENT: if ((handle = event->data.info.load_dll.handle) != -1) @@ -131,6 +144,15 @@ static int fill_debug_event( struct thread *debugger, struct thread *thread, event->data.info.load_dll.handle = handle; } break; + case EXIT_PROCESS_DEBUG_EVENT: + case EXIT_THREAD_DEBUG_EVENT: + event->data.info.exit.exit_code = thread->exit_code; + break; + case EXCEPTION_DEBUG_EVENT: + case UNLOAD_DLL_DEBUG_EVENT: + case OUTPUT_DEBUG_STRING_EVENT: + case RIP_EVENT: + break; } return 1; } @@ -189,7 +211,6 @@ static void build_wait_debug_reply( struct thread *thread, struct object *obj, i req->event.code = 0; req->pid = 0; req->tid = 0; - thread->error = signaled; } } @@ -330,9 +351,10 @@ static int continue_debug_event( struct process *process, struct thread *thread, } /* queue a debug event for a debugger */ -static struct debug_event *queue_debug_event( struct thread *debugger, struct thread *thread, +static struct debug_event *queue_debug_event( struct thread *thread, int code, debug_event_t *data ) { + struct thread *debugger = thread->process->debugger; struct debug_ctx *debug_ctx = debugger->debug_ctx; struct debug_event *event; @@ -347,7 +369,8 @@ static struct debug_event *queue_debug_event( struct thread *debugger, struct th event->state = EVENT_QUEUED; event->sender = (struct thread *)grab_object( thread ); event->debugger = (struct thread *)grab_object( debugger ); - memcpy( &event->data, data, sizeof(event->data) ); + if (data) memcpy( &event->data, data, sizeof(event->data) ); + event->data.code = code; if (!fill_debug_event( debugger, thread, event )) { @@ -361,6 +384,16 @@ static struct debug_event *queue_debug_event( struct thread *debugger, struct th return event; } +/* generate a debug event from inside the server and queue it */ +void generate_debug_event( struct thread *thread, int code ) +{ + if (thread->process->debugger) + { + struct debug_event *event = queue_debug_event( thread, code, NULL ); + if (event) release_object( event ); + } +} + /* return a pointer to the context in case the thread is inside an exception event */ CONTEXT *get_debug_context( struct thread *thread ) { @@ -409,29 +442,14 @@ int debugger_attach( struct process *process, struct thread *debugger ) } /* a thread is exiting */ -void debug_exit_thread( struct thread *thread, int exit_code ) +void debug_exit_thread( struct thread *thread ) { - struct thread *debugger = thread->process->debugger; - struct debug_ctx *debug_ctx = thread->debug_ctx; - - if (debugger) /* being debugged -> send an event to the debugger */ - { - struct debug_event *event; - debug_event_t exit; - exit.info.exit.exit_code = exit_code; - /* if this is the last thread, send an exit process event */ - exit.code = ((thread->process->running_threads == 1) ? - EXIT_PROCESS_DEBUG_EVENT : EXIT_THREAD_DEBUG_EVENT); - event = queue_debug_event( debugger, thread, &exit ); - if (event) release_object( event ); - } - - if (debug_ctx) /* this thread is a debugger */ + if (thread->debug_ctx) /* this thread is a debugger */ { /* kill all debugged processes */ - kill_debugged_processes( thread, exit_code ); + kill_debugged_processes( thread, thread->exit_code ); + release_object( thread->debug_ctx ); thread->debug_ctx = NULL; - release_object( debug_ctx ); } } @@ -466,27 +484,30 @@ DECL_HANDLER(continue_debug_event) DECL_HANDLER(debug_process) { struct process *process = get_process_from_id( req->pid ); - if (process) + if (!process) return; + if (debugger_attach( process, current )) { - debugger_attach( process, current ); - /* FIXME: should notify the debugged process somehow */ - release_object( process ); + struct thread *thread = process->thread_list; + generate_debug_event( thread, CREATE_PROCESS_DEBUG_EVENT ); + while ((thread = thread->next)) generate_debug_event( thread, CREATE_THREAD_DEBUG_EVENT ); + /* FIXME: load dll + breakpoint exception events */ } + release_object( process ); } /* Send a debug event */ DECL_HANDLER(send_debug_event) { - struct thread *debugger = current->process->debugger; struct debug_event *event; + int code = req->event.code; - if ((req->event.code <= 0) || (req->event.code > RIP_EVENT)) + if ((code <= 0) || (code > RIP_EVENT)) { - fatal_protocol_error( current, "send_debug_event: bad code %d\n", req->event.code ); + fatal_protocol_error( current, "send_debug_event: bad code %d\n", code ); return; } req->status = 0; - if (debugger && ((event = queue_debug_event( debugger, current, &req->event )))) + if (current->process->debugger && ((event = queue_debug_event( current, code, &req->event )))) { /* wait for continue_debug_event */ struct object *obj = &event->obj; diff --git a/server/object.h b/server/object.h index 0a7ad5d1356..3f87b85bd25 100644 --- a/server/object.h +++ b/server/object.h @@ -154,7 +154,8 @@ extern int free_console( struct process *process ); /* debugger functions */ extern int debugger_attach( struct process *process, struct thread *debugger ); -extern void debug_exit_thread( struct thread *thread, int exit_code ); +extern void generate_debug_event( struct thread *thread, int code ); +extern void debug_exit_thread( struct thread *thread ); extern CONTEXT *get_debug_context( struct thread *thread ); /* mapping functions */ diff --git a/server/process.c b/server/process.c index 0dd779df0ac..9d01b5f3303 100644 --- a/server/process.c +++ b/server/process.c @@ -584,6 +584,9 @@ DECL_HANDLER(init_process_done) fatal_protocol_error( current, "init_process_done: no event\n" ); return; } + current->entry = req->entry; + process->module = req->module; + generate_debug_event( current, CREATE_PROCESS_DEBUG_EVENT ); set_event( process->init_event ); release_object( process->init_event ); process->init_event = NULL; diff --git a/server/process.h b/server/process.h index 873aad7f7da..e8e7cc68b54 100644 --- a/server/process.h +++ b/server/process.h @@ -37,6 +37,7 @@ struct process struct event *init_event; /* event for init done */ void *ldt_copy; /* pointer to LDT copy in client addr space */ void *ldt_flags; /* pointer to LDT flags in client addr space */ + void *module; /* main module base address */ struct new_process_request *info; /* startup info (freed after startup) */ }; @@ -66,4 +67,6 @@ extern void kill_process( struct process *process, int exit_code ); extern void kill_debugged_processes( struct thread *debugger, int exit_code ); extern struct process_snapshot *process_snap( int *count ); +static inline void *get_process_id( struct process *process ) { return process; } + #endif /* __WINE_SERVER_PROCESS_H */ diff --git a/server/thread.c b/server/thread.c index b04215893fa..14d7ea649da 100644 --- a/server/thread.c +++ b/server/thread.c @@ -92,25 +92,32 @@ static struct thread *booting_thread; /* allocate the buffer for the communication with the client */ static int alloc_client_buffer( struct thread *thread ) { + struct get_thread_buffer_request *req; int fd; if ((fd = create_anonymous_file()) == -1) return -1; if (ftruncate( fd, MAX_REQUEST_LENGTH ) == -1) goto error; if ((thread->buffer = mmap( 0, MAX_REQUEST_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 )) == (void*)-1) goto error; - return fd; + /* build the first request into the buffer and send it */ + req = thread->buffer; + req->pid = get_process_id( thread->process ); + req->tid = get_thread_id( thread ); + req->boot = (thread == booting_thread); + set_reply_fd( thread, fd ); + send_reply( thread ); + return 1; error: file_set_error(); if (fd != -1) close( fd ); - return -1; + return 0; } /* create a new thread */ struct thread *create_thread( int fd, struct process *process, int suspend ) { struct thread *thread; - int buf_fd; int flags = fcntl( fd, F_GETFL, 0 ); fcntl( fd, F_SETFL, flags | O_NONBLOCK ); @@ -150,11 +157,8 @@ struct thread *create_thread( int fd, struct process *process, int suspend ) first_thread = thread; add_process_thread( process, thread ); - if ((buf_fd = alloc_client_buffer( thread )) == -1) goto error; - set_select_events( &thread->obj, POLLIN ); /* start listening to events */ - set_reply_fd( thread, buf_fd ); /* send the fd to the client */ - send_reply( thread ); + if (!alloc_client_buffer( thread )) goto error; return thread; error: @@ -560,7 +564,9 @@ void kill_thread( struct thread *thread, int exit_code ) if (current == thread) current = NULL; if (debug_level) trace_kill( thread ); if (thread->wait) end_wait( thread ); - debug_exit_thread( thread, exit_code ); + generate_debug_event( thread, (thread->process->running_threads == 1) ? + EXIT_PROCESS_DEBUG_EVENT : EXIT_THREAD_DEBUG_EVENT ); + debug_exit_thread( thread ); abandon_mutexes( thread ); remove_process_thread( thread->process, thread ); wake_up( &thread->obj, 0 ); @@ -623,10 +629,10 @@ DECL_HANDLER(init_thread) } current->unix_pid = req->unix_pid; current->teb = req->teb; + current->entry = req->entry; if (current->suspend + current->process->suspend > 0) stop_thread( current ); - req->pid = current->process; - req->tid = current; - req->boot = (current == booting_thread); + if (current->process->running_threads > 1) + generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT ); } /* terminate a thread */ diff --git a/server/thread.h b/server/thread.h index 5e464938615..9cc088d2553 100644 --- a/server/thread.h +++ b/server/thread.h @@ -48,6 +48,7 @@ struct thread int exit_code; /* thread exit code */ int unix_pid; /* Unix pid of client */ void *teb; /* TEB address (in client address space) */ + void *entry; /* thread entry point (in client address space) */ int priority; /* priority level */ int affinity; /* affinity mask */ int suspend; /* suspend count */ @@ -92,4 +93,6 @@ static inline int get_error(void) { return current->error; } static inline void set_error( int err ) { current->error = err; } static inline void clear_error(void) { set_error(0); } +static inline void *get_thread_id( struct thread *thread ) { return thread; } + #endif /* __WINE_SERVER_THREAD_H */ diff --git a/server/trace.c b/server/trace.c index c38f7dbaf85..79ffa2e19d6 100644 --- a/server/trace.c +++ b/server/trace.c @@ -258,25 +258,26 @@ static void dump_init_process_reply( const struct init_process_request *req ) static void dump_init_process_done_request( const struct init_process_done_request *req ) { - fprintf( stderr, " dummy=%d", req->dummy ); + fprintf( stderr, " module=%p,", req->module ); + fprintf( stderr, " entry=%p", req->entry ); } static void dump_init_thread_request( const struct init_thread_request *req ) { fprintf( stderr, " unix_pid=%d,", req->unix_pid ); - fprintf( stderr, " teb=%p", req->teb ); -} - -static void dump_init_thread_reply( const struct init_thread_request *req ) -{ - fprintf( stderr, " pid=%p,", req->pid ); - fprintf( stderr, " tid=%p,", req->tid ); - fprintf( stderr, " boot=%d", req->boot ); + fprintf( stderr, " teb=%p,", req->teb ); + fprintf( stderr, " entry=%p", req->entry ); } static void dump_get_thread_buffer_request( const struct get_thread_buffer_request *req ) { - fprintf( stderr, " dummy=%d", req->dummy ); +} + +static void dump_get_thread_buffer_reply( const struct get_thread_buffer_request *req ) +{ + fprintf( stderr, " pid=%p,", req->pid ); + fprintf( stderr, " tid=%p,", req->tid ); + fprintf( stderr, " boot=%d", req->boot ); } static void dump_terminate_process_request( const struct terminate_process_request *req ) @@ -1329,8 +1330,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)0, (dump_func)dump_init_process_reply, (dump_func)0, - (dump_func)dump_init_thread_reply, (dump_func)0, + (dump_func)dump_get_thread_buffer_reply, (dump_func)0, (dump_func)0, (dump_func)dump_get_process_info_reply,