Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Lerele <lerele@champenstudios.com>
To: gdb-patches@sourceware.org
Subject: [Patch] Win32 gdbserver new interrupt support, and attach to process  fix.
Date: Fri, 23 Feb 2007 23:52:00 -0000	[thread overview]
Message-ID: <45DF7E27.10102@champenstudios.com> (raw)


Hello,

I've added remote interrupt support for gdbserver on win32.
Also fixed gdbserver attach functionality, it wasn't even working at all.

Daniel, adding this support was much simpler than what I proposed some 
time ago.
You can also see I have added in server.h a new function so that win32 
code can call 'input_interrupt' function from remote-utils.c. I don't 
know if you're going to like that (having win32-i386-low.c call server 
code), but it needs to check for socket data availability, to be able to 
interrupt the child process.

Also, interrupt support is done by having the gdbserver constantly check 
(4 times a second) for debug events from child, and also check for 
socket data to interrupt it. This was how win32 gdbserver was working 
before anyway, except it was doing it once a second, and without 
checking socket data.
The alternative I think would be to, as Eli Zaretskii pointed out some 
days ago in gdb list, to have a separate thread check for socket 
availability and have it send the signal to the child, however this 
option would need some kind of thread synchronization to access 
gdbserver data from the thread (mainly read socket data from several 
threads).
It works fine as it is, without making it too complex. Only problem is 
that gdbserver may consume *some* cpu.

Hope patch is Ok.

Regards,
Leo.


PD: Patch follows:

2007-02-24    Leo Zayas
    * server.h, remote-utils.c: Expose input_interrupt through
    check_remote_input_interrupt_request for gdbserver.
    * win32-i386-low.c: Fix gdbserver attach support on win32.
    * win32-i386-low.c: Add remote interrupt support.
===================================================================
diff -u src_orig/gdb/gdbserver/remote-utils.c 
src/gdb/gdbserver/remote-utils.c
--- src_orig/gdb/gdbserver/remote-utils.c    2007-02-16 
21:01:14.000000000 +0100
+++ src/gdb/gdbserver/remote-utils.c    2007-02-23 23:53:44.796875000 +0100
@@ -78,7 +78,11 @@
 int remote_debug = 0;
 struct ui_file *gdb_stdlog;
 
-static int remote_desc;
+#ifdef USE_WIN32API
+static int remote_desc=INVALID_SOCKET;
+#else
+static int remote_desc=-1;
+#endif
 
 /* FIXME headerize? */
 extern int using_threads;
@@ -567,8 +571,6 @@
   return putpkt_binary (buf, strlen (buf));
 }
 
-#ifndef USE_WIN32API
-
 /* Come here when we get an input interrupt from the remote side.  This
    interrupt should only be active while we are waiting for the child to do
    something.  About the only thing that should come through is a ^C, which
@@ -580,16 +582,30 @@
   fd_set readset;
   struct timeval immediate = { 0, 0 };
 
+  /* We will be calling input_interrupt on win32 to check for remote 
interrupt,
+     via exposed function 'check_remote_input_interrupt_request'.
+     This function may be called before establishing communications;
+     need to validate socket object. */
+
+#ifdef USE_WIN32API
+  if (remote_desc==INVALID_SOCKET)
+    return;
+#else
+  if (remote_desc==-1)
+    return;
+#endif
+
   /* Protect against spurious interrupts.  This has been observed to
      be a problem under NetBSD 1.4 and 1.5.  */
-
+ 
   FD_ZERO (&readset);
   FD_SET (remote_desc, &readset);
+
   if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0)
     {
       int cc;
       char c = 0;
-     
+
       cc = read (remote_desc, &c, 1);
 
       if (cc != 1 || c != '\003')
@@ -602,7 +618,13 @@
       (*the_target->send_signal) (SIGINT);
     }
 }
