diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/gdbserver/win32-low.c | 39 | ||||
-rw-r--r-- | gdb/gdbserver/win32-low.h | 7 |
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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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; |