This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gdbserver] (11/11) Windows CE process attaching support


Hi,

One of the Debug API differences between Windows CE and
other versions of Windows, is that the inferior isn't automatically
stopped either when running or attaching.  On the desktop, Windows
arranges for a breakpoint to be set before the entry point is ran,
or after reporting the loaded dlls and running threads when
attaching.
For the run case, I'm already handling it by having gdbserver
setting a breakpoing at the entry point, and removing it
when it is hit, so gdb never sees it.

The attach case wasn't working yet.  We can reuse the new
interrupt method to stop the inferior when that patch goes in.
One quirk is knowing when to stop the inferior.  There's a
comment in the patch explaining it.  It's not perfect, but it
has been working here for a while.

Cheers,
Pedro Alves



2007-11-12  Pedro Alves  <pedro_alves@portugalmail.pt>

	* win32-low.c (attaching): New global.
	(win32_create_inferior): Clear the `attaching' global.
	(win32_attach): Set the `attaching' global.
	(get_child_debug_event) [_WIN32_WCE]: Stop the inferior when
	attaching.  Only set a breakpoint at the entry point if not
	attaching.

---
 gdb/gdbserver/win32-low.c |   65 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 54 insertions(+), 11 deletions(-)

Index: src/gdb/gdbserver/win32-low.c
===================================================================
--- src.orig/gdb/gdbserver/win32-low.c	2007-11-12 00:20:38.000000000 +0000
+++ src/gdb/gdbserver/win32-low.c	2007-11-12 00:21:52.000000000 +0000
@@ -65,6 +65,7 @@
 int using_threads = 1;
 
 /* Globals.  */
+static int attaching = 0;
 static HANDLE current_process_handle = NULL;
 static DWORD current_process_id = 0;
 static enum target_signal last_sig = TARGET_SIGNAL_0;
@@ -670,6 +671,9 @@ win32_create_inferior (char *program, ch
   PROCESS_INFORMATION pi;
   DWORD err;
 
+  /* win32_wait needs to know we're not attaching.  */
+  attaching = 0;
+
   if (!program)
     error ("No executable specified, specify executable to debug.\n");
 
@@ -772,6 +776,8 @@ win32_attach (unsigned long pid)
 	  if (DebugSetProcessKillOnExit != NULL)
 	    DebugSetProcessKillOnExit (FALSE);
 
+	  /* win32_wait needs to know we're attaching.  */
+ 	  attaching = 1;
 	  current_process_handle = h;
 	  current_process_id = pid;
 	  do_initial_child_stuff (pid);
@@ -1524,11 +1530,44 @@ get_child_debug_event (struct target_wai
       goto gotevent;
     }
 
-  /* Keep the wait time low enough for confortable remote
-     interruption, but high enough so gdbserver doesn't become a
-     bottleneck.  */
-  if (!WaitForDebugEvent (&current_event, 250))
-    return 0;
+#ifndef _WIN32_WCE
+  attaching = 0;
+#else
+  if (attaching)
+    {
+      /* WinCE doesn't set an initial breakpoint automatically.  To
+ 	 stop the inferior, we flush all currently pending debug
+ 	 events -- the thread list and the dll list are always
+ 	 reported immediatelly without delay, then, we suspend all
+ 	 threads and pretend we saw a trap at the current PC of the
+ 	 main thread.
+
+ 	 Contrary to desktop Windows, Windows CE *does* report the dll
+ 	 names on LOAD_DLL_DEBUG_EVENTs resulting from a
+ 	 DebugActiveProcess call.  This limits the way we can detect
+ 	 if all the dlls have already been reported.  If we get a real
+ 	 debug event before leaving attaching, the worst that will
+ 	 happen is the user will see a spurious breakpoint.  */
+
+      current_event.dwDebugEventCode = 0;
+      if (!WaitForDebugEvent (&current_event, 0))
+ 	{
+ 	  OUTMSG2(("no attach events left\n"));
+ 	  fake_breakpoint_event ();
+ 	  attaching = 0;
+ 	}
+      else
+ 	OUTMSG2(("got attach event\n"));
+    }
+  else
+#endif
+    {
+      /* Keep the wait time low enough for confortable remote
+ 	 interruption, but high enough so gdbserver doesn't become a
+ 	 bottleneck.  */
+      if (!WaitForDebugEvent (&current_event, 250))
+ 	return 0;
+    }
 
  gotevent:
 
@@ -1576,12 +1615,16 @@ get_child_debug_event (struct target_wai
 
       ourstatus->value.related_pid = current_event.dwThreadId;
 #ifdef _WIN32_WCE
-      /* Windows CE doesn't set the initial breakpoint automatically
-	 like the desktop versions of Windows do.  We add it explicitly
-	 here.  It will be removed as soon as it is hit.  */
-      set_breakpoint_at ((CORE_ADDR) (long) current_event.u
-			 .CreateProcessInfo.lpStartAddress,
-			 delete_breakpoint_at);
+      if (!attaching)
+	{
+	  /* Windows CE doesn't set the initial breakpoint
+	     automatically like the desktop versions of Windows do.
+	     We add it explicitly here.	 It will be removed as soon as
+	     it is hit.	 */
+	  set_breakpoint_at ((CORE_ADDR) (long) current_event.u
+			     .CreateProcessInfo.lpStartAddress,
+			     delete_breakpoint_at);
+	}
 #endif
       break;
 



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]