This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC: 6/9] Make step_multi per-thread in all-stop, and don't context-switch it
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Sat, 16 Aug 2008 16:36:52 +0100
- Subject: [RFC: 6/9] Make step_multi per-thread in all-stop, and don't context-switch it
This patch removes the global step_multi, in favour of accessing
the equivalent member in thread_info. This is already per-thread in
non-stop, and this patch makes it per-thread in all-stop too.
I don't think there's much to say here, except that in async all-stop
mode, if while we're doing a multi-step, another thread stops at
a breakpoint, the original multi-step is cancelled. The way it
works currently, is that in all-stop, continuations are global, not
per-thread, so the step_1_continuation is always called in that case.
The continuation itself is responsible to detect that the
multi-step is to be cancelled. Further ahead, I'll be making
continuations per-thread in all-stop too, but this will still work,
as in all-stop, when the inferior stops, I'll run the continuations
of all threads.
--
Pedro Alves
2008-08-16 Pedro Alves <pedro@codesourcery.com>
Remove the global step_multi in favour of a per-thread
step_multi.
* inferior.h (step_multi): Delete.
* gdbthread.h (struct thread_info): Add comments around
step_multi.
(save_infrun_state, load_infrun_state): Remove step_multi
parameter.
* thread.c (load_infrun_state, save_infrun_state): Remove
step_multi argument, and references to it.
* infcmd.c (step_multi): Delete.
(step_1): Adjust.
(step_1_continuation, until_next_command): Adjust.
* infrun.c (fetch_inferior_event): Adjust.
(context_switch): Don't context-switch step_multi.
(print_stop_reason, normal_stop): Adjust.
---
gdb/gdbthread.h | 9 +++++----
gdb/infcmd.c | 37 ++++++++++++++++++++-----------------
gdb/inferior.h | 6 ------
gdb/infrun.c | 26 ++++++++++++++++++--------
gdb/thread.c | 8 ++------
5 files changed, 45 insertions(+), 41 deletions(-)
Index: src/gdb/inferior.h
===================================================================
--- src.orig/gdb/inferior.h 2008-08-16 16:13:44.000000000 +0100
+++ src/gdb/inferior.h 2008-08-16 16:17:09.000000000 +0100
@@ -311,12 +311,6 @@ enum step_over_calls_kind
STEP_OVER_UNDEBUGGABLE
};
-/* If stepping, nonzero means step count is > 1
- so don't print frame next time inferior stops
- if it stops due to stepping. */
-
-extern int step_multi;
-
/* Anything but NO_STOP_QUIETLY means we expect a trap and the caller
will handle it themselves. STOP_QUIETLY is used when running in
the shell before the child program has been exec'd and when running
Index: src/gdb/gdbthread.h
===================================================================
--- src.orig/gdb/gdbthread.h 2008-08-16 16:13:44.000000000 +0100
+++ src/gdb/gdbthread.h 2008-08-16 16:17:09.000000000 +0100
@@ -147,6 +147,9 @@ struct thread_info
enum step_over_calls_kind step_over_calls;
int stop_step;
+
+ /* If stepping, nonzero means step count is > 1 so don't print frame
+ next time inferior stops if it stops due to stepping. */
int step_multi;
/* Last signal that the inferior received (why it stopped). */
@@ -224,16 +227,14 @@ extern int thread_count (void);
extern void save_infrun_state (ptid_t ptid,
struct continuation *continuations,
struct continuation *intermediate_continuations,
- int stop_step,
- int step_multi);
+ int stop_step);
/* infrun context switch: load the debugger state previously saved
for the given thread. */
extern void load_infrun_state (ptid_t ptid,
struct continuation **continuations,
struct continuation **intermediate_continuations,
- int *stop_step,
- int *step_multi);
+ int *stop_step);
/* Switch from one thread to another. */
extern void switch_to_thread (ptid_t ptid);
Index: src/gdb/thread.c
===================================================================
--- src.orig/gdb/thread.c 2008-08-16 16:13:44.000000000 +0100
+++ src/gdb/thread.c 2008-08-16 16:17:09.000000000 +0100
@@ -445,8 +445,7 @@ void
load_infrun_state (ptid_t ptid,
struct continuation **continuations,
struct continuation **intermediate_continuations,
- int *stop_step,
- int *step_multi)
+ int *stop_step)
{
struct thread_info *tp;
@@ -465,7 +464,6 @@ load_infrun_state (ptid_t ptid,
*intermediate_continuations = tp->intermediate_continuations;
tp->intermediate_continuations = NULL;
*stop_step = tp->stop_step;
- *step_multi = tp->step_multi;
}
}
@@ -475,8 +473,7 @@ void
save_infrun_state (ptid_t ptid,
struct continuation *continuations,
struct continuation *intermediate_continuations,
- int stop_step,
- int step_multi)
+ int stop_step)
{
struct thread_info *tp;
@@ -493,7 +490,6 @@ save_infrun_state (ptid_t ptid,
tp->continuations = continuations;
tp->intermediate_continuations = intermediate_continuations;
tp->stop_step = stop_step;
- tp->step_multi = step_multi;
}
}
Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c 2008-08-16 16:13:44.000000000 +0100
+++ src/gdb/infcmd.c 2008-08-16 16:17:09.000000000 +0100
@@ -169,12 +169,6 @@ int stop_stack_dummy;
int stopped_by_random_signal;
-/* If stepping, nonzero means step count is > 1
- so don't print frame next time inferior stops
- if it stops due to stepping. */
-
-int step_multi;
-
/* Environment to use for running inferior,
in format described in environ.h. */
@@ -852,7 +846,7 @@ which has no line number information.\n"
if (skip_subroutines)
tp->step_over_calls = STEP_OVER_ALL;
- step_multi = (count > 1);
+ tp->step_multi = (count > 1);
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
if (!stop_step)
@@ -893,16 +887,25 @@ step_1_continuation (void *args)
{
struct step_1_continuation_args *a = args;
- if (!step_multi || !stop_step)
+ if (target_has_execution)
{
- /* If we stopped for some reason that is not stepping there are
- no further steps to make. Cleanup. */
- if (!a->single_inst || a->skip_subroutines)
- delete_longjmp_breakpoint (a->thread);
- step_multi = 0;
+ struct thread_info *tp;
+
+ tp = inferior_thread ();
+ if (tp->step_multi && stop_step)
+ {
+ /* There are more steps to make, and we did stop due to
+ ending a stepping range. Do another step. */
+ step_once (a->skip_subroutines, a->single_inst, a->count - 1, a->thread);
+ return;
+ }
+ tp->step_multi = 0;
}
- else
- step_once (a->skip_subroutines, a->single_inst, a->count - 1, a->thread);
+
+ /* We either stopped for some reason that is not stepping, or there
+ are no further steps to make. Cleanup. */
+ if (!a->single_inst || a->skip_subroutines)
+ delete_longjmp_breakpoint (a->thread);
}
/* Do just one step operation. If count >1 we will have to set up a
@@ -970,7 +973,7 @@ which has no line number information.\n"
if (skip_subroutines)
tp->step_over_calls = STEP_OVER_ALL;
- step_multi = (count > 1);
+ inferior_thread ()->step_multi = (count > 1);
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
args = xmalloc (sizeof (*args));
@@ -1201,7 +1204,7 @@ until_next_command (int from_tty)
tp->step_over_calls = STEP_OVER_ALL;
tp->step_frame_id = get_frame_id (frame);
- step_multi = 0; /* Only one call to proceed */
+ tp->step_multi = 0; /* Only one call to proceed */
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
}
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c 2008-08-16 16:14:01.000000000 +0100
+++ src/gdb/infrun.c 2008-08-16 16:17:09.000000000 +0100
@@ -1641,7 +1641,11 @@ fetch_inferior_event (void *client_data)
if (stop_soon == NO_STOP_QUIETLY)
normal_stop ();
- if (step_multi && stop_step)
+ if (target_has_execution
+ && ecs->ws.kind != TARGET_WAITKIND_EXITED
+ && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
+ && ecs->event_thread->step_multi
+ && stop_step)
inferior_event_handler (INF_EXEC_CONTINUE, NULL);
else
inferior_event_handler (INF_EXEC_COMPLETE, NULL);
@@ -1724,14 +1728,12 @@ context_switch (ptid_t ptid)
/* Save infrun state for the old thread. */
save_infrun_state (inferior_ptid,
cmd_continuation, intermediate_continuation,
- stop_step,
- step_multi);
+ stop_step);
/* Load infrun state for the new thread. */
load_infrun_state (ptid,
&cmd_continuation, &intermediate_continuation,
- &stop_step,
- &step_multi);
+ &stop_step);
}
switch_to_thread (ptid);
@@ -3669,7 +3671,7 @@ print_stop_reason (enum inferior_stop_re
/* For now print nothing. */
/* Print a message only if not in the middle of doing a "step n"
operation for n > 1 */
- if (!step_multi || !stop_step)
+ if (!inferior_thread ()->step_multi || !stop_step)
if (ui_out_is_mi_like_p (uiout))
ui_out_field_string
(uiout, "reason",
@@ -3818,7 +3820,11 @@ Further execution is probably impossible
/* Don't print a message if in the middle of doing a "step n"
operation for n > 1 */
- if (step_multi && stop_step)
+ if (target_has_execution
+ && last.kind != TARGET_WAITKIND_SIGNALLED
+ && last.kind != TARGET_WAITKIND_EXITED
+ && inferior_thread ()->step_multi
+ && stop_step)
goto done;
target_terminal_ours ();
@@ -3968,7 +3974,11 @@ Further execution is probably impossible
done:
annotate_stopped ();
- if (!suppress_stop_observer && !step_multi)
+ if (!suppress_stop_observer
+ && !(target_has_execution
+ && last.kind != TARGET_WAITKIND_SIGNALLED
+ && last.kind != TARGET_WAITKIND_EXITED
+ && inferior_thread ()->step_multi))
{
if (!ptid_equal (inferior_ptid, null_ptid))
observer_notify_normal_stop (inferior_thread ()->stop_bpstat);