aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me+cygwin@cgf.cx>2009-03-22 21:43:56 +0000
committerChristopher Faylor <me+cygwin@cgf.cx>2009-03-22 21:43:56 +0000
commit695de547fcbfa05456ab7d47eb539d5024ebd892 (patch)
tree967b2f0c59ec3dc2f5b6225abd1227b23d961e97
parent2b008701dc388692b80774c1913c55d54be5c320 (diff)
downloadgdb-695de547fcbfa05456ab7d47eb539d5024ebd892.zip
gdb-695de547fcbfa05456ab7d47eb539d5024ebd892.tar.gz
gdb-695de547fcbfa05456ab7d47eb539d5024ebd892.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/windows-nat.c80
2 files changed, 66 insertions, 21 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 686a149..dd7f91e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index e80c4c5..ffd2222 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -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);