This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] Fixes to Cygwin-specific signal handling
- From: Jon Turney <jon dot turney at dronecode dot org dot uk>
- To: gdb-patches at sourceware dot org
- Cc: Jon Turney <jon dot turney at dronecode dot org dot uk>
- Date: Tue, 14 Apr 2015 12:03:02 +0100
- Subject: [PATCH] Fixes to Cygwin-specific signal handling
- Authentication-results: sourceware.org; auth=none
Originally by cgf, this patch has been carried in Cygwin's gdb package for a few
years. I've cleaned it up a bit and revised it for master.
Without this patch, it's impossible to usefully run the testsuite on Cygwin.
gdb/ChangeLog:
2015-04-11 Jon Turney <jon.turney@dronecode.org.uk>
* windows-nat.c: Replace have_saved_context with signal_thread_id
throughout.
(thread_rec): Don't retrieve context if we have a saved one.
Ignore 'Invalid Handle' errors.
(handle_output_debug_string): Mark signal context as not to be
written to inferior by windows_continue() or windows_resume().
(get_windows_debug_event): Replace retval with thread_id
throughout. Don't clear any saved context.
---
gdb/ChangeLog | 11 +++++++++++
gdb/windows-nat.c | 55 +++++++++++++++++++++++++++++++------------------------
2 files changed, 42 insertions(+), 24 deletions(-)
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index fd31083..5c191de 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -118,8 +118,8 @@ static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD);
# define bad_GetModuleFileNameEx bad_GetModuleFileNameExW
#endif
-static int have_saved_context; /* True if we've saved context from a
- cygwin signal. */
+static DWORD signal_thread_id; /* Non-zero thread id if we have a saved
+ context from a cygwin signal. */
static CONTEXT saved_context; /* Containes the saved context from a
cygwin signal. */
@@ -301,7 +301,8 @@ thread_rec (DWORD id, int get_context)
{
if (!th->suspended && get_context)
{
- if (get_context > 0 && id != current_event.dwThreadId)
+ if (get_context > 0 && id != current_event.dwThreadId
+ && id != signal_thread_id)
{
if (SuspendThread (th->h) == (DWORD) -1)
{
@@ -310,8 +311,11 @@ thread_rec (DWORD id, int get_context)
/* We get Access Denied (5) when trying to suspend
threads that Windows started on behalf of the
debuggee, usually when those threads are just
- about to exit. */
- if (err != ERROR_ACCESS_DENIED)
+ about to exit.
+ We can get Invalid Handle (6) if the main thread
+ has exited. */
+ if (err != ERROR_INVALID_HANDLE
+ && err != ERROR_ACCESS_DENIED)
warning (_("SuspendThread (tid=0x%x) failed."
" (winerr %u)"),
(unsigned) id, (unsigned) err);
@@ -433,7 +437,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
if (current_thread->reload_context)
{
#ifdef __COPY_CONTEXT_SIZE
- if (have_saved_context)
+ if (signal_thread_id)
{
/* Lie about where the program actually is stopped since
cygwin has informed us that we should consider the signal
@@ -441,7 +445,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
"saved_context. */
memcpy (¤t_thread->context, &saved_context,
__COPY_CONTEXT_SIZE);
- have_saved_context = 0;
+ signal_thread_id = 0;
}
else
#endif
@@ -849,8 +853,12 @@ handle_output_debug_string (struct target_waitstatus *ourstatus)
&saved_context,
__COPY_CONTEXT_SIZE, &n)
&& n == __COPY_CONTEXT_SIZE)
- have_saved_context = 1;
- current_event.dwThreadId = retval;
+ {
+ signal_thread_id = retval;
+ saved_context.ContextFlags = 0; /* Don't attempt to call SetThreadContext */
+ }
+ else
+ retval = 0;
}
}
#endif
@@ -1317,7 +1325,7 @@ get_windows_debug_event (struct target_ops *ops,
DWORD continue_status, event_code;
windows_thread_info *th;
static windows_thread_info dummy_thread_info;
- int retval = 0;
+ DWORD thread_id = 0;
last_sig = GDB_SIGNAL_0;
@@ -1330,7 +1338,6 @@ get_windows_debug_event (struct target_ops *ops,
event_code = current_event.dwDebugEventCode;
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
th = NULL;
- have_saved_context = 0;
switch (event_code)
{
@@ -1348,14 +1355,14 @@ get_windows_debug_event (struct target_ops *ops,
/* Kludge around a Windows bug where first event is a create
thread event. Caused when attached process does not have
a main thread. */
- retval = fake_create_process ();
- if (retval)
+ thread_id = fake_create_process ();
+ if (thread_id)
saw_create++;
}
break;
}
/* Record the existence of this thread. */
- retval = current_event.dwThreadId;
+ thread_id = current_event.dwThreadId;
th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
current_event.dwThreadId),
current_event.u.CreateThread.hThread,
@@ -1398,7 +1405,7 @@ get_windows_debug_event (struct target_ops *ops,
current_event.dwThreadId),
current_event.u.CreateProcessInfo.hThread,
current_event.u.CreateProcessInfo.lpThreadLocalBase);
- retval = current_event.dwThreadId;
+ thread_id = current_event.dwThreadId;
break;
case EXIT_PROCESS_DEBUG_EVENT:
@@ -1417,7 +1424,7 @@ get_windows_debug_event (struct target_ops *ops,
{
ourstatus->kind = TARGET_WAITKIND_EXITED;
ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
- retval = main_thread_id;
+ thread_id = main_thread_id;
}
break;
@@ -1432,7 +1439,7 @@ get_windows_debug_event (struct target_ops *ops,
catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
ourstatus->kind = TARGET_WAITKIND_LOADED;
ourstatus->value.integer = 0;
- retval = main_thread_id;
+ thread_id = main_thread_id;
break;
case UNLOAD_DLL_DEBUG_EVENT:
@@ -1445,7 +1452,7 @@ get_windows_debug_event (struct target_ops *ops,
catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
ourstatus->kind = TARGET_WAITKIND_LOADED;
ourstatus->value.integer = 0;
- retval = main_thread_id;
+ thread_id = main_thread_id;
break;
case EXCEPTION_DEBUG_EVENT:
@@ -1461,7 +1468,7 @@ get_windows_debug_event (struct target_ops *ops,
continue_status = DBG_EXCEPTION_NOT_HANDLED;
break;
case 1:
- retval = current_event.dwThreadId;
+ thread_id = current_event.dwThreadId;
break;
case -1:
last_sig = 1;
@@ -1477,7 +1484,7 @@ get_windows_debug_event (struct target_ops *ops,
"OUTPUT_DEBUG_STRING_EVENT"));
if (saw_create != 1)
break;
- retval = handle_output_debug_string (ourstatus);
+ thread_id = handle_output_debug_string (ourstatus);
break;
default:
@@ -1491,7 +1498,7 @@ get_windows_debug_event (struct target_ops *ops,
break;
}
- if (!retval || saw_create != 1)
+ if (!thread_id || saw_create != 1)
{
if (continue_status == -1)
windows_resume (ops, minus_one_ptid, 0, 1);
@@ -1501,12 +1508,12 @@ get_windows_debug_event (struct target_ops *ops,
else
{
inferior_ptid = ptid_build (current_event.dwProcessId, 0,
- retval);
- current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
+ thread_id);
+ current_thread = th ?: thread_rec (thread_id, TRUE);
}
out:
- return retval;
+ return (int) thread_id;
}
/* Wait for interesting events to occur in the target process. */
--
2.1.4