Set thread start address to 0 on events generated by
DebugActiveProcess.
Return a correct address in the simulated exception event.
diff --git a/server/context_i386.c b/server/context_i386.c
index 821b528..52ee132 100644
--- a/server/context_i386.c
+++ b/server/context_i386.c
@@ -458,6 +458,19 @@
/* 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 d704b5f..ccfbd50 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -94,7 +94,7 @@
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 @@
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 @@
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 @@
}
/* 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 @@
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 e106fba..d26b8cc 100644
--- a/server/main.c
+++ b/server/main.c
@@ -86,6 +86,7 @@
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 2040ca4..53cb9dc 100644
--- a/server/object.h
+++ b/server/object.h
@@ -155,7 +155,7 @@
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 342d3b3..eab9801 100644
--- a/server/process.c
+++ b/server/process.c
@@ -656,9 +656,8 @@
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 3bca7c3..e205eaa 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -635,10 +635,9 @@
}
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 54d38a4..d851d46 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -49,7 +49,6 @@
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 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; }