aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/ChangeLog9
-rw-r--r--gdb/gdbserver/win32-low.c39
-rw-r--r--gdb/gdbserver/win32-low.h7
3 files changed, 51 insertions, 4 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index eb79471..2e9530a 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -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>
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index d125e9b..e0fb777 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -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;
}
}
diff --git a/gdb/gdbserver/win32-low.h b/gdb/gdbserver/win32-low.h
index c2bf06a..aad09dd 100644
--- a/gdb/gdbserver/win32-low.h
+++ b/gdb/gdbserver/win32-low.h
@@ -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;