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]

[non-stop] 06/10 Don't rely on ecs->wait_for_more before fetching an event


In async mode / fetch_inferior_event, ecs->wait_for_more is being
checked before fetching the pending event from the target, and if
not set, we clear some state to prepare for the new stepping
sequence.

void
fetch_inferior_event (void *client_data)
{
  struct execution_control_state *ecs = &ecss;

  if (!ecs->wait_some_more)
    {
      /* Fill in with reasonable starting values.  */
      init_execution_control_state (ecs);

      /* We'll update this if & when we switch to a new thread. */
      previous_inferior_ptid = inferior_ptid;

      overlay_cache_invalid = 1;

      /* We have to invalidate the registers BEFORE calling target_wait
         because they can be loaded from the target while in target_wait.
         This makes remote debugging a bit more efficient for those
         targets that provide critical registers as part of their normal
         status mechanism. */

      registers_changed ();
    }
...

This worked in all-stop mode, were this would catch the first
time fetch_inferior_event was reached after a normal_stop.  
In non-stop, that is not true anymore -- if we don't fix it,
we'll accidently clear the wrong thread's context, say
if the user switches threads, and wait_for_more happens to be false
due to another having stopped.  This patch fixes the issue by
moving the clearing code in question to `proceed'.

-- 
Pedro Alves
2008-06-15  Pedro Alves  <pedro@codesourcery.com>

	Don't rely on wait_for_more.

	* infrun.c (proceed): Clear the stepping state, set
	previous_inferior_ptid and clear infwait state.
	(wait_for_inferior): Don't clear the stepping state, set
	previous_inferior_ptid, or clear the infwait state here.
	(fetch_inferior_event): Don't clear the stepping state, set
	previous_inferior_ptid, or clear the infwait state here.  Don't
	condition on wait_for_more.

---
 gdb/infrun.c |   43 ++++++++++++++++---------------------------
 1 file changed, 16 insertions(+), 27 deletions(-)

Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2008-06-06 02:38:46.000000000 +0100
+++ src/gdb/infrun.c	2008-06-06 02:38:53.000000000 +0100
@@ -1284,6 +1284,15 @@ proceed (CORE_ADDR addr, enum target_sig
      updated correctly when the inferior is stopped.  */
   prev_pc = regcache_read_pc (get_current_regcache ());
 
+  /* Fill in with reasonable starting values.  */
+  init_thread_stepping_state (tss);
+
+  /* We'll update this if & when we switch to a new thread. */
+  previous_inferior_ptid = inferior_ptid;
+
+  /* Reset to normal state.  */
+  init_infwait_state ();
+
   /* Resume inferior.  */
   resume (oneproc || step || bpstat_should_step (), stop_signal);
 
@@ -1456,15 +1465,6 @@ wait_for_inferior (int treat_exec_as_sig
 
   ecs = &ecss;
 
-    /* Fill in with reasonable starting values.  */
-  init_thread_stepping_state (tss);
-
-    /* Reset to normal state.  */
-  init_infwait_state ();
-
-  /* We'll update this if & when we switch to a new thread. */
-  previous_inferior_ptid = inferior_ptid;
-
   overlay_cache_invalid = 1;
 
   /* We have to invalidate the registers BEFORE calling target_wait
@@ -1513,26 +1513,15 @@ fetch_inferior_event (void *client_data)
   struct execution_control_state ecss = ecss;
   struct execution_control_state *ecs = &ecss;
 
-  if (!ecs->wait_some_more)
-    {
-      /* Fill in with reasonable starting values.  */
-      init_thread_stepping_state (tcs);
-
-      init_infwait_state ();
-
-      /* We'll update this if & when we switch to a new thread. */
-      previous_inferior_ptid = inferior_ptid;
-
-      overlay_cache_invalid = 1;
+  overlay_cache_invalid = 1;
 
-      /* We have to invalidate the registers BEFORE calling target_wait
-         because they can be loaded from the target while in target_wait.
-         This makes remote debugging a bit more efficient for those
-         targets that provide critical registers as part of their normal
-         status mechanism. */
+  /* We have to invalidate the registers BEFORE calling target_wait
+     because they can be loaded from the target while in target_wait.
+     This makes remote debugging a bit more efficient for those
+     targets that provide critical registers as part of their normal
+     status mechanism. */
 
-      registers_changed ();
-    }
+  registers_changed ();
 
   if (deprecated_target_wait_hook)
     ecs->ptid =

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