Fix for PR threads/1048
authorChristopher Faylor <me+cygwin@cgf.cx>
Fri, 26 Dec 2003 04:29:22 +0000 (04:29 +0000)
committerChristopher Faylor <me+cygwin@cgf.cx>
Fri, 26 Dec 2003 04:29:22 +0000 (04:29 +0000)
* win32-nat.c (thread_info_struct): Add reload_context flag.
(thread_rec): Don't reload thread context here.  Just set a flag.
(do_child_fetch_inferior_registers): Reload thread context here if appropriate.
Avoid doing anything if current_thread is NULL thanks to strange Windows
behavior.
(child_fetch_inferior_registers): Avoid doing anything if current_thread is
NULL.
(do_child_store_inferior_registers): Ditto.
(child_store_inferior_registers): Ditto.
(child_kill_inferior): Ditto.
(fake_create_process): Pretend to create a process for pathological windows
attach situation.
(get_child_debug_event): Call fake_create_process when the first event noticed
is thread creation rather than process creation.
(child_attach): Always set attach_flag when attaching.
(child_create_inferior): Set attach_flag to zero since we're not attaching.

gdb/ChangeLog
gdb/win32-nat.c
gdb/windows-nat.c

index e0f06d912dc190134f304e24d0754db9211433a0..fc835801845919441350f61df35915704f58bb44 100644 (file)
@@ -1,3 +1,24 @@
+2003-12-25  Christopher Faylor  <cgf@redhat.com>
+
+       Fix for PR threads/1048
+       * win32-nat.c (thread_info_struct): Add reload_context flag.
+       (thread_rec): Don't reload thread context here.  Just set a flag.
+       (do_child_fetch_inferior_registers): Reload thread context here if
+       appropriate.  Avoid doing anything if current_thread is NULL thanks to
+       strange Windows behavior.
+       (child_fetch_inferior_registers): Avoid doing anything if
+       current_thread is NULL.
+       (do_child_store_inferior_registers): Ditto.
+       (child_store_inferior_registers): Ditto.
+       (child_kill_inferior): Ditto.
+       (fake_create_process): Pretend to create a process for pathological
+       windows attach situation.
+       (get_child_debug_event): Call fake_create_process when the first event
+       noticed is thread creation rather than process creation.
+       (child_attach): Always set attach_flag when attaching.
+       (child_create_inferior): Set attach_flag to zero since we're not
+       attaching.
+
 2003-12-25  Christopher Faylor  <cgf@redhat.com>
 
        * win32-nat.c (get_child_debug_event): Keep main thread id around even
index c29bcc0e829af2905cbccf8b25f260b39cae55e0..c28e26ad2c7cc15a777074219fd3ac6b8b59eb86 100644 (file)
@@ -108,6 +108,7 @@ typedef struct thread_info_struct
     HANDLE h;
     char *name;
     int suspend_count;
+    int reload_context;
     CONTEXT context;
     STACKFRAME sf;
   }
@@ -228,7 +229,6 @@ 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. */
@@ -246,19 +246,7 @@ thread_rec (DWORD id, int get_context)
              th->suspend_count = SuspendThread (th->h) + 1;
            else if (get_context < 0)
              th->suspend_count = -1;
-
-           th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
-           GetThreadContext (th->h, &th->context);
-           if (id == current_event.dwThreadId)
-             {
-               /* Copy dr values from that thread.  */
-               dr[0] = th->context.Dr0;
-               dr[1] = th->context.Dr1;
-               dr[2] = th->context.Dr2;
-               dr[3] = th->context.Dr3;
-               dr[6] = th->context.Dr6;
-               dr[7] = th->context.Dr7;
-             }
+           th->reload_context = 1;
          }
        return th;
       }
@@ -349,6 +337,24 @@ do_child_fetch_inferior_registers (int r)
   char *context_offset = ((char *) &current_thread->context) + mappings[r];
   long l;
 
+  if (!current_thread)
+    return;
+
+  if (current_thread->reload_context)
+    {
+      thread_info *th = current_thread;
+      th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
+      GetThreadContext (th->h, &th->context);
+      /* Copy dr values from that thread.  */
+      dr[0] = th->context.Dr0;
+      dr[1] = th->context.Dr1;
+      dr[2] = th->context.Dr2;
+      dr[3] = th->context.Dr3;
+      dr[6] = th->context.Dr6;
+      dr[7] = th->context.Dr7;
+      current_thread->reload_context = 0;
+    }
+
 #define I387_ST0_REGNUM I386_ST0_REGNUM
 
   if (r == I387_FISEG_REGNUM)
@@ -376,13 +382,16 @@ static void
 child_fetch_inferior_registers (int r)
 {
   current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
-  do_child_fetch_inferior_registers (r);
+  if (current_thread)
+    do_child_fetch_inferior_registers (r);
 }
 
 static void
 do_child_store_inferior_registers (int r)
 {
-  if (r >= 0)
+  if (!current_thread)
+    /* nothing to do */;
+  else if (r >= 0)
     regcache_collect (r, ((char *) &current_thread->context) + mappings[r]);
   else
     {
@@ -396,7 +405,8 @@ static void
 child_store_inferior_registers (int r)
 {
   current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
-  do_child_store_inferior_registers (r);
+  if (current_thread)
+    do_child_store_inferior_registers (r);
 }
 
 static int psapi_loaded = 0;
@@ -1179,7 +1189,7 @@ child_continue (DWORD continue_status, int id)
          th->suspend_count = 0;
          if (debug_registers_changed)
            {
-             /* Only change the value of the debug reisters */
+             /* Only change the value of the debug registers */
              th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
              th->context.Dr0 = dr[0];
              th->context.Dr1 = dr[1];
@@ -1197,6 +1207,17 @@ child_continue (DWORD continue_status, int id)
   return res;
 }
 
+DWORD
+fake_create_process ()
+{
+  current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
+                                       current_event.dwProcessId);
+  main_thread_id = current_event.dwThreadId;
+  current_thread = child_add_thread (main_thread_id,
+                                    current_event.u.CreateThread.hThread);
+  return main_thread_id;
+}
+
 /* Get the next event from the child.  Return 1 if the event requires
    handling by WFI (or whatever).
  */
@@ -1229,7 +1250,14 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
                     (unsigned) current_event.dwThreadId,
                     "CREATE_THREAD_DEBUG_EVENT"));
       if (saw_create != 1)
-       break;
+       {
+         if (!saw_create && attach_flag)
+           {
+             retval = ourstatus->value.related_pid = fake_create_process ();
+             saw_create++;
+           }
+         break;
+       }
       /* Record the existence of this thread */
       th = child_add_thread (current_event.dwThreadId,
                             current_event.u.CreateThread.hThread);
@@ -1245,8 +1273,6 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
                     (unsigned) current_event.dwProcessId,
                     (unsigned) current_event.dwThreadId,
                     "EXIT_THREAD_DEBUG_EVENT"));
-      if (saw_create != 1)
-       break;
       if (current_event.dwThreadId != main_thread_id)
        {
          child_delete_thread (current_event.dwThreadId);
@@ -1355,8 +1381,8 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
     CHECK (child_continue (continue_status, -1));
   else
     {
-      current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
       inferior_ptid = pid_to_ptid (retval);
+      current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
     }
 
 out:
@@ -1571,10 +1597,9 @@ child_attach (char *args, int from_tty)
     }
 
   if (has_detach_ability ())
-    {
-      attach_flag = 1;
-      DebugSetProcessKillOnExit (FALSE);
-    }
+    DebugSetProcessKillOnExit (FALSE);
+
+  attach_flag = 1;
 
   if (from_tty)
     {
@@ -1696,6 +1721,8 @@ child_create_inferior (char *exec_file, char *allargs, char **env)
   if (new_console)
     flags |= CREATE_NEW_CONSOLE;
 
+  attach_flag = 0;
+
   args = alloca (strlen (toexec) + strlen (allargs) + 2);
   strcpy (args, toexec);
   strcat (args, " ");
@@ -1897,7 +1924,8 @@ child_kill_inferior (void)
   CHECK (CloseHandle (current_process_handle));
 
   /* this may fail in an attached process so don't check. */
-  (void) CloseHandle (current_thread->h);
+  if (current_thread && current_thread->h)
+    (void) CloseHandle (current_thread->h);
   target_mourn_inferior ();    /* or just child_mourn_inferior? */
 }
 
@@ -2149,7 +2177,6 @@ cygwin_get_dr6 (void)
   return dr[6];
 }
 
-
 /* Determine if the thread referenced by "pid" is alive
    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
    it means that the pid has died.  Otherwise it is assumed to be alive. */
index c29bcc0e829af2905cbccf8b25f260b39cae55e0..c28e26ad2c7cc15a777074219fd3ac6b8b59eb86 100644 (file)
@@ -108,6 +108,7 @@ typedef struct thread_info_struct
     HANDLE h;
     char *name;
     int suspend_count;
+    int reload_context;
     CONTEXT context;
     STACKFRAME sf;
   }
@@ -228,7 +229,6 @@ 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. */
@@ -246,19 +246,7 @@ thread_rec (DWORD id, int get_context)
              th->suspend_count = SuspendThread (th->h) + 1;
            else if (get_context < 0)
              th->suspend_count = -1;
-
-           th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
-           GetThreadContext (th->h, &th->context);
-           if (id == current_event.dwThreadId)
-             {
-               /* Copy dr values from that thread.  */
-               dr[0] = th->context.Dr0;
-               dr[1] = th->context.Dr1;
-               dr[2] = th->context.Dr2;
-               dr[3] = th->context.Dr3;
-               dr[6] = th->context.Dr6;
-               dr[7] = th->context.Dr7;
-             }
+           th->reload_context = 1;
          }
        return th;
       }
@@ -349,6 +337,24 @@ do_child_fetch_inferior_registers (int r)
   char *context_offset = ((char *) &current_thread->context) + mappings[r];
   long l;
 
