From: "Pierre Muller" <muller@ics.u-strasbg.fr>
To: <gdb-patches@sourceware.org>,
"'Joel Brobecker'" <brobecker@adacore.com>,
"'Pedro Alves'" <pedro@codesourcery.com>
Subject: [RFC-v3] win32-nat.c 'set new-console' and interruption
Date: Tue, 24 Jun 2008 13:36:00 -0000 [thread overview]
Message-ID: <000a01c8d5d1$7201a250$5604e6f0$@u-strasbg.fr> (raw)
In-Reply-To: <20080624011456.GB13397@ednor.casa.cgf.cx>
> >So, I would personally prefered if we kept the SIGTRAP to SIGINT
> >translation... Just my 2 cents.
>
> I think that makes 4 cents. A SIGTRAP would be confusing.
>
> I haven't looked at the patch yet, however.
>
> cgf
In that case, let me send you a new version of the patch then:
version 3 superseeds the two previous versions in this thread.
It contains the attempt to distinguish
if EXCEPTION_BREAKPOINT comes from the win32_stop call,
to eliminate the race condition you raised:
if ctrl_break_sent is set and the location of the
exception addr is not a breakpoint set by GDB,
then we assume that the exception was generated by
the call to DebugBreakProcess.
I also added code to reset ctrl_break_sent to zero
in do_initial_win32_stuff.
Finally I also set start_flags to CREATE_NEW_CONSOLE
if we attach to a running process rather than
start one. It seems rather odd to me to try to
attach to a process running in the same console, it
is much better to start GDB in an new console and
to attach from there.
Nevertheless, I must admit that I don't know if
there is away to know if the process to which we are attaching
is running in the console or not.
Pierre Muller
Pascal language support maintainer for GDB
$ cat win32term.log
ChangeLog entry:
2008-06-24 Pierre Muller <muller@ics.u-strasbg.fr>
* win32-nat.c (group_id, ctrl_break_sent, start_flags): New
variables.
(handle_exception): Recognize signal sent with DebugBreakProcess
and treat as TARGET_SIGNAL_INT.
(gdb_ctrl_handler): New function. Sends a interrupting signal to
debuggee.
(win32_wait): Use gdb_ctrl_handler if debuggee started in a new
console.
(do_initial_win32_stuff): Reset ctrl_break_sent.
(kernel32): HANDLE variable moved from has_detach_ability to main
level.
(win32_attach): set start_flags to CREATE_NEW_CONSOLE.
(DebugBreakProcess): New function variable.
(win32_stop): Only use GenerateConsoleCtrlEvent if debuggee on same
console. Otherwise test for kernel32 DebugBreakProcess function and
use if available.
(win32_create_inferior): Set start_flags and group_id.
(win32_terminal_inferior, win32_terminal_ours): New functions.
Do nothing if debuggee was started in a new console.
(win32_terminal_ours_for_output): New function, as above.
(init_win32_ops): Set to_terminal_inferior to
win32_terminal_inferior
and to_terminal_ours to win32_terminal_ours.
$ cat win32term.patch
Index: gdb/win32-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/win32-nat.c,v
retrieving revision 1.155
diff -u -p -r1.155 win32-nat.c
--- gdb/win32-nat.c 24 Jun 2008 02:33:17 -0000 1.155
+++ gdb/win32-nat.c 24 Jun 2008 07:43:13 -0000
@@ -137,6 +137,8 @@ static DEBUG_EVENT current_event; /* The
static HANDLE current_process_handle; /* Currently executing process */
static thread_info *current_thread; /* Info on currently selected thread
*/
static DWORD main_thread_id; /* Thread ID of the main thread */
+static DWORD group_id = 0;
+static int ctrl_break_sent = 0;
/* Counts of things. */
static int exception_count = 0;
@@ -155,6 +157,7 @@ static int debug_events = 0; /* show ev
static int debug_memory = 0; /* show target memory accesses */
static int debug_exceptions = 0; /* show target exceptions */
static int useshell = 0; /* use shell for subprocesses */
+static DWORD start_flags = 0; /* remember CreateProcess flags */
/* This vector maps GDB's idea of a register's number into an address
in the win32 exception context vector.
@@ -1074,7 +1077,22 @@ handle_exception (struct target_waitstat
break;
case EXCEPTION_BREAKPOINT:
DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
- ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ if (ctrl_break_sent)
+
+ {
+ CORE_ADDR addr =
+ (CORE_ADDR)
current_event.u.Exception.ExceptionRecord.ExceptionAddre
ss;
+
+ if (!breakpoint_inserted_here_p (addr))
+ {
+ DEBUG_EXCEPT (("EXCEPTION_BREAKPOINT at 0x%lx converted to \
+TARGET_SIGNAL_INT\n", (DWORD) addr));
+ ctrl_break_sent = 0;
+ ourstatus->value.sig = TARGET_SIGNAL_INT;
+ }
+ }
+ else
+ ourstatus->value.sig = TARGET_SIGNAL_TRAP;
break;
case DBG_CONTROL_C:
DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
@@ -1445,6 +1463,30 @@ out:
return retval;
}
+
+static BOOL WINAPI
+gdb_ctrl_handler (DWORD dw_ctrl_type)
+{
+ DEBUG_EVENTS(("gdb_ctrl_handler called with dwCtrType=%u\n",
+ (unsigned int) dw_ctrl_type));
+ switch (dw_ctrl_type)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ win32_stop();
+ /* Notify that event is handled. */
+ return TRUE;
+ break;
+ case CTRL_CLOSE_EVENT:
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ /* Notify that event is not handled. */
+ return FALSE;
+ break;
+ }
+ return FALSE;
+}
+
/* Wait for interesting events to occur in the target process. */
static ptid_t
win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
@@ -1476,9 +1518,16 @@ win32_wait (ptid_t ptid, struct target_w
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 (start_flags & CREATE_NEW_CONSOLE)
+ SetConsoleCtrlHandler (&gdb_ctrl_handler, TRUE);
+ else
+ SetConsoleCtrlHandler (NULL, TRUE);
retval = get_win32_debug_event (pid, ourstatus);
SetConsoleCtrlHandler (NULL, FALSE);
+ if (start_flags & CREATE_NEW_CONSOLE)
+ SetConsoleCtrlHandler (&gdb_ctrl_handler, FALSE);
+ else
+ SetConsoleCtrlHandler (NULL, FALSE);
if (retval)
return pid_to_ptid (retval);
@@ -1505,6 +1554,8 @@ do_initial_win32_stuff (DWORD pid)
event_count = 0;
exception_count = 0;
open_process_used = 0;
+ ctrl_break_sent = 0;
+
debug_registers_changed = 0;
debug_registers_used = 0;
for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
@@ -1546,12 +1597,12 @@ do_initial_win32_stuff (DWORD pid)
detach has worked. */
static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
-
+static BOOL WINAPI (*DebugBreakProcess)(HANDLE);
+static HMODULE kernel32 = NULL;
+
static int
has_detach_ability (void)
{
- static HMODULE kernel32 = NULL;
-
if (!kernel32)
kernel32 = LoadLibrary ("kernel32.dll");
if (kernel32)
@@ -1686,6 +1737,10 @@ win32_attach (char *args, int from_tty)
attach_flag = 1;
+ /* Attaching to a process on the same console seems not the right thing
to do
.
+ Let's assume the debuggee runs on a separate console. */
+ start_flags = CREATE_NEW_CONSOLE;
+
if (from_tty)
{
char *exec_file = (char *) get_exec_file (0);
@@ -1906,6 +1961,13 @@ win32_create_inferior (char *exec_file,
else
saw_create = 0;
+ start_flags = flags;
+
+ if (flags & CREATE_NEW_PROCESS_GROUP)
+ group_id = pi.dwProcessId;
+ else
+ group_id = 0;
+
do_initial_win32_stuff (pi.dwProcessId);
/* win32_continue (DBG_CONTINUE, -1); */
@@ -1921,6 +1983,7 @@ win32_mourn_inferior (void)
CHECK (CloseHandle (current_process_handle));
open_process_used = 0;
}
+ start_flags = 0;
unpush_target (&win32_ops);
generic_mourn_inferior ();
}
@@ -1931,11 +1994,35 @@ win32_mourn_inferior (void)
static void
win32_stop (void)
{
- DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
- CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT,
current_event.dwProcessId));
+ if ((start_flags & CREATE_NEW_CONSOLE) == 0)
+ {
+ DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT,
%lu)\n",
+ current_event.dwProcessId));
+ CHECK (GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT,
+ group_id));
+ }
+ else
+ {
+ if (!kernel32)
+ kernel32 = LoadLibrary ("kernel32.dll");
+ if (kernel32)
+ {
+ if (!DebugBreakProcess)
+ DebugBreakProcess = GetProcAddress (kernel32,
"DebugBreakProcess");
+ }
+ if (DebugBreakProcess && current_process_handle)
+ {
+ DEBUG_EVENTS (("DebugBreakProcess (%d)\n",
+ (int) current_process_handle));
+ ctrl_break_sent = 1;
+ DebugBreakProcess (current_process_handle);
+ }
+ else
+ DEBUG_EVENTS (("Unable to interrupt debuggee in another
console\n"));
+ }
registers_changed (); /* refresh register state */
}
-
+
static int
win32_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len,
int write, struct mem_attrib *mem,
@@ -2076,6 +2163,36 @@ win32_xfer_partial (struct target_ops *o
return -1;
}
}
+static void
+win32_terminal_inferior ()
+{
+ /* If the debuggee is not on the same console,
+ we don't need to do anything. */
+ if (start_flags & CREATE_NEW_CONSOLE)
+ return;
+ terminal_inferior ();
+}
+
+static void
+win32_terminal_ours_for_output ()
+{
+ /* If the debuggee is not on the same console,
+ we don't need to do anything. */
+ if (start_flags & CREATE_NEW_CONSOLE)
+ return;
+ terminal_ours_for_output ();
+}
+
+
+static void
+win32_terminal_ours ()
+{
+ /* If the debuggee is not on the same console,
+ we don't need to do anything. */
+ if (start_flags & CREATE_NEW_CONSOLE)
+ return;
+ terminal_ours ();
+}
static void
init_win32_ops (void)
@@ -2098,9 +2215,9 @@ init_win32_ops (void)
win32_ops.to_insert_breakpoint = memory_insert_breakpoint;
win32_ops.to_remove_breakpoint = memory_remove_breakpoint;
win32_ops.to_terminal_init = terminal_init_inferior;
- win32_ops.to_terminal_inferior = terminal_inferior;
- win32_ops.to_terminal_ours_for_output = terminal_ours_for_output;
- win32_ops.to_terminal_ours = terminal_ours;
+ win32_ops.to_terminal_inferior = win32_terminal_inferior;
+ win32_ops.to_terminal_ours_for_output = win32_terminal_ours_for_output;
+ win32_ops.to_terminal_ours = win32_terminal_ours;
win32_ops.to_terminal_save_ours = terminal_save_ours;
win32_ops.to_terminal_info = child_terminal_info;
win32_ops.to_kill = win32_kill_inferior;
next prev parent reply other threads:[~2008-06-24 8:08 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-21 17:05 [RFC] " Pierre Muller
2008-06-21 18:37 ` Christopher Faylor
2008-06-22 3:17 ` Daniel Jacobowitz
2008-06-22 3:18 ` Corinna Vinschen
2008-06-23 1:04 ` Christopher Faylor
2008-06-23 1:10 ` Corinna Vinschen
2008-06-23 7:40 ` Pierre Muller
2008-06-23 12:00 ` Christopher Faylor
2008-06-23 16:05 ` Pierre Muller
2008-06-23 17:00 ` Pedro Alves
2008-06-23 17:25 ` Pierre Muller
2008-06-23 18:03 ` Christopher Faylor
2008-06-23 19:24 ` Pedro Alves
2008-06-23 20:33 ` Pierre Muller
2008-06-23 21:06 ` Joel Brobecker
2008-06-24 6:33 ` Christopher Faylor
2008-06-24 13:36 ` Pierre Muller [this message]
2008-06-24 2:33 ` Christopher Faylor
2008-06-24 13:54 ` Pedro Alves
2008-06-24 18:29 ` Christopher Faylor
2008-06-22 9:00 ` Christopher Faylor
2008-06-23 8:52 ` [RFC v2] " Pierre Muller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='000a01c8d5d1$7201a250$5604e6f0$@u-strasbg.fr' \
--to=muller@ics.u-strasbg.fr \
--cc=brobecker@adacore.com \
--cc=gdb-patches@sourceware.org \
--cc=pedro@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox