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!
This commit is contained in:
parent
9e696f8906
commit
371fd75a39
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue