From 78a3fc32338171cb791512076e3696e62d08c33a Mon Sep 17 00:00:00 2001
From: Jon Turney <jon.turney@dronecode.org.uk>
Date: Tue, 12 Jan 2016 22:26:26 +0000
Subject: [PATCH 2/5] 7.8-windows-nat-cygwin

Remaining parts of 7.8-windows-nat-cygwin.patch not yet upstream.

Signal changes:

* Replace have_saved_context with signal_thread_id throughout, and store the
thread id in it

* In thread_rec(), only use the signal saved context if we are retrieving the
context for the correct thread.

* Clear ContextFlags in the signal saved context so we never attempt to restore
it to the inferior

Since the signal context is the context which will be restored after any signal
handler has been run, to resume to it skips over the actual signal delivery.

(Unfortunately, this isn't quite right.  If GDB decides it needs to single-step
after continuing by setting FLAG_TRACE_BIT, we must alter the inferior state. So
we potentially need to have both the signal saved context, and the actual
context for the thread.  Which is not a straightforward change to make.)

Unrelated changes:

* An unclear change for detecting if it's an unexpected Cygwin message. Just
checking for a leading 'cYg' should be enough?

* Cast DWORD thread_id to int before returning it from get_windows_event.
(I don't think this is needed.  If DWORD->int is a narrowing conversion, we
have other problems...)

* In one place, clarify that thread_rec()'s second parameter is a bool flag.
(This should be done everywhere, or not)
---
 gdb/windows-nat.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 108e1e32edc..a0faa058be7 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -176,8 +176,7 @@ static Wow64GetThreadSelectorEntry_ftype *Wow64GetThreadSelectorEntry;
 #   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 if we saved context. */
 #ifdef __CYGWIN__
 static CONTEXT saved_context;	/* Contains the saved context from a
 				   cygwin signal.  */
@@ -403,7 +402,7 @@ windows_nat::thread_rec (ptid_t ptid, thread_disposition_type disposition)
 		/* Nothing.  */
 		break;
 	      case INVALIDATE_CONTEXT:
-		if (ptid.lwp () != current_event.dwThreadId)
+		if (ptid.lwp () != current_event.dwThreadId && ptid.lwp () != signal_thread_id)
 		  th->suspend ();
 		th->reload_context = true;
 		break;
@@ -644,7 +643,7 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r)
   if (th->reload_context)
     {
 #ifdef __CYGWIN__
-      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
@@ -652,7 +651,7 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r)
 	     "saved_context.  */
 	  memcpy (&th->context, &saved_context,
 		  __COPY_CONTEXT_SIZE);
-	  have_saved_context = 0;
+	  signal_thread_id = 0;
 	}
       else
 #endif
@@ -997,7 +996,11 @@ windows_nat::handle_output_debug_string (struct target_waitstatus *ourstatus)
   else if (!startswith (s.get (), _CYGWIN_SIGNAL_STRING))
     {
 #ifdef __CYGWIN__
-      if (!startswith (s.get (), "cYg"))
+      /* This looks like this is supposed to ignore all other expected Cygwin
+	 debug output (e.g. handle and strace output), but isn't quite right as
+	 strace output might be indicated by any 8 digit hex address. */
+      if (!startswith (s.get (), "cYg") || (strncmp (s.get () + 3, "FFFFFFFF", 8) != 0
+				     && strncmp (s.get () + 3, "std", 3) != 0))
 #endif
 	{
 	  char *p = strchr (s.get (), '\0');
@@ -1036,7 +1039,12 @@ windows_nat::handle_output_debug_string (struct target_waitstatus *ourstatus)
 					 &saved_context,
 					 __COPY_CONTEXT_SIZE, &n)
 		   && n == __COPY_CONTEXT_SIZE)
-	    have_saved_context = 1;
+	    {
+	      signal_thread_id = retval;
+	      saved_context.ContextFlags = 0;  /* Don't attempt to call SetContext */
+	    }
+	  else
+	    retval = 0;
 	}
     }
 #endif
@@ -1563,7 +1571,6 @@ windows_nat_target::get_windows_debug_event (int pid,
 
   event_code = current_event.dwDebugEventCode;
   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
-  have_saved_context = 0;
 
   switch (event_code)
     {
@@ -1765,7 +1772,7 @@ windows_nat_target::get_windows_debug_event (int pid,
     }
 
 out:
-  return thread_id;
+  return (int) thread_id;
 }
 
 /* Wait for interesting events to occur in the target process.  */
-- 
2.31.1.windows.1

