diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c index b7ec9e99ed3..fb5ea1581e2 100644 --- a/dlls/kernel32/tests/debugger.c +++ b/dlls/kernel32/tests/debugger.c @@ -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); } diff --git a/server/debugger.c b/server/debugger.c index 927fe42929e..24cf33f92b4 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -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) { diff --git a/server/object.h b/server/object.h index 77d0594f99e..62f2cbafca6 100644 --- a/server/object.h +++ b/server/object.h @@ -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 */ diff --git a/server/process.c b/server/process.c index 95e030777c9..60562db326b 100644 --- a/server/process.c +++ b/server/process.c @@ -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) { diff --git a/server/thread.c b/server/thread.c index fd3538c51f3..03b483d14ee 100644 --- a/server/thread.c +++ b/server/thread.c @@ -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 ); diff --git a/server/thread.h b/server/thread.h index a83309bc940..5f8eeeb3c50 100644 --- a/server/thread.h +++ b/server/thread.h @@ -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 */