* win32-low.c (attaching): New global.
authorPedro Alves <palves@redhat.com>
Mon, 3 Dec 2007 01:42:06 +0000 (01:42 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 3 Dec 2007 01:42:06 +0000 (01:42 +0000)
(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/ChangeLog
gdb/gdbserver/win32-low.c

index f502138990691f055527a1361b4181c6e3353c6e..314ab0bfad7cbc5abe42b02391164e7df07790f5 100644 (file)
@@ -1,3 +1,12 @@
+2007-12-03  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.
+
 2007-12-03  Pedro Alves  <pedro_alves@portugalmail.pt>
 
        * server.c (main): Don't report dll events on the initial
index 3ff7c17e2bfebfb113f806fce69d5c75af8fd8e1..1c81804c2cfce8c17472cc68949eb49b806b6dce 100644 (file)
@@ -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;
@@ -498,6 +499,9 @@ win32_create_inferior (char *program, char **program_args)
   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");
 
@@ -600,6 +604,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);
@@ -1346,11 +1352,44 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
       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:
 
@@ -1398,12 +1437,16 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
 
       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;