* win32-nat.c (ctrl_c_handler): New function.
(win32_wait): Register ctrl_c_handler as Ctrl-C handler if the inferior is run in a separate console.
This commit is contained in:
parent
2b008701dc
commit
695de547fc
2 changed files with 66 additions and 21 deletions
|
@ -1,3 +1,10 @@
|
|||
2009-03-22 Nicolas Roche <roche@adacore.com>
|
||||
Christopher Faylor <me+cygwin@cgf.cx>
|
||||
|
||||
* win32-nat.c (ctrl_c_handler): New function.
|
||||
(win32_wait): Register ctrl_c_handler as Ctrl-C handler if the inferior
|
||||
is run in a separate console.
|
||||
|
||||
2009-03-22 Christopher Faylor <me+cygwin@cgf.cx>
|
||||
|
||||
* windows-nat.c (DebugActiveProcessStop): Implement macro wraparound
|
||||
|
|
|
@ -1267,9 +1267,34 @@ windows_resume (struct target_ops *ops,
|
|||
windows_continue (continue_status, ptid_get_tid (ptid));
|
||||
}
|
||||
|
||||
/* Ctrl-C handler used when the inferior is not run in the same console. The
|
||||
handler is in charge of interrupting the inferior using DebugBreakProcess.
|
||||
Note that this function is not available prior to Windows XP. In this case
|
||||
we emit a warning. */
|
||||
BOOL WINAPI
|
||||
ctrl_c_handler (DWORD event_type)
|
||||
{
|
||||
const int attach_flag = current_inferior ()->attach_flag;
|
||||
|
||||
/* Only handle Ctrl-C event. Ignore others. */
|
||||
if (event_type != CTRL_C_EVENT)
|
||||
return FALSE;
|
||||
|
||||
/* If the inferior and the debugger share the same console, do nothing as
|
||||
the inferior has also received the Ctrl-C event. */
|
||||
if (!new_console && !attach_flag)
|
||||
return TRUE;
|
||||
|
||||
if (!DebugBreakProcess (current_process_handle))
|
||||
warning (_("\
|
||||
Could not interrupt program. Press Ctrl-c in the program console."));
|
||||
|
||||
/* Return true to tell that Ctrl-C has been handled. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Get the next event from the child. Return 1 if the event requires
|
||||
handling by WFI (or whatever).
|
||||
*/
|
||||
handling by WFI (or whatever). */
|
||||
static int
|
||||
get_windows_debug_event (struct target_ops *ops,
|
||||
int pid, struct target_waitstatus *ourstatus)
|
||||
|
@ -1346,13 +1371,13 @@ get_windows_debug_event (struct target_ops *ops,
|
|||
|
||||
current_process_handle = current_event.u.CreateProcessInfo.hProcess;
|
||||
if (main_thread_id)
|
||||
windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
|
||||
main_thread_id));
|
||||
windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
|
||||
main_thread_id));
|
||||
main_thread_id = current_event.dwThreadId;
|
||||
/* Add the main thread */
|
||||
th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
|
||||
current_event.dwThreadId),
|
||||
current_event.u.CreateProcessInfo.hThread);
|
||||
current_event.dwThreadId),
|
||||
current_event.u.CreateProcessInfo.hThread);
|
||||
retval = current_event.dwThreadId;
|
||||
break;
|
||||
|
||||
|
@ -1475,22 +1500,35 @@ windows_wait (struct target_ops *ops,
|
|||
{
|
||||
int retval;
|
||||
|
||||
/* Ignore CTRL+C signals while waiting for a debug event.
|
||||
FIXME: brobecker/2008-05-20: When the user presses CTRL+C while
|
||||
the inferior is running, both the inferior and GDB receive the
|
||||
associated signal. If the inferior receives the signal first
|
||||
and the delay until GDB receives that signal is sufficiently long,
|
||||
GDB can sometimes receive the SIGINT after we have unblocked
|
||||
the CTRL+C handler. This would lead to the debugger to stop
|
||||
prematurely while handling the new-thread event that comes
|
||||
with the handling of the SIGINT inside the inferior, and then
|
||||
stop again immediately when the user tries to resume the execution
|
||||
in the inferior. This is a classic race, and it would be nice
|
||||
to find a better solution to that problem. But in the meantime,
|
||||
the current approach already greatly mitigate this issue. */
|
||||
SetConsoleCtrlHandler (NULL, TRUE);
|
||||
/* If the user presses Ctrl-c while the debugger is waiting
|
||||
for an event, he expects the debugger to interrupt his program
|
||||
and to get the prompt back. There are two possible situations:
|
||||
|
||||
- The debugger and the program do not share the console, in
|
||||
which case the Ctrl-c event only reached the debugger.
|
||||
In that case, the ctrl_c handler will take care of interrupting
|
||||
the inferior. Note that this case is working starting with
|
||||
Windows XP. For Windows 2000, Ctrl-C should be pressed in the
|
||||
inferior console.
|
||||
|
||||
- The debugger and the program share the same console, in which
|
||||
case both debugger and inferior will receive the Ctrl-c event.
|
||||
In that case the ctrl_c handler will ignore the event, as the
|
||||
Ctrl-c event generated inside the inferior will trigger the
|
||||
expected debug event.
|
||||
|
||||
FIXME: brobecker/2008-05-20: If the inferior receives the
|
||||
signal first and the delay until GDB receives that signal
|
||||
is sufficiently long, GDB can sometimes receive the SIGINT
|
||||
after we have unblocked the CTRL+C handler. This would
|
||||
lead to the debugger stopping prematurely while handling
|
||||
the new-thread event that comes with the handling of the SIGINT
|
||||
inside the inferior, and then stop again immediately when
|
||||
the user tries to resume the execution in the inferior.
|
||||
This is a classic race that we should try to fix one day. */
|
||||
SetConsoleCtrlHandler (&ctrl_c_handler, TRUE);
|
||||
retval = get_windows_debug_event (ops, pid, ourstatus);
|
||||
SetConsoleCtrlHandler (NULL, FALSE);
|
||||
SetConsoleCtrlHandler (&ctrl_c_handler, FALSE);
|
||||
|
||||
if (retval)
|
||||
return ptid_build (current_event.dwProcessId, 0, retval);
|
||||
|
|
Loading…
Reference in a new issue