server: Don't store the debug object in the debugger thread.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7999af8244
commit
2b6426da65
|
@ -1727,15 +1727,29 @@ static DWORD run_child_wait( char *cmd, HANDLE event )
|
|||
return exit_code;
|
||||
}
|
||||
|
||||
static PROCESS_INFORMATION pi;
|
||||
static char *cmd;
|
||||
|
||||
static DWORD WINAPI debug_and_exit(void *arg)
|
||||
{
|
||||
STARTUPINFOA si = { sizeof(si) };
|
||||
BOOL ret;
|
||||
|
||||
ret = CreateProcessA(NULL, cmd, NULL, NULL, TRUE, DEBUG_PROCESS, NULL, NULL, &si, &pi);
|
||||
ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError());
|
||||
Sleep(200);
|
||||
*(HANDLE *)arg = pDbgUiGetThreadDebugObject();
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
static void test_kill_on_exit(const char *argv0)
|
||||
{
|
||||
static const char arguments[] = " debugger wait ";
|
||||
SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
|
||||
OBJECT_ATTRIBUTES attr = { sizeof(attr) };
|
||||
NTSTATUS status;
|
||||
HANDLE event, debug;
|
||||
DWORD exit_code;
|
||||
char *cmd;
|
||||
HANDLE event, debug, thread;
|
||||
DWORD exit_code, tid;
|
||||
ULONG val;
|
||||
|
||||
event = CreateEventW(&sa, FALSE, FALSE, NULL);
|
||||
|
@ -1784,6 +1798,26 @@ static void test_kill_on_exit(const char *argv0)
|
|||
exit_code = run_child_wait( cmd, event );
|
||||
ok( exit_code == STATUS_DEBUGGER_INACTIVE, "exit code = %08x\n", exit_code);
|
||||
|
||||
/* test that threads don't close the debug port on exit */
|
||||
thread = CreateThread(NULL, 0, debug_and_exit, &debug, 0, &tid);
|
||||
WaitForSingleObject( thread, 1000 );
|
||||
ok( debug != 0, "no debug port\n" );
|
||||
SetEvent( event );
|
||||
WaitForSingleObject( pi.hProcess, 100 );
|
||||
GetExitCodeProcess( pi.hProcess, &exit_code );
|
||||
ok( exit_code == STILL_ACTIVE, "exit code = %08x\n", exit_code);
|
||||
val = 0;
|
||||
status = pNtSetInformationDebugObject( debug, DebugObjectKillProcessOnExitInformation,
|
||||
&val, sizeof(val), NULL );
|
||||
ok( !status, "NtSetInformationDebugObject failed %x\n", status );
|
||||
CloseHandle( debug );
|
||||
WaitForSingleObject( pi.hProcess, 1000 );
|
||||
GetExitCodeProcess( pi.hProcess, &exit_code );
|
||||
ok( exit_code == 0, "exit code = %08x\n", exit_code);
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
CloseHandle( thread );
|
||||
|
||||
heap_free(cmd);
|
||||
}
|
||||
|
||||
|
|
|
@ -488,7 +488,6 @@ static int debugger_attach( struct process *process, struct thread *debugger, st
|
|||
struct thread *renderer = console_get_renderer(debugger->process->console);
|
||||
if (renderer && renderer->process == process) goto error;
|
||||
}
|
||||
if (!debugger->debug_obj) debugger->debug_obj = (struct debug_obj *)grab_object( debug_obj );
|
||||
|
||||
suspend_process( process );
|
||||
|
||||
|
@ -568,20 +567,6 @@ void generate_startup_debug_events( struct process *process, client_ptr_t entry
|
|||
}
|
||||
}
|
||||
|
||||
/* a thread is exiting */
|
||||
void debug_exit_thread( struct thread *thread )
|
||||
{
|
||||
struct debug_obj *debug_obj = thread->debug_obj;
|
||||
|
||||
if (debug_obj) /* this thread is a debugger */
|
||||
{
|
||||
detach_debugged_processes( debug_obj,
|
||||
(debug_obj->flags & DEBUG_KILL_ON_CLOSE) ? STATUS_DEBUGGER_INACTIVE : 0 );
|
||||
release_object( thread->debug_obj );
|
||||
thread->debug_obj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* create a debug object */
|
||||
DECL_HANDLER(create_debug_obj)
|
||||
{
|
||||
|
|
|
@ -215,7 +215,6 @@ extern void sock_init(void);
|
|||
extern void generate_debug_event( struct thread *thread, int code, const void *arg );
|
||||
extern void resume_delayed_debug_events( struct thread *thread );
|
||||
extern void generate_startup_debug_events( struct process *process, client_ptr_t entry );
|
||||
extern void debug_exit_thread( struct thread *thread );
|
||||
|
||||
/* registry functions */
|
||||
|
||||
|
|
|
@ -1261,7 +1261,6 @@ DECL_HANDLER(new_process)
|
|||
{
|
||||
process->debug_obj = debug_obj;
|
||||
process->debug_children = !(req->create_flags & DEBUG_ONLY_THIS_PROCESS);
|
||||
if (!current->debug_obj) current->debug_obj = (struct debug_obj *)grab_object( debug_obj );
|
||||
}
|
||||
else if (parent->debug_children)
|
||||
{
|
||||
|
|
|
@ -221,7 +221,6 @@ static inline void init_thread_structure( struct thread *thread )
|
|||
thread->context = NULL;
|
||||
thread->teb = 0;
|
||||
thread->entry_point = 0;
|
||||
thread->debug_obj = NULL;
|
||||
thread->system_regs = 0;
|
||||
thread->queue = NULL;
|
||||
thread->wait = NULL;
|
||||
|
@ -429,7 +428,6 @@ static void destroy_thread( struct object *obj )
|
|||
struct thread *thread = (struct thread *)obj;
|
||||
assert( obj->ops == &thread_ops );
|
||||
|
||||
assert( !thread->debug_obj ); /* cannot still be debugging something */
|
||||
list_remove( &thread->entry );
|
||||
cleanup_thread( thread );
|
||||
release_object( thread->process );
|
||||
|
@ -1266,7 +1264,6 @@ void kill_thread( struct thread *thread, int violent_death )
|
|||
violent_death = 0;
|
||||
}
|
||||
kill_console_processes( thread, 0 );
|
||||
debug_exit_thread( thread );
|
||||
abandon_mutexes( thread );
|
||||
wake_up( &thread->obj, 0 );
|
||||
if (violent_death) send_thread_signal( thread, SIGQUIT );
|
||||
|
|
|
@ -54,7 +54,6 @@ struct thread
|
|||
struct process *process;
|
||||
thread_id_t id; /* thread id */
|
||||
struct list mutex_list; /* list of currently owned mutexes */
|
||||
struct debug_obj *debug_obj; /* debugger context if this thread is a debugger */
|
||||
unsigned int system_regs; /* which system regs have been set */
|
||||
struct msg_queue *queue; /* message queue */
|
||||
struct thread_wait *wait; /* current wait condition if sleeping */
|
||||
|
|
Loading…
Reference in New Issue