-#endif
+
+/* Expose 'static void input_interrupt (int unused)' function to enable 
checking for a
+   remote interrupt request. */
+void check_remote_input_interrupt_request (void)
+{
+  input_interrupt(0);
+}
 
 /* Asynchronous I/O support.  SIGIO must be enabled when waiting, in 
order to
    accept Control-C from the client, and must be disabled when talking to
diff -u src_orig/gdb/gdbserver/server.h src/gdb/gdbserver/server.h
--- src_orig/gdb/gdbserver/server.h    2007-01-09 18:59:08.000000000 +0100
+++ src/gdb/gdbserver/server.h    2007-02-23 12:53:56.859375000 +0100
@@ -147,6 +147,7 @@
 void disable_async_io (void);
 void unblock_async_io (void);
 void block_async_io (void);
+void check_remote_input_interrupt_request (void);
 void convert_ascii_to_int (char *from, unsigned char *to, int n);
 void convert_int_to_ascii (unsigned char *from, char *to, int n);
 void new_thread_notify (int id);
diff -u src_orig/gdb/gdbserver/win32-i386-low.c 
src/gdb/gdbserver/win32-i386-low.c
--- src_orig/gdb/gdbserver/win32-i386-low.c    2007-01-09 
18:59:08.000000000 +0100
+++ src/gdb/gdbserver/win32-i386-low.c    2007-02-24 00:26:26.171875000 
+0100
@@ -37,6 +37,10 @@
 
 #define LOG 0
 
+#if LOG
+#include "../gdb_wait.h"
+#endif
+
 #define OUTMSG(X) do { printf X; fflush (stdout); } while (0)
 #if LOG
 #define OUTMSG2(X) do { printf X; fflush (stdout); } while (0)
@@ -238,7 +242,13 @@
 
   /* Nothing happened, but we stopped anyway.  This perhaps should be 
handled
      within target_wait, but I'm not sure target_wait should be 
resuming the
-     inferior.  */
+     inferior.
+
+     It should be safe to continue child given this wait status.
+     See function get_child_debug_event. Default wait status is spurious,
+     and it gets modified if any important debug events get received.
+     More specifically, this status gets returned in the wait loop to
+     allow socket pooling/resuming, to allow for remote interruption. */
   TARGET_WAITKIND_SPURIOUS,
 };
 
@@ -574,7 +584,7 @@
 
   FreeLibrary (kernel32);
 
-  return res;
+  return res? 0:-1;
 }
 
 /* Kill all inferiors.  */
@@ -840,7 +850,12 @@
   last_sig = TARGET_SIGNAL_0;
   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
 
-  if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
+  /* Check for remote interruption request */
+  check_remote_input_interrupt_request();
+
+  /* 250 ms wait time for debug event to allow for more precise
+     remote interruption. */
+  if (!(debug_event = WaitForDebugEvent (&current_event, 250)))
     goto out;
 
   current_inferior =
@@ -1004,6 +1019,10 @@
 
       return our_status.value.sig;
     }
+      else if (our_status.kind == TARGET_WAITKIND_SPURIOUS)
+    {
+      /* do nothing, just continue */
+    }
       else
     OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
 
@@ -1054,6 +1073,35 @@
   return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
 }
 
+/* Send a signal to the inferior process, however is appropriate. */
+static void
+win32_send_signal (int signo)
+{
+  if ( signo == TARGET_SIGNAL_INT )
+    {
+      if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, current_process_id))
+    {
+      /* fallback to XP/Vista 'DebugBreakProcess'.
+         GenerateConsoleCtrlEvent can fail if process id being debugged is
+         not a process group id.
+         Note if the above function fails, the code bellow will
+         generate a breakpoint exception to stop. */
+
+      typedef BOOL winapi_DebugBreakProcess(HANDLE);
+      HMODULE kernel32 = LoadLibrary ("KERNEL32.DLL");
+      winapi_DebugBreakProcess *DebugBreakProcess = NULL;
+      DebugBreakProcess =
+        (winapi_DebugBreakProcess *) GetProcAddress (kernel32,
+                             "DebugBreakProcess");
+      if (DebugBreakProcess==NULL || !DebugBreakProcess 
(current_process_handle))
+        {
+          OUTMSG ( ("Could not interrupt process.\n") );
+        }
+      FreeLibrary(kernel32);
+    }
+    }
+}
+
 static struct target_ops win32_target_ops = {
   win32_create_inferior,
   win32_attach,
@@ -1067,7 +1115,7 @@
   win32_read_inferior_memory,
   win32_write_inferior_memory,
   0,
-  0
+  win32_send_signal
 };
 
 /* Initialize the Win32 backend.  */


             reply	other threads:[~2007-02-23 23:52 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-23 23:52 Lerele [this message]
2007-02-24 12:07 ` Eli Zaretskii
2007-02-24 13:03   ` Lerele
2007-02-24 14:07     ` Eli Zaretskii
2007-02-24 15:23       ` Lerele
2007-02-24 19:10         ` Eli Zaretskii
2007-02-24 21:19         ` Pedro Alves
2007-02-24 21:44           ` Andreas Schwab
2007-02-24 23:35           ` Lerele
2007-02-25  0:15             ` Daniel Jacobowitz
2007-02-25  1:57             ` Pedro Alves
2007-02-25 22:46 ` Pedro Alves
2007-03-04 22:53   ` Lerele
2007-03-05  0:56     ` Pedro Alves
2007-03-05  1:21       ` Pedro Alves
2007-03-05 13:17       ` Lerele
2007-03-05 20:34         ` Lerele
2007-03-05 20:44         ` Pedro Alves
2007-03-06  0:04           ` Pedro Alves
2007-03-06 20:39           ` Pedro Alves
2007-03-06 22:18             ` Lerele
2007-03-06 23:22               ` Pedro Alves
2007-03-05 12:44     ` Daniel Jacobowitz
2007-03-05 20:30       ` Lerele

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=45DF7E27.10102@champenstudios.com \
    --to=lerele@champenstudios.com \
    --cc=gdb-patches@sourceware.org \
    /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