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
};
/* 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 */
struct queue_apc_request
{
......@@ -694,6 +703,7 @@ extern int CLIENT_InitServer(void);
struct _THDB;
extern int CLIENT_SetDebug( int level );
extern int CLIENT_DebuggerRequest( int op );
extern int CLIENT_InitThread(void);
#endif /* __WINE_SERVER__ */
......
......@@ -18,6 +18,7 @@ enum request
REQ_SET_THREAD_INFO,
REQ_SUSPEND_THREAD,
REQ_RESUME_THREAD,
REQ_DEBUGGER,
REQ_QUEUE_APC,
REQ_CLOSE_HANDLE,
REQ_GET_HANDLE_INFO,
......@@ -80,6 +81,7 @@ DECL_HANDLER(get_thread_info);
DECL_HANDLER(set_thread_info);
DECL_HANDLER(suspend_thread);
DECL_HANDLER(resume_thread);
DECL_HANDLER(debugger);
DECL_HANDLER(queue_apc);
DECL_HANDLER(close_handle);
DECL_HANDLER(get_handle_info);
......@@ -139,6 +141,7 @@ static const struct handler {
{ (void(*)())req_set_thread_info, sizeof(struct set_thread_info_request) },
{ (void(*)())req_suspend_thread, sizeof(struct suspend_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_close_handle, sizeof(struct close_handle_request) },
{ (void(*)())req_get_handle_info, sizeof(struct get_handle_info_request) },
......
......@@ -59,6 +59,8 @@ extern void set_thread_info( struct thread *thread,
struct set_thread_info_request *req );
extern int suspend_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,
int n, ... /* arg_1, len_1, ..., arg_n, len_n */ );
extern int add_queue( struct object *obj, struct wait_queue_entry *entry );
......
......@@ -293,6 +293,9 @@ int CLIENT_InitServer(void)
perror("fork");
exit(1);
case 0: /* child */
close( fd[1] );
break;
default: /* parent */
close( fd[0] );
sprintf( buffer, "%d", fd[1] );
/*#define EXEC_SERVER*/
......@@ -303,9 +306,6 @@ int CLIENT_InitServer(void)
#endif
create_initial_thread( fd[1] );
exit(0);
default: /* parent */
close( fd[1] );
break;
}
return fd[0];
}
......@@ -341,3 +341,17 @@ int CLIENT_SetDebug( int level )
CLIENT_SendRequest( REQ_SET_DEBUG, -1, 1, &level, sizeof(level) );
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)
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)
{
......
......@@ -102,6 +102,7 @@ void create_initial_thread( int fd )
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 @@ int resume_thread( struct thread *thread )
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 */ )
......
......@@ -160,6 +160,12 @@ static int dump_resume_thread_reply( struct resume_thread_reply *req, int len )
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 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
(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 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"set_thread_info",
"suspend_thread",
"resume_thread",
"debugger",
"queue_apc",
"close_handle",
"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