server: Don't store the debug object in the debugger thread.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-02-01 12:17:03 +01:00
parent 7999af8244
commit 2b6426da65
6 changed files with 37 additions and 24 deletions

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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 */

View File

@ -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)
{

View File

@ -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 );

View File

@ -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 */