Added new CLIENT_DebuggerRequest routine, implemented support for DEBUGGER_FREEZE_ALL/DEBUGGER_UNFREEZE_ALL requests. Run wine server in the main wine process. Bugfix: never free initial thread!
diff --git a/server/request.c b/server/request.c index 25bd353..01d64c5 100644 --- a/server/request.c +++ b/server/request.c
@@ -315,6 +315,23 @@ send_reply( current, -1, 0 ); } +/* debugger support operations */ +DECL_HANDLER(debugger) +{ + switch ( req->op ) + { + case DEBUGGER_FREEZE_ALL: + suspend_all_threads(); + break; + + case DEBUGGER_UNFREEZE_ALL: + resume_all_threads(); + break; + } + + send_reply( current, -1, 0 ); +} + /* suspend a thread */ DECL_HANDLER(suspend_thread) {
diff --git a/server/thread.c b/server/thread.c index bf8a2ca..e86cd6d 100644 --- a/server/thread.c +++ b/server/thread.c
@@ -102,6 +102,7 @@ initial_thread.process = create_initial_process(); add_process_thread( initial_thread.process, &initial_thread ); add_client( fd, &initial_thread ); + grab_object( &initial_thread ); /* so that we never free it */ select_loop(); } @@ -242,6 +243,24 @@ return old_count; } +/* suspend all threads but the current */ +void suspend_all_threads( void ) +{ + struct thread *thread; + for ( thread = first_thread; thread; thread = thread->next ) + if ( thread != current ) + suspend_thread( thread ); +} + +/* resume all threads but the current */ +void resume_all_threads( void ) +{ + struct thread *thread; + for ( thread = first_thread; thread; thread = thread->next ) + if ( thread != current ) + resume_thread( thread ); +} + /* send a reply to a thread */ int send_reply( struct thread *thread, int pass_fd, int n, ... /* arg_1, len_1, ..., arg_n, len_n */ )
diff --git a/server/trace.c b/server/trace.c index f1ab987..260b16b 100644 --- a/server/trace.c +++ b/server/trace.c
@@ -160,6 +160,12 @@ return (int)sizeof(*req); } +static int dump_debugger_request( struct debugger_request *req, int len ) +{ + fprintf( stderr, " op=%d", req->op ); + return (int)sizeof(*req); +} + static int dump_queue_apc_request( struct queue_apc_request *req, int len ) { fprintf( stderr, " handle=%d,", req->handle ); @@ -663,6 +669,8 @@ (void(*)())dump_suspend_thread_reply }, { (int(*)(void *,int))dump_resume_thread_request, (void(*)())dump_resume_thread_reply }, + { (int(*)(void *,int))dump_debugger_request, + (void(*)())0 }, { (int(*)(void *,int))dump_queue_apc_request, (void(*)())0 }, { (int(*)(void *,int))dump_close_handle_request, @@ -762,6 +770,7 @@ "set_thread_info", "suspend_thread", "resume_thread", + "debugger", "queue_apc", "close_handle", "get_handle_info",