diff options
author | Pedro Alves <palves@redhat.com> | 2007-11-24 12:13:28 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2007-11-24 12:13:28 +0000 |
commit | 6537bb249efc0e7279d4b23d2e9501e3416feb7f (patch) | |
tree | 2853ad16e09efa056012b2b60b4610464324cd6c /gdb/win32-nat.c | |
parent | 7129a489bd8d26554ebf7830d62a6eb95a0db7e8 (diff) | |
download | gdb-6537bb249efc0e7279d4b23d2e9501e3416feb7f.zip gdb-6537bb249efc0e7279d4b23d2e9501e3416feb7f.tar.gz gdb-6537bb249efc0e7279d4b23d2e9501e3416feb7f.tar.bz2 |
* win32-nat.c (DR6_CLEAR_VALUE): New define.
(thread_info_struct): Rename suspend_count to suspended, to be
used as a flag.
(thread_rec): Only suspend the thread if it wasn't suspended by
gdb before. Warn if suspending failed.
(win32_add_thread): Set Dr6 to DR6_CLEAR_VALUE.
(win32_continue): Set Dr6 to DR6_CLEAR_VALUE. Update usage of the
`suspended' flag. Do ContinueDebugEvent after resuming the
suspended threads, not before. Set threads' contexts before
resuming them, not after.
(win32_resume): Set Dr6 to DR6_CLEAR_VALUE.
Diffstat (limited to 'gdb/win32-nat.c')
-rw-r--r-- | gdb/win32-nat.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/gdb/win32-nat.c b/gdb/win32-nat.c index 6c76719..67082fa 100644 --- a/gdb/win32-nat.c +++ b/gdb/win32-nat.c @@ -91,6 +91,7 @@ enum static unsigned dr[8]; static int debug_registers_changed; static int debug_registers_used; +#define DR6_CLEAR_VALUE 0xffff0ff0 /* The string sent by cygwin when it processes a signal. FIXME: This should be in a cygwin include file. */ @@ -112,14 +113,14 @@ static enum target_signal last_sig = TARGET_SIGNAL_0; /* Set if a signal was received from the debugged process */ /* Thread information structure used to track information that is - not available in gdb's thread structure. */ + not available in gdb's thread structure. */ typedef struct thread_info_struct { struct thread_info_struct *next; DWORD id; HANDLE h; char *name; - int suspend_count; + int suspended; int reload_context; CONTEXT context; STACKFRAME sf; @@ -244,9 +245,9 @@ check (BOOL ok, const char *file, int line) GetLastError ()); } -/* Find a thread record given a thread id. - If get_context then also retrieve the context for this - thread. */ +/* Find a thread record given a thread id. If GET_CONTEXT is not 0, + then also retrieve the context for this thread. If GET_CONTEXT is + negative, then don't suspend the thread. */ static thread_info * thread_rec (DWORD id, int get_context) { @@ -255,12 +256,21 @@ thread_rec (DWORD id, int get_context) for (th = &thread_head; (th = th->next) != NULL;) if (th->id == id) { - if (!th->suspend_count && get_context) + if (!th->suspended && get_context) { if (get_context > 0 && id != current_event.dwThreadId) - th->suspend_count = SuspendThread (th->h) + 1; + { + if (SuspendThread (th->h) == (DWORD) -1) + { + DWORD err = GetLastError (); + warning (_("SuspendThread failed. (winerr %d)"), + (int) err); + return NULL; + } + th->suspended = 1; + } else if (get_context < 0) - th->suspend_count = -1; + th->suspended = -1; th->reload_context = 1; } return th; @@ -294,8 +304,7 @@ win32_add_thread (DWORD id, HANDLE h) th->context.Dr1 = dr[1]; th->context.Dr2 = dr[2]; th->context.Dr3 = dr[3]; - /* th->context.Dr6 = dr[6]; - FIXME: should we set dr6 also ?? */ + th->context.Dr6 = DR6_CLEAR_VALUE; th->context.Dr7 = dr[7]; CHECK (SetThreadContext (th->h, &th->context)); th->context.ContextFlags = 0; @@ -1122,32 +1131,34 @@ win32_continue (DWORD continue_status, int id) current_event.dwProcessId, current_event.dwThreadId, continue_status == DBG_CONTINUE ? "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED")); + + for (th = &thread_head; (th = th->next) != NULL;) + if ((id == -1 || id == (int) th->id) + && th->suspended) + { + if (debug_registers_changed) + { + th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS; + th->context.Dr0 = dr[0]; + th->context.Dr1 = dr[1]; + th->context.Dr2 = dr[2]; + th->context.Dr3 = dr[3]; + th->context.Dr6 = DR6_CLEAR_VALUE; + th->context.Dr7 = dr[7]; + } + if (th->context.ContextFlags) + { + CHECK (SetThreadContext (th->h, &th->context)); + th->context.ContextFlags = 0; + } + if (th->suspended > 0) + (void) ResumeThread (th->h); + th->suspended = 0; + } + res = ContinueDebugEvent (current_event.dwProcessId, current_event.dwThreadId, continue_status); - if (res) - for (th = &thread_head; (th = th->next) != NULL;) - if (((id == -1) || (id == (int) th->id)) && th->suspend_count) - { - - for (i = 0; i < th->suspend_count; i++) - (void) ResumeThread (th->h); - th->suspend_count = 0; - if (debug_registers_changed) - { - /* Only change the value of the debug registers */ - th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS; - th->context.Dr0 = dr[0]; - th->context.Dr1 = dr[1]; - th->context.Dr2 = dr[2]; - th->context.Dr3 = dr[3]; - /* th->context.Dr6 = dr[6]; - FIXME: should we set dr6 also ?? */ - th->context.Dr7 = dr[7]; - CHECK (SetThreadContext (th->h, &th->context)); - th->context.ContextFlags = 0; - } - } debug_registers_changed = 0; return res; @@ -1233,8 +1244,7 @@ win32_resume (ptid_t ptid, int step, enum target_signal sig) th->context.Dr1 = dr[1]; th->context.Dr2 = dr[2]; th->context.Dr3 = dr[3]; - /* th->context.Dr6 = dr[6]; - FIXME: should we set dr6 also ?? */ + th->context.Dr6 = DR6_CLEAR_VALUE; th->context.Dr7 = dr[7]; } CHECK (SetThreadContext (th->h, &th->context)); |