Commit 371fd75a authored by Ulrich Weigand's avatar Ulrich Weigand Committed by Alexandre Julliard

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!
parent 9e696f89
...@@ -195,6 +195,15 @@ struct resume_thread_reply ...@@ -195,6 +195,15 @@ struct resume_thread_reply
}; };
/* Debugger support: freeze / unfreeze */
struct debugger_request
{
int op; /* operation type */
};
enum debugger_op { DEBUGGER_FREEZE_ALL, DEBUGGER_UNFREEZE_ALL };
/* Queue an APC for a thread */ /* Queue an APC for a thread */
struct queue_apc_request struct queue_apc_request
{ {
...@@ -694,6 +703,7 @@ extern int CLIENT_InitServer(void); ...@@ -694,6 +703,7 @@ extern int CLIENT_InitServer(void);
struct _THDB; struct _THDB;
extern int CLIENT_SetDebug( int level ); extern int CLIENT_SetDebug( int level );
extern int CLIENT_DebuggerRequest( int op );
extern int CLIENT_InitThread(void); extern int CLIENT_InitThread(void);
#endif /* __WINE_SERVER__ */ #endif /* __WINE_SERVER__ */
......
...@@ -18,6 +18,7 @@ enum request ...@@ -18,6 +18,7 @@ enum request
REQ_SET_THREAD_INFO, REQ_SET_THREAD_INFO,
REQ_SUSPEND_THREAD, REQ_SUSPEND_THREAD,
REQ_RESUME_THREAD, REQ_RESUME_THREAD,
REQ_DEBUGGER,
REQ_QUEUE_APC, REQ_QUEUE_APC,
REQ_CLOSE_HANDLE, REQ_CLOSE_HANDLE,
REQ_GET_HANDLE_INFO, REQ_GET_HANDLE_INFO,
...@@ -80,6 +81,7 @@ DECL_HANDLER(get_thread_info); ...@@ -80,6 +81,7 @@ DECL_HANDLER(get_thread_info);
DECL_HANDLER(set_thread_info); DECL_HANDLER(set_thread_info);
DECL_HANDLER(suspend_thread); DECL_HANDLER(suspend_thread);
DECL_HANDLER(resume_thread); DECL_HANDLER(resume_thread);
DECL_HANDLER(debugger);
DECL_HANDLER(queue_apc); DECL_HANDLER(queue_apc);
DECL_HANDLER(close_handle); DECL_HANDLER(close_handle);
DECL_HANDLER(get_handle_info); DECL_HANDLER(get_handle_info);
...@@ -139,6 +141,7 @@ static const struct handler { ...@@ -139,6 +141,7 @@ static const struct handler {
{ (void(*)())req_set_thread_info, sizeof(struct set_thread_info_request) }, { (void(*)())req_set_thread_info, sizeof(struct set_thread_info_request) },
{ (void(*)())req_suspend_thread, sizeof(struct suspend_thread_request) }, { (void(*)())req_suspend_thread, sizeof(struct suspend_thread_request) },
{ (void(*)())req_resume_thread, sizeof(struct resume_thread_request) }, { (void(*)())req_resume_thread, sizeof(struct resume_thread_request) },
{ (void(*)())req_debugger, sizeof(struct debugger_request) },
{ (void(*)())req_queue_apc, sizeof(struct queue_apc_request) }, { (void(*)())req_queue_apc, sizeof(struct queue_apc_request) },
{ (void(*)())req_close_handle, sizeof(struct close_handle_request) }, { (void(*)())req_close_handle, sizeof(struct close_handle_request) },
{ (void(*)())req_get_handle_info, sizeof(struct get_handle_info_request) }, { (void(*)())req_get_handle_info, sizeof(struct get_handle_info_request) },
......
...@@ -59,6 +59,8 @@ extern void set_thread_info( struct thread *thread, ...@@ -59,6 +59,8 @@ extern void set_thread_info( struct thread *thread,
struct set_thread_info_request *req ); struct set_thread_info_request *req );
extern int suspend_thread( struct thread *thread ); extern int suspend_thread( struct thread *thread );
extern int resume_thread( struct thread *thread ); extern int resume_thread( struct thread *thread );
extern void suspend_all_threads( void );
extern void resume_all_threads( void );
extern int send_reply( struct thread *thread, int pass_fd, extern int send_reply( struct thread *thread, int pass_fd,
int n, ... /* arg_1, len_1, ..., arg_n, len_n */ ); int n, ... /* arg_1, len_1, ..., arg_n, len_n */ );
extern int add_queue( struct object *obj, struct wait_queue_entry *entry ); extern int add_queue( struct object *obj, struct wait_queue_entry *entry );
......
...@@ -293,6 +293,9 @@ int CLIENT_InitServer(void) ...@@ -293,6 +293,9 @@ int CLIENT_InitServer(void)
perror("fork"); perror("fork");
exit(1); exit(1);
case 0: /* child */ case 0: /* child */
close( fd[1] );
break;
default: /* parent */
close( fd[0] ); close( fd[0] );
sprintf( buffer, "%d", fd[1] ); sprintf( buffer, "%d", fd[1] );
/*#define EXEC_SERVER*/ /*#define EXEC_SERVER*/
...@@ -303,9 +306,6 @@ int CLIENT_InitServer(void) ...@@ -303,9 +306,6 @@ int CLIENT_InitServer(void)
#endif #endif
create_initial_thread( fd[1] ); create_initial_thread( fd[1] );
exit(0); exit(0);
default: /* parent */
close( fd[1] );
break;
} }
return fd[0]; return fd[0];
} }
...@@ -341,3 +341,17 @@ int CLIENT_SetDebug( int level ) ...@@ -341,3 +341,17 @@ int CLIENT_SetDebug( int level )
CLIENT_SendRequest( REQ_SET_DEBUG, -1, 1, &level, sizeof(level) ); CLIENT_SendRequest( REQ_SET_DEBUG, -1, 1, &level, sizeof(level) );
return CLIENT_WaitReply( NULL, NULL, 0 ); return CLIENT_WaitReply( NULL, NULL, 0 );
} }
/***********************************************************************
* CLIENT_DebuggerRequest
*
* Send a debugger support request. Return 0 if OK.
*/
int CLIENT_DebuggerRequest( int op )
{
struct debugger_request req;
req.op = op;
CLIENT_SendRequest( REQ_DEBUGGER, -1, 1, &req, sizeof(req) );
return CLIENT_WaitReply( NULL, NULL, 0 );
}
...@@ -315,6 +315,23 @@ DECL_HANDLER(set_thread_info) ...@@ -315,6 +315,23 @@ DECL_HANDLER(set_thread_info)
send_reply( current, -1, 0 ); 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 */ /* suspend a thread */
DECL_HANDLER(suspend_thread) DECL_HANDLER(suspend_thread)
{ {
......
...@@ -102,6 +102,7 @@ void create_initial_thread( int fd ) ...@@ -102,6 +102,7 @@ void create_initial_thread( int fd )
initial_thread.process = create_initial_process(); initial_thread.process = create_initial_process();
add_process_thread( initial_thread.process, &initial_thread ); add_process_thread( initial_thread.process, &initial_thread );
add_client( fd, &initial_thread ); add_client( fd, &initial_thread );
grab_object( &initial_thread ); /* so that we never free it */
select_loop(); select_loop();
} }
...@@ -242,6 +243,24 @@ int resume_thread( struct thread *thread ) ...@@ -242,6 +243,24 @@ int resume_thread( struct thread *thread )
return old_count; 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 */ /* send a reply to a thread */
int send_reply( struct thread *thread, int pass_fd, int n, int send_reply( struct thread *thread, int pass_fd, int n,
... /* arg_1, len_1, ..., arg_n, len_n */ ) ... /* arg_1, len_1, ..., arg_n, len_n */ )
......
...@@ -160,6 +160,12 @@ static int dump_resume_thread_reply( struct resume_thread_reply *req, int len ) ...@@ -160,6 +160,12 @@ static int dump_resume_thread_reply( struct resume_thread_reply *req, int len )
return (int)sizeof(*req); 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 ) static int dump_queue_apc_request( struct queue_apc_request *req, int len )
{ {
fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " handle=%d,", req->handle );
...@@ -663,6 +669,8 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] = ...@@ -663,6 +669,8 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
(void(*)())dump_suspend_thread_reply }, (void(*)())dump_suspend_thread_reply },
{ (int(*)(void *,int))dump_resume_thread_request, { (int(*)(void *,int))dump_resume_thread_request,
(void(*)())dump_resume_thread_reply }, (void(*)())dump_resume_thread_reply },
{ (int(*)(void *,int))dump_debugger_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_queue_apc_request, { (int(*)(void *,int))dump_queue_apc_request,
(void(*)())0 }, (void(*)())0 },
{ (int(*)(void *,int))dump_close_handle_request, { (int(*)(void *,int))dump_close_handle_request,
...@@ -762,6 +770,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = ...@@ -762,6 +770,7 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"set_thread_info", "set_thread_info",
"suspend_thread", "suspend_thread",
"resume_thread", "resume_thread",
"debugger",
"queue_apc", "queue_apc",
"close_handle", "close_handle",
"get_handle_info", "get_handle_info",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment