diff --git a/server/context_i386.c b/server/context_i386.c index 821b5287faa..52ee132c88a 100644 --- a/server/context_i386.c +++ b/server/context_i386.c @@ -458,6 +458,19 @@ static void copy_context( CONTEXT *to, CONTEXT *from, int flags ) /* always need to be accessed by ptrace anyway */ } +/* retrieve the current instruction pointer of a thread */ +void *get_thread_ip( struct thread *thread ) +{ + CONTEXT context; + context.Eip = 0; + if (suspend_for_ptrace( thread )) + { + get_thread_context( thread, CONTEXT_CONTROL, &context ); + resume_thread( thread ); + } + return (void *)context.Eip; +} + /* retrieve the current context of a thread */ DECL_HANDLER(get_thread_context) { diff --git a/server/debugger.c b/server/debugger.c index d704b5fac47..ccfbd502bc1 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -94,7 +94,7 @@ static int fill_exception_event( struct debug_event *event, void *arg ) static int fill_create_thread_event( struct debug_event *event, void *arg ) { struct process *debugger = event->debugger->process; - struct thread *thread = arg; + struct thread *thread = event->sender; int handle; /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */ @@ -102,15 +102,15 @@ static int fill_create_thread_event( struct debug_event *event, void *arg ) return 0; event->data.info.create_thread.handle = handle; event->data.info.create_thread.teb = thread->teb; - event->data.info.create_thread.start = thread->entry; + event->data.info.create_thread.start = arg; return 1; } static int fill_create_process_event( struct debug_event *event, void *arg ) { struct process *debugger = event->debugger->process; - struct process *process = arg; - struct thread *thread = process->thread_list; + struct thread *thread = event->sender; + struct process *process = thread->process; int handle; /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */ @@ -138,7 +138,7 @@ static int fill_create_process_event( struct debug_event *event, void *arg ) event->data.info.create_process.file = handle; event->data.info.create_process.teb = thread->teb; event->data.info.create_process.base = process->exe.base; - event->data.info.create_process.start = thread->entry; + event->data.info.create_process.start = arg; event->data.info.create_process.dbg_offset = process->exe.dbg_offset; event->data.info.create_process.dbg_size = process->exe.dbg_size; event->data.info.create_process.name = 0; @@ -472,15 +472,15 @@ static int debugger_attach( struct process *process, struct thread *debugger ) } /* generate all startup events of a given process */ -void generate_startup_debug_events( struct process *process ) +void generate_startup_debug_events( struct process *process, void *entry ) { struct process_dll *dll; struct thread *thread = process->thread_list; /* generate creation events */ - generate_debug_event( thread, CREATE_PROCESS_DEBUG_EVENT, process ); + generate_debug_event( thread, CREATE_PROCESS_DEBUG_EVENT, entry ); while ((thread = thread->proc_next)) - generate_debug_event( thread, CREATE_THREAD_DEBUG_EVENT, thread ); + generate_debug_event( thread, CREATE_THREAD_DEBUG_EVENT, NULL ); /* generate dll events (in loading order, i.e. reverse list order) */ for (dll = &process->exe; dll->next; dll = dll->next); @@ -559,13 +559,13 @@ DECL_HANDLER(debug_process) if (debugger_attach( process, current )) { - generate_startup_debug_events( process ); + generate_startup_debug_events( process, NULL ); resume_process( process ); data.record.ExceptionCode = EXCEPTION_BREAKPOINT; data.record.ExceptionFlags = EXCEPTION_CONTINUABLE; data.record.ExceptionRecord = NULL; - data.record.ExceptionAddress = process->thread_list->entry; /* FIXME */ + data.record.ExceptionAddress = get_thread_ip( process->thread_list ); data.record.NumberParameters = 0; data.first = 1; if ((event = queue_debug_event( process->thread_list, EXCEPTION_DEBUG_EVENT, &data ))) diff --git a/server/main.c b/server/main.c index e106fba0d61..d26b8cc30f9 100644 --- a/server/main.c +++ b/server/main.c @@ -86,6 +86,7 @@ int main( int argc, char *argv[] ) parse_args( argc, argv ); signal_init(); open_master_socket(); + setvbuf( stderr, NULL, _IOLBF, 0 ); if (debug_level) fprintf( stderr, "Server: starting (pid=%ld)\n", (long) getpid() ); select_loop(); diff --git a/server/object.h b/server/object.h index 2040ca4410a..53cb9dc702b 100644 --- a/server/object.h +++ b/server/object.h @@ -155,7 +155,7 @@ extern int free_console( struct process *process ); 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_startup_debug_events( struct process *process ); +extern void generate_startup_debug_events( struct process *process, void *entry ); extern void debug_exit_thread( struct thread *thread ); /* mapping functions */ diff --git a/server/process.c b/server/process.c index 342d3b35656..eab980118c6 100644 --- a/server/process.c +++ b/server/process.c @@ -656,9 +656,8 @@ DECL_HANDLER(init_process_done) fatal_protocol_error( current, "init_process_done: no event\n" ); return; } - current->entry = req->entry; process->exe.base = req->module; - generate_startup_debug_events( current->process ); + generate_startup_debug_events( current->process, req->entry ); set_event( process->init_event ); release_object( process->init_event ); process->init_event = NULL; diff --git a/server/thread.c b/server/thread.c index 3bca7c3d899..e205eaa5fe0 100644 --- a/server/thread.c +++ b/server/thread.c @@ -635,10 +635,9 @@ 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 ); if (current->process->running_threads > 1) - generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT, current ); + generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT, req->entry ); } /* terminate a thread */ diff --git a/server/thread.h b/server/thread.h index 54d38a44848..d851d462f6f 100644 --- a/server/thread.h +++ b/server/thread.h @@ -49,7 +49,6 @@ struct thread 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 *entry; /* thread entry point (in client address space) */ int priority; /* priority level */ int affinity; /* affinity mask */ int suspend; /* suspend count */ @@ -89,6 +88,7 @@ extern void detach_thread( struct thread *thread, int sig ); extern int suspend_for_ptrace( struct thread *thread ); extern int read_thread_int( struct thread *thread, const int *addr, int *data ); extern int write_thread_int( struct thread *thread, int *addr, int data, unsigned int mask ); +extern void *get_thread_ip( struct thread *thread ); static inline int get_error(void) { return current->error; }