diff --git a/dlls/kernel/debugger.c b/dlls/kernel/debugger.c index 1b6a90c3790..a2d31218e77 100644 --- a/dlls/kernel/debugger.c +++ b/dlls/kernel/debugger.c @@ -268,22 +268,19 @@ void WINAPI DebugBreak(void) */ BOOL WINAPI DebugBreakProcess(HANDLE hProc) { -#if 0 /* FIXME: not correct */ - int res; - int pid; + BOOL ret, self; - TRACE("(%08lx)\n", (DWORD)hProc); + TRACE("(%08x)\n", hProc); - SERVER_START_REQ( get_process_info ) + SERVER_START_REQ( debug_break ) { req->handle = hProc; - res = wine_server_call_err( req ); - pid = (int)reply->pid; + ret = !wine_server_call_err( req ); + self = ret && reply->self; } SERVER_END_REQ; - return !res && kill(pid, SIGINT) == 0; -#endif - return FALSE; + if (self) DbgBreakPoint(); + return ret; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index d2b9ccb84de..086de667bf3 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1563,6 +1563,19 @@ struct debug_process_reply +struct debug_break_request +{ + struct request_header __header; + handle_t handle; +}; +struct debug_break_reply +{ + struct reply_header __header; + int self; +}; + + + struct set_debugger_kill_on_exit_request { struct request_header __header; @@ -2681,6 +2694,7 @@ enum request REQ_output_debug_string, REQ_continue_debug_event, REQ_debug_process, + REQ_debug_break, REQ_set_debugger_kill_on_exit, REQ_read_process_memory, REQ_write_process_memory, @@ -2837,6 +2851,7 @@ union generic_request struct output_debug_string_request output_debug_string_request; struct continue_debug_event_request continue_debug_event_request; struct debug_process_request debug_process_request; + struct debug_break_request debug_break_request; struct set_debugger_kill_on_exit_request set_debugger_kill_on_exit_request; struct read_process_memory_request read_process_memory_request; struct write_process_memory_request write_process_memory_request; @@ -2991,6 +3006,7 @@ union generic_reply struct output_debug_string_reply output_debug_string_reply; struct continue_debug_event_reply continue_debug_event_reply; struct debug_process_reply debug_process_reply; + struct debug_break_reply debug_break_reply; struct set_debugger_kill_on_exit_reply set_debugger_kill_on_exit_reply; struct read_process_memory_reply read_process_memory_reply; struct write_process_memory_reply write_process_memory_reply; @@ -3059,6 +3075,6 @@ union generic_reply struct get_window_properties_reply get_window_properties_reply; }; -#define SERVER_PROTOCOL_VERSION 71 +#define SERVER_PROTOCOL_VERSION 72 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/debugger.c b/server/debugger.c index 42d73622a11..60e406bc956 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -698,6 +699,32 @@ DECL_HANDLER(output_debug_string) generate_debug_event( current, OUTPUT_DEBUG_STRING_EVENT, &data ); } +/* simulate a breakpoint in a process */ +DECL_HANDLER(debug_break) +{ + struct process *process; + + reply->self = 0; + if (!(process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION /*FIXME*/ ))) + return; + if (process != current->process) + { + /* find a suitable thread to signal */ + struct thread *thread; + for (thread = process->thread_list; thread; thread = thread->proc_next) + { + if (thread->unix_pid) + { + kill( thread->unix_pid, SIGTRAP ); + break; + } + } + if (!thread) set_error( STATUS_ACCESS_DENIED ); + } + else reply->self = 1; + release_object( process ); +} + /* set debugger kill on exit flag */ DECL_HANDLER(set_debugger_kill_on_exit) { diff --git a/server/protocol.def b/server/protocol.def index f5dd291b9af..72b10538d3b 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1124,6 +1124,14 @@ enum char_info_mode @END +/* Simulate a breakpoint in a process */ +@REQ(debug_break) + handle_t handle; /* process handle */ +@REPLY + int self; /* was it the caller itself? */ +@END + + /* Set debugger kill on exit flag */ @REQ(set_debugger_kill_on_exit) int kill_on_exit; /* 0=detach/1=kill debuggee when debugger dies */ diff --git a/server/request.h b/server/request.h index 44f2cafb20a..6acabfedd4f 100644 --- a/server/request.h +++ b/server/request.h @@ -170,6 +170,7 @@ DECL_HANDLER(get_exception_status); DECL_HANDLER(output_debug_string); DECL_HANDLER(continue_debug_event); DECL_HANDLER(debug_process); +DECL_HANDLER(debug_break); DECL_HANDLER(set_debugger_kill_on_exit); DECL_HANDLER(read_process_memory); DECL_HANDLER(write_process_memory); @@ -325,6 +326,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_output_debug_string, (req_handler)req_continue_debug_event, (req_handler)req_debug_process, + (req_handler)req_debug_break, (req_handler)req_set_debugger_kill_on_exit, (req_handler)req_read_process_memory, (req_handler)req_write_process_memory, diff --git a/server/trace.c b/server/trace.c index d7859db553a..0d5a89d6d60 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1288,6 +1288,16 @@ static void dump_debug_process_request( const struct debug_process_request *req fprintf( stderr, " attach=%d", req->attach ); } +static void dump_debug_break_request( const struct debug_break_request *req ) +{ + fprintf( stderr, " handle=%d", req->handle ); +} + +static void dump_debug_break_reply( const struct debug_break_reply *req ) +{ + fprintf( stderr, " self=%d", req->self ); +} + static void dump_set_debugger_kill_on_exit_request( const struct set_debugger_kill_on_exit_request *req ) { fprintf( stderr, " kill_on_exit=%d", req->kill_on_exit ); @@ -2121,6 +2131,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_output_debug_string_request, (dump_func)dump_continue_debug_event_request, (dump_func)dump_debug_process_request, + (dump_func)dump_debug_break_request, (dump_func)dump_set_debugger_kill_on_exit_request, (dump_func)dump_read_process_memory_request, (dump_func)dump_write_process_memory_request, @@ -2273,6 +2284,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)0, (dump_func)0, (dump_func)0, + (dump_func)dump_debug_break_reply, (dump_func)0, (dump_func)dump_read_process_memory_reply, (dump_func)0, @@ -2425,6 +2437,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "output_debug_string", "continue_debug_event", "debug_process", + "debug_break", "set_debugger_kill_on_exit", "read_process_memory", "write_process_memory",