Commit b73421dd authored by Alexandre Julliard's avatar Alexandre Julliard

Set thread start address to 0 on events generated by

DebugActiveProcess. Return a correct address in the simulated exception event.
parent f64c404e
......@@ -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)
{
......
......@@ -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 )))
......
......@@ -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();
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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; }
......
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