* win32-low.c (win32_get_thread_context)
authorPedro Alves <palves@redhat.com>
Mon, 3 Dec 2007 01:27:19 +0000 (01:27 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 3 Dec 2007 01:27:19 +0000 (01:27 +0000)
(win32_set_thread_context): New functions.
(thread_rec): Use win32_get_thread_context.
(continue_one_thread, win32_resume): Use win32_set_thread_context.
* win32-low.h (win32_thread_info) [_WIN32_WCE]: Add `base_context'
field.

gdb/gdbserver/ChangeLog
gdb/gdbserver/win32-low.c
gdb/gdbserver/win32-low.h

index eb7947117847a64526f51d37f1fc5b5fdbc08344..2e9530a0e79b52a20f14d63daaea569b19a8dbc2 100644 (file)
@@ -1,3 +1,12 @@
+2007-12-03  Pedro Alves  <pedro_alves@portugalmail.pt>
+
+       * win32-low.c (win32_get_thread_context)
+       (win32_set_thread_context): New functions.
+       (thread_rec): Use win32_get_thread_context.
+       (continue_one_thread, win32_resume): Use win32_set_thread_context.
+       * win32-low.h (win32_thread_info) [_WIN32_WCE]: Add `base_context'
+       field.
+
 2007-12-03  Leo Zayas
            Pedro Alves  <pedro_alves@portugalmail.pt>
 
index d125e9bdccc77b260a03e3a6fc9b31ef1558e8e6..e0fb7772bfaf0b4b906f9e73b5ea3d59c26bcd71 100644 (file)
@@ -100,6 +100,39 @@ current_inferior_tid (void)
   return th->tid;
 }
 
+/* Get the thread context of the thread associated with TH.  */
+
+static void
+win32_get_thread_context (win32_thread_info *th)
+{
+  memset (&th->context, 0, sizeof (CONTEXT));
+  (*the_low_target.get_thread_context) (th, &current_event);
+#ifdef _WIN32_WCE
+  memcpy (&th->base_context, &th->context, sizeof (CONTEXT));
+#endif
+}
+
+/* Set the thread context of the thread associated with TH.  */
+
+static void
+win32_set_thread_context (win32_thread_info *th)
+{
+#ifdef _WIN32_WCE
+  /* Calling SuspendThread on a thread that is running kernel code
+     will report that the suspending was successful, but in fact, that
+     will often not be true.  In those cases, the context returned by
+     GetThreadContext will not be correct by the time the thread
+     stops, hence we can't set that context back into the thread when
+     resuming - it will most likelly crash the inferior.
+     Unfortunately, there is no way to know when the thread will
+     really stop.  To work around it, we'll only write the context
+     back to the thread when either the user or GDB explicitly change
+     it between stopping and resuming.  */
+  if (memcmp (&th->context, &th->base_context, sizeof (CONTEXT)) != 0)
+#endif
+    (*the_low_target.set_thread_context) (th, &current_event);
+}
+
 /* Find a thread record given a thread id.  If GET_CONTEXT is set then
    also retrieve the context for this thread.  */
 static win32_thread_info *
@@ -127,7 +160,7 @@ thread_rec (DWORD id, int get_context)
            th->suspended = 1;
        }
 
-      (*the_low_target.get_thread_context) (th, &current_event);
+      win32_get_thread_context (th);
     }
 
   return th;
@@ -281,7 +314,7 @@ continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
     {
       if (th->context.ContextFlags)
        {
-         (*the_low_target.set_thread_context) (th, &current_event);
+         win32_set_thread_context (th);
          th->context.ContextFlags = 0;
        }
 
@@ -806,7 +839,7 @@ win32_resume (struct thread_resume *resume_info)
                       "in this configuration.\n");
            }
 
-         (*the_low_target.set_thread_context) (th, &current_event);
+         win32_set_thread_context (th);
          th->context.ContextFlags = 0;
        }
     }
index c2bf06a3632b986b6732a48c97608345508366f4..aad09dd49bc908e3cdfcacf84d55f020c1e8293f 100644 (file)
@@ -31,7 +31,12 @@ typedef struct win32_thread_info
   /* Non zero if SuspendThread was called on this thread.  */
   int suspended;
 
-  /* The context of the thread.  */
+#ifdef _WIN32_WCE
+  /* The context as retrieved right after suspending the thread. */
+  CONTEXT base_context;
+#endif
+
+  /* The context of the thread, including any manipulations.  */
   CONTEXT context;
 } win32_thread_info;