This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[non-stop] 06/10 Don't rely on ecs->wait_for_more before fetching an event
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Sun, 15 Jun 2008 22:05:02 +0100
- Subject: [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 =