+  if (!current_thread)
+    return;
+
+  if (current_thread->reload_context)
+    {
+      thread_info *th = current_thread;
+      th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
+      GetThreadContext (th->h, &th->context);
+      /* Copy dr values from that thread.  */
+      dr[0] = th->context.Dr0;
+      dr[1] = th->context.Dr1;
+      dr[2] = th->context.Dr2;
+      dr[3] = th->context.Dr3;
+      dr[6] = th->context.Dr6;
+      dr[7] = th->context.Dr7;
+      current_thread->reload_context = 0;
+    }
+
 #define I387_ST0_REGNUM I386_ST0_REGNUM
 
   if (r == I387_FISEG_REGNUM)
@@ -376,13 +382,16 @@ static void
 child_fetch_inferior_registers (int r)
 {
   current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
-  do_child_fetch_inferior_registers (r);
+  if (current_thread)
+    do_child_fetch_inferior_registers (r);
 }
 
 static void
 do_child_store_inferior_registers (int r)
 {
-  if (r >= 0)
+  if (!current_thread)
+    /* nothing to do */;
+  else if (r >= 0)
     regcache_collect (r, ((char *) &current_thread->context) + mappings[r]);
   else
     {
@@ -396,7 +405,8 @@ static void
 child_store_inferior_registers (int r)
 {
   current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
-  do_child_store_inferior_registers (r);
+  if (current_thread)
+    do_child_store_inferior_registers (r);
 }
 
 static int psapi_loaded = 0;
@@ -1179,7 +1189,7 @@ child_continue (DWORD continue_status, int id)
          th->suspend_count = 0;
          if (debug_registers_changed)
            {
-             /* Only change the value of the debug reisters */
+             /* Only change the value of the debug registers */
              th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
              th->context.Dr0 = dr[0];
              th->context.Dr1 = dr[1];
@@ -1197,6 +1207,17 @@ child_continue (DWORD continue_status, int id)
   return res;
 }
 
+DWORD
+fake_create_process ()
+{
+  current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
+                                       current_event.dwProcessId);
+  main_thread_id = current_event.dwThreadId;
+  current_thread = child_add_thread (main_thread_id,
+                                    current_event.u.CreateThread.hThread);
+  return main_thread_id;
+}
+
 /* Get the next event from the child.  Return 1 if the event requires
    handling by WFI (or whatever).
  */
@@ -1229,7 +1250,14 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
                     (unsigned) current_event.dwThreadId,
                     "CREATE_THREAD_DEBUG_EVENT"));
       if (saw_create != 1)
-       break;
+       {
+         if (!saw_create && attach_flag)
+           {
+             retval = ourstatus->value.related_pid = fake_create_process ();
+             saw_create++;
+           }
+         break;
+       }
       /* Record the existence of this thread */
       th = child_add_thread (current_event.dwThreadId,
                             current_event.u.CreateThread.hThread);
@@ -1245,8 +1273,6 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
                     (unsigned) current_event.dwProcessId,
                     (unsigned) current_event.dwThreadId,
                     "EXIT_THREAD_DEBUG_EVENT"));
-      if (saw_create != 1)
-       break;
       if (current_event.dwThreadId != main_thread_id)
        {
          child_delete_thread (current_event.dwThreadId);
@@ -1355,8 +1381,8 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
     CHECK (child_continue (continue_status, -1));
   else
     {
-      current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
       inferior_ptid = pid_to_ptid (retval);
+      current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
     }
 
 out:
@@ -1571,10 +1597,9 @@ child_attach (char *args, int from_tty)
     }
 
   if (has_detach_ability ())
-    {
-      attach_flag = 1;
-      DebugSetProcessKillOnExit (FALSE);
-    }
+    DebugSetProcessKillOnExit (FALSE);
+
+  attach_flag = 1;
 
   if (from_tty)
     {
@@ -1696,6 +1721,8 @@ child_create_inferior (char *exec_file, char *allargs, char **env)
   if (new_console)
     flags |= CREATE_NEW_CONSOLE;
 
+  attach_flag = 0;
+
   args = alloca (strlen (toexec) + strlen (allargs) + 2);
   strcpy (args, toexec);
   strcat (args, " ");
@@ -1897,7 +1924,8 @@ child_kill_inferior (void)
   CHECK (CloseHandle (current_process_handle));
 
   /* this may fail in an attached process so don't check. */
-  (void) CloseHandle (current_thread->h);
+  if (current_thread && current_thread->h)
+    (void) CloseHandle (current_thread->h);
   target_mourn_inferior ();    /* or just child_mourn_inferior? */
 }
 
@@ -2149,7 +2177,6 @@ cygwin_get_dr6 (void)
   return dr[6];
 }
 
-
 /* Determine if the thread referenced by "pid" is alive
    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
    it means that the pid has died.  Otherwise it is assumed to be alive. */
This page took 0.050749 seconds and 4 git commands to generate.