This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] windows-nat.c Cygwin save_context fix


  Cygwin has a way to give a "fake" context for 
an exception using a OUTPUT_DEBUG_STRING_EVENT.

  While trying to debug some crashes inside cygwin dll,
I realized the the saved_context code has a problem.

  The saved context was correctly written to the thread_info
struct, but later overwritten by a call to GetThreadContext.
 
  After the cygwin special output_debug_string was correctly
converted into a context stored in saved_context.
  The next call to do_windows_fetch_inferior_registers
then copied this context to the thread_info struct,
set the reload_context field to zero.

  But a later call to thread_rec() with get_context=1
can reset reload_context to one, if suspended field
is zero (this only happens if it is not the main thread).

  My patch fixes the problem by explicitly calling
SuspendThread for the threaded of the saved_context
if suspended is still zero at that point.


Pierre Muller
Pascal language support maintainer for GDB



2009-09-21  Pierre Muller  <muller@ics.u-strasbg.fr>

	* src/gdb/windows-nat.c (saved_threadid): New variable.
	(do_windows_fetch_inferior_registers): Check for correct thread id
	and force call to SuspendThread if needed.
	(handle_output_debug_string): Set saved_threadid.

Index: src/gdb/windows-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/windows-nat.c,v
retrieving revision 1.196
diff -u -p -r1.196 windows-nat.c
--- src/gdb/windows-nat.c	2 Jul 2009 17:21:07 -0000	1.196
+++ src/gdb/windows-nat.c	21 Sep 2009 14:53:38 -0000
@@ -97,6 +98,7 @@ static CORE_ADDR cygwin_load_start;
 static CORE_ADDR cygwin_load_end;
 #endif
 
+static int saved_threadid;
 static int have_saved_context;	/* True if we've saved context from a cygwin
signal. */
 static CONTEXT saved_context;	/* Containes the saved context from a cygwin
signal. */
 
@@ -381,11 +383,23 @@ do_windows_fetch_inferior_registers (str
   if (current_thread->reload_context)
     {
 #ifdef __COPY_CONTEXT_SIZE
-      if (have_saved_context)
+      if (have_saved_context && current_thread->id == saved_threadid)
 	{
 	  /* Lie about where the program actually is stopped since cygwin
has informed us that
 	     we should consider the signal to have occurred at another
location which is stored
 	     in "saved_context. */
+	  if (!current_thread->suspended)
+	  /* Force suspend to avoid resetting reload_context
+	     later in get_thread.  */ 
+	    {
+	      if (SuspendThread (current_thread->h) == (DWORD) -1)
+		{
+		  DWORD err = GetLastError ();
+		  warning (_("SuspendThread failed. (winerr %d)"),
+		  	   (int) err);
+		}
+	      current_thread->suspended = 1;
+	    }
 	  memcpy (&current_thread->context, &saved_context,
__COPY_CONTEXT_SIZE);
 	  have_saved_context = 0;
 	}
@@ -863,6 +877,7 @@ handle_output_debug_string (struct targe
 					 &saved_context,
__COPY_CONTEXT_SIZE, &n)
 		   && n == __COPY_CONTEXT_SIZE)
 	    have_saved_context = 1;
+	  saved_threadid = retval;
 	  current_event.dwThreadId = retval;
 	}
     }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]