Alexandre Julliard : server: Don't store the debug object in the debugger thread.
Alexandre Julliard
julliard at winehq.org
Mon Feb 1 16:13:08 CST 2021
Module: wine
Branch: master
Commit: 2b6426da6550c50787eeb2b39affcb766e07ec11
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2b6426da6550c50787eeb2b39affcb766e07ec11
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Feb 1 12:17:03 2021 +0100
server: Don't store the debug object in the debugger thread.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/kernel32/tests/debugger.c | 40 +++++++++++++++++++++++++++++++++++++---
server/debugger.c | 15 ---------------
server/object.h | 1 -
server/process.c | 1 -
server/thread.c | 3 ---
server/thread.h | 1 -
6 files changed, 37 insertions(+), 24 deletions(-)
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 */
More information about the wine-cvs
mailing list