Set thread start address to 0 on events generated by
DebugActiveProcess. Return a correct address in the simulated exception event.
This commit is contained in:
parent
f64c404ea6
commit
b73421dd91
|
@ -458,6 +458,19 @@ static void copy_context( CONTEXT *to, CONTEXT *from, int flags )
|
||||||
/* always need to be accessed by ptrace anyway */
|
/* 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 */
|
/* retrieve the current context of a thread */
|
||||||
DECL_HANDLER(get_thread_context)
|
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 )
|
static int fill_create_thread_event( struct debug_event *event, void *arg )
|
||||||
{
|
{
|
||||||
struct process *debugger = event->debugger->process;
|
struct process *debugger = event->debugger->process;
|
||||||
struct thread *thread = arg;
|
struct thread *thread = event->sender;
|
||||||
int handle;
|
int handle;
|
||||||
|
|
||||||
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
|
/* 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;
|
return 0;
|
||||||
event->data.info.create_thread.handle = handle;
|
event->data.info.create_thread.handle = handle;
|
||||||
event->data.info.create_thread.teb = thread->teb;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fill_create_process_event( struct debug_event *event, void *arg )
|
static int fill_create_process_event( struct debug_event *event, void *arg )
|
||||||
{
|
{
|
||||||
struct process *debugger = event->debugger->process;
|
struct process *debugger = event->debugger->process;
|
||||||
struct process *process = arg;
|
struct thread *thread = event->sender;
|
||||||
struct thread *thread = process->thread_list;
|
struct process *process = thread->process;
|
||||||
int handle;
|
int handle;
|
||||||
|
|
||||||
/* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
|
/* 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.file = handle;
|
||||||
event->data.info.create_process.teb = thread->teb;
|
event->data.info.create_process.teb = thread->teb;
|
||||||
event->data.info.create_process.base = process->exe.base;
|
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_offset = process->exe.dbg_offset;
|
||||||
event->data.info.create_process.dbg_size = process->exe.dbg_size;
|
event->data.info.create_process.dbg_size = process->exe.dbg_size;
|
||||||
event->data.info.create_process.name = 0;
|
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 */
|
/* 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 process_dll *dll;
|
||||||
struct thread *thread = process->thread_list;
|
struct thread *thread = process->thread_list;
|
||||||
|
|
||||||
/* generate creation events */
|
/* 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))
|
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) */
|
/* generate dll events (in loading order, i.e. reverse list order) */
|
||||||
for (dll = &process->exe; dll->next; dll = dll->next);
|
for (dll = &process->exe; dll->next; dll = dll->next);
|
||||||
|
@ -559,13 +559,13 @@ DECL_HANDLER(debug_process)
|
||||||
|
|
||||||
if (debugger_attach( process, current ))
|
if (debugger_attach( process, current ))
|
||||||
{
|
{
|
||||||
generate_startup_debug_events( process );
|
generate_startup_debug_events( process, NULL );
|
||||||
resume_process( process );
|
resume_process( process );
|
||||||
|
|
||||||
data.record.ExceptionCode = EXCEPTION_BREAKPOINT;
|
data.record.ExceptionCode = EXCEPTION_BREAKPOINT;
|
||||||
data.record.ExceptionFlags = EXCEPTION_CONTINUABLE;
|
data.record.ExceptionFlags = EXCEPTION_CONTINUABLE;
|
||||||
data.record.ExceptionRecord = NULL;
|
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.record.NumberParameters = 0;
|
||||||
data.first = 1;
|
data.first = 1;
|
||||||
if ((event = queue_debug_event( process->thread_list, EXCEPTION_DEBUG_EVENT, &data )))
|
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 );
|
parse_args( argc, argv );
|
||||||
signal_init();
|
signal_init();
|
||||||
open_master_socket();
|
open_master_socket();
|
||||||
|
setvbuf( stderr, NULL, _IOLBF, 0 );
|
||||||
|
|
||||||
if (debug_level) fprintf( stderr, "Server: starting (pid=%ld)\n", (long) getpid() );
|
if (debug_level) fprintf( stderr, "Server: starting (pid=%ld)\n", (long) getpid() );
|
||||||
select_loop();
|
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 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, void *entry );
|
||||||
extern void debug_exit_thread( struct thread *thread );
|
extern void debug_exit_thread( struct thread *thread );
|
||||||
|
|
||||||
/* mapping functions */
|
/* mapping functions */
|
||||||
|
|
|
@ -656,9 +656,8 @@ DECL_HANDLER(init_process_done)
|
||||||
fatal_protocol_error( current, "init_process_done: no event\n" );
|
fatal_protocol_error( current, "init_process_done: no event\n" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
current->entry = req->entry;
|
|
||||||
process->exe.base = req->module;
|
process->exe.base = req->module;
|
||||||
generate_startup_debug_events( current->process );
|
generate_startup_debug_events( current->process, req->entry );
|
||||||
set_event( process->init_event );
|
set_event( process->init_event );
|
||||||
release_object( process->init_event );
|
release_object( process->init_event );
|
||||||
process->init_event = NULL;
|
process->init_event = NULL;
|
||||||
|
|
|
@ -635,10 +635,9 @@ DECL_HANDLER(init_thread)
|
||||||
}
|
}
|
||||||
current->unix_pid = req->unix_pid;
|
current->unix_pid = req->unix_pid;
|
||||||
current->teb = req->teb;
|
current->teb = req->teb;
|
||||||
current->entry = req->entry;
|
|
||||||
if (current->suspend + current->process->suspend > 0) stop_thread( current );
|
if (current->suspend + current->process->suspend > 0) stop_thread( current );
|
||||||
if (current->process->running_threads > 1)
|
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 */
|
/* terminate a thread */
|
||||||
|
|
|
@ -49,7 +49,6 @@ struct thread
|
||||||
int unix_pid; /* Unix pid of client */
|
int unix_pid; /* Unix pid of client */
|
||||||
CONTEXT *context; /* current context if in an exception handler */
|
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) */
|
|
||||||
int priority; /* priority level */
|
int priority; /* priority level */
|
||||||
int affinity; /* affinity mask */
|
int affinity; /* affinity mask */
|
||||||
int suspend; /* suspend count */
|
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 suspend_for_ptrace( struct thread *thread );
|
||||||
extern int read_thread_int( struct thread *thread, const int *addr, int *data );
|
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 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; }
|
static inline int get_error(void) { return current->error; }
|
||||||
|
|
Loading…
Reference in New Issue