* inferior.h (stop_bpstat): Delete.

* breakpoint.h (bpstat_do_actions): Remove bpstat* argument.

	* breakpoint.c (bpstat_do_actions): Rename to ...
	(bpstat_do_actions_1): ... this.  Make static.  Change return type
	to int.  Return true if a breakpoint proceeded.
	(bpstat_do_actions): New, as wrapper around bpstat_do_actions_1.
	(delete_breakpoint): Don't reference the global stop_bpstat; it's
	gone.

	* gdbthread.h (struct thread_info): Add stop_bpstat.
	(save_infrun_state, load_infrun_state): Remove stop_bpstat
	argument.
	* thread.c (load_infrun_state, save_infrun_state): Remove
	stop_bpstat argument, and the code referencing it.

	* infcall.c: Include "gdbthread.h".
	(call_function_by_hand): Adjust.
	* exceptions.c: Include "gdbthread.h".
	(throw_exception): Adjust.
	* infcmd.c (stop_bpstat): Delete.
	(continue_command): In all-stop, set the ignore count on the
	thread that reported the stop.  In non-stop, set it on the current
	thread.
	(finish_command_continuation): Adjust.
	(program_info): Adjust.
	* infrun.c (clear_proceed_status): Adjust.
	(context_switch): Don't context-switch stop_bpstat.
	(handle_inferior_event): Adjust.
	(normal_stop): Adjust.
	(save_inferior_status, restore_inferior_status): Adjust.

	* inf-loop.c (inferior_event_handler): Remove parameter to
	bpstat_do_actions call.
	* top.c (command_loop): Remove parameter to bpstat_do_actions
	call.  Call it unconditionally.
	* event-top.c (command_handler): Ditto.
	* python/python.c (execute_gdb_command): Ditto.
This commit is contained in:
Pedro Alves 2008-09-08 21:46:21 +00:00
parent 078130d0ca
commit 347bddb745
14 changed files with 214 additions and 141 deletions

View file

@ -1,3 +1,45 @@
2008-09-08 Pedro Alves <pedro@codesourcery.com>
* inferior.h (stop_bpstat): Delete.
* breakpoint.h (bpstat_do_actions): Remove bpstat* argument.
* breakpoint.c (bpstat_do_actions): Rename to ...
(bpstat_do_actions_1): ... this. Make static. Change return type
to int. Return true if a breakpoint proceeded.
(bpstat_do_actions): New, as wrapper around bpstat_do_actions_1.
(delete_breakpoint): Don't reference the global stop_bpstat; it's
gone.
* gdbthread.h (struct thread_info): Add stop_bpstat.
(save_infrun_state, load_infrun_state): Remove stop_bpstat
argument.
* thread.c (load_infrun_state, save_infrun_state): Remove
stop_bpstat argument, and the code referencing it.
* infcall.c: Include "gdbthread.h".
(call_function_by_hand): Adjust.
* exceptions.c: Include "gdbthread.h".
(throw_exception): Adjust.
* infcmd.c (stop_bpstat): Delete.
(continue_command): In all-stop, set the ignore count on the
thread that reported the stop. In non-stop, set it on the current
thread.
(finish_command_continuation): Adjust.
(program_info): Adjust.
* infrun.c (clear_proceed_status): Adjust.
(context_switch): Don't context-switch stop_bpstat.
(handle_inferior_event): Adjust.
(normal_stop): Adjust.
(save_inferior_status, restore_inferior_status): Adjust.
* inf-loop.c (inferior_event_handler): Remove parameter to
bpstat_do_actions call.
* top.c (command_loop): Remove parameter to bpstat_do_actions
call. Call it unconditionally.
* event-top.c (command_handler): Ditto.
* python/python.c (execute_gdb_command): Ditto.
2008-09-08 Pedro Alves <pedro@codesourcery.com> 2008-09-08 Pedro Alves <pedro@codesourcery.com>
* inferior.h (step_over_calls): Delete. * inferior.h (step_over_calls): Delete.

View file

@ -2138,31 +2138,27 @@ cleanup_executing_breakpoints (void *ignore)
/* Execute all the commands associated with all the breakpoints at this /* Execute all the commands associated with all the breakpoints at this
location. Any of these commands could cause the process to proceed location. Any of these commands could cause the process to proceed
beyond this point, etc. We look out for such changes by checking beyond this point, etc. We look out for such changes by checking
the global "breakpoint_proceeded" after each command. */ the global "breakpoint_proceeded" after each command.
void Returns true if a breakpoint command resumed the inferior. In that
bpstat_do_actions (bpstat *bsp) case, it is the caller's responsibility to recall it again with the
bpstat of the current thread. */
static int
bpstat_do_actions_1 (bpstat *bsp)
{ {
bpstat bs; bpstat bs;
struct cleanup *old_chain; struct cleanup *old_chain;
int again = 0;
/* Avoid endless recursion if a `source' command is contained /* Avoid endless recursion if a `source' command is contained
in bs->commands. */ in bs->commands. */
if (executing_breakpoint_commands) if (executing_breakpoint_commands)
return; return 0;
executing_breakpoint_commands = 1; executing_breakpoint_commands = 1;
old_chain = make_cleanup (cleanup_executing_breakpoints, 0); old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
top:
/* Note that (as of this writing), our callers all appear to
be passing us the address of global stop_bpstat. And, if
our calls to execute_control_command cause the inferior to
proceed, that global (and hence, *bsp) will change.
We must be careful to not touch *bsp unless the inferior
has not proceeded. */
/* This pointer will iterate over the list of bpstat's. */ /* This pointer will iterate over the list of bpstat's. */
bs = *bsp; bs = *bsp;
@ -2202,30 +2198,46 @@ top:
if (breakpoint_proceeded) if (breakpoint_proceeded)
{ {
if (target_can_async_p ()) if (target_can_async_p ())
/* If we are in async mode, then the target might /* If we are in async mode, then the target might be still
be still running, not stopped at any breakpoint, running, not stopped at any breakpoint, so nothing for
so nothing for us to do here -- just return to us to do here -- just return to the event loop. */
the event loop. */ ;
break;
else else
/* In sync mode, when execute_control_command returns /* In sync mode, when execute_control_command returns
we're already standing on the next breakpoint. we're already standing on the next breakpoint.
Breakpoint commands for that stop were not run, Breakpoint commands for that stop were not run, since
since execute_command does not run breakpoint execute_command does not run breakpoint commands --
commands -- only command_line_handler does, but only command_line_handler does, but that one is not
that one is not involved in execution of breakpoint involved in execution of breakpoint commands. So, we
commands. So, we can now execute breakpoint commands. can now execute breakpoint commands. It should be
There's an implicit assumption that we're called with noted that making execute_command do bpstat actions is
stop_bpstat, so our parameter is the new bpstat to not an option -- in this case we'll have recursive
handle. invocation of bpstat for each breakpoint with a
It should be noted that making execute_command do command, and can easily blow up GDB stack. Instead, we
bpstat actions is not an option -- in this case we'll return true, which will trigger the caller to recall us
have recursive invocation of bpstat for each breakpoint with the new stop_bpstat. */
with a command, and can easily blow up GDB stack. */ again = 1;
goto top; break;
} }
} }
do_cleanups (old_chain); do_cleanups (old_chain);
return again;
}
void
bpstat_do_actions (void)
{
/* Do any commands attached to breakpoint we are stopped at. */
while (!ptid_equal (inferior_ptid, null_ptid)
&& target_has_execution
&& !is_exited (inferior_ptid)
&& !is_executing (inferior_ptid))
/* Since in sync mode, bpstat_do_actions may resume the inferior,
and only return when it is stopped at the next breakpoint, we
keep doing breakpoint actions until it returns false to
indicate the inferior was not resumed. */
if (!bpstat_do_actions_1 (&inferior_thread ()->stop_bpstat))
break;
} }
/* Print out the (old or new) value associated with a watchpoint. */ /* Print out the (old or new) value associated with a watchpoint. */
@ -7241,9 +7253,6 @@ delete_breakpoint (struct breakpoint *bpt)
in event-top.c won't do anything, and temporary breakpoints in event-top.c won't do anything, and temporary breakpoints
with commands won't work. */ with commands won't work. */
/* Clear the current context. */
bpstat_remove_breakpoint (stop_bpstat, bpt);
/* And from all threads. */
iterate_over_threads (bpstat_remove_breakpoint_callback, bpt); iterate_over_threads (bpstat_remove_breakpoint_callback, bpt);
/* Now that breakpoint is removed from breakpoint /* Now that breakpoint is removed from breakpoint

View file

@ -604,10 +604,11 @@ extern enum print_stop_action bpstat_print (bpstat);
Return 1 otherwise. */ Return 1 otherwise. */
extern int bpstat_num (bpstat *, int *); extern int bpstat_num (bpstat *, int *);
/* Perform actions associated with having stopped at *BSP. Actually, we just /* Perform actions associated with the stopped inferior. Actually, we
use this for breakpoint commands. Perhaps other actions will go here just use this for breakpoint commands. Perhaps other actions will
later, but this is executed at a late time (from the command loop). */ go here later, but this is executed at a late time (from the
extern void bpstat_do_actions (bpstat *); command loop). */
extern void bpstat_do_actions (void);
/* Modify BS so that the actions will not be performed. */ /* Modify BS so that the actions will not be performed. */
extern void bpstat_clear_actions (bpstat); extern void bpstat_clear_actions (bpstat);

View file

@ -478,7 +478,6 @@ async_disable_stdin (void)
static void static void
command_handler (char *command) command_handler (char *command)
{ {
struct cleanup *old_chain;
int stdin_is_tty = ISATTY (stdin); int stdin_is_tty = ISATTY (stdin);
long time_at_cmd_start; long time_at_cmd_start;
#ifdef HAVE_SBRK #ifdef HAVE_SBRK
@ -490,7 +489,6 @@ command_handler (char *command)
quit_flag = 0; quit_flag = 0;
if (instream == stdin && stdin_is_tty) if (instream == stdin && stdin_is_tty)
reinitialize_more_filter (); reinitialize_more_filter ();
old_chain = make_cleanup (null_cleanup, 0);
/* If readline returned a NULL command, it means that the /* If readline returned a NULL command, it means that the
connection with the terminal is gone. This happens at the connection with the terminal is gone. This happens at the
@ -515,35 +513,29 @@ command_handler (char *command)
execute_command (command, instream == stdin); execute_command (command, instream == stdin);
/* Do any commands attached to breakpoint we stopped at. Only if we /* Do any commands attached to breakpoint we stopped at. */
are always running synchronously. Or if we have just executed a bpstat_do_actions ();
command that doesn't start the target. */
if (!target_can_async_p () || is_stopped (inferior_ptid)) if (display_time)
{ {
bpstat_do_actions (&stop_bpstat); long cmd_time = get_run_time () - time_at_cmd_start;
do_cleanups (old_chain);
if (display_time) printf_unfiltered (_("Command execution time: %ld.%06ld\n"),
{ cmd_time / 1000000, cmd_time % 1000000);
long cmd_time = get_run_time () - time_at_cmd_start; }
printf_unfiltered (_("Command execution time: %ld.%06ld\n"), if (display_space)
cmd_time / 1000000, cmd_time % 1000000); {
}
if (display_space)
{
#ifdef HAVE_SBRK #ifdef HAVE_SBRK
char *lim = (char *) sbrk (0); char *lim = (char *) sbrk (0);
long space_now = lim - lim_at_start; long space_now = lim - lim_at_start;
long space_diff = space_now - space_at_cmd_start; long space_diff = space_now - space_at_cmd_start;
printf_unfiltered (_("Space used: %ld (%c%ld for this command)\n"), printf_unfiltered (_("Space used: %ld (%c%ld for this command)\n"),
space_now, space_now,
(space_diff >= 0 ? '+' : '-'), (space_diff >= 0 ? '+' : '-'),
space_diff); space_diff);
#endif #endif
}
} }
} }

View file

@ -29,6 +29,7 @@
#include "gdb_assert.h" #include "gdb_assert.h"
#include "gdb_string.h" #include "gdb_string.h"
#include "serial.h" #include "serial.h"
#include "gdbthread.h"
const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, NULL }; const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, NULL };
@ -212,12 +213,18 @@ exceptions_state_mc_action_iter_1 (void)
NORETURN void NORETURN void
throw_exception (struct gdb_exception exception) throw_exception (struct gdb_exception exception)
{ {
struct thread_info *tp = NULL;
quit_flag = 0; quit_flag = 0;
immediate_quit = 0; immediate_quit = 0;
if (!ptid_equal (inferior_ptid, null_ptid))
tp = find_thread_pid (inferior_ptid);
/* Perhaps it would be cleaner to do this via the cleanup chain (not sure /* Perhaps it would be cleaner to do this via the cleanup chain (not sure
I can think of a reason why that is vital, though). */ I can think of a reason why that is vital, though). */
bpstat_clear_actions (stop_bpstat); /* Clear queued breakpoint commands */ if (tp != NULL)
bpstat_clear_actions (tp->stop_bpstat); /* Clear queued breakpoint commands */
disable_current_display (); disable_current_display ();
do_cleanups (ALL_CLEANUPS); do_cleanups (ALL_CLEANUPS);

View file

@ -146,8 +146,9 @@ struct thread_info
int step_multi; int step_multi;
enum target_signal stop_signal; enum target_signal stop_signal;
/* Used in continue_command to set the proceed count of the
breakpoint the thread stopped at. */ /* Chain containing status of breakpoint(s) the thread stopped
at. */
bpstat stop_bpstat; bpstat stop_bpstat;
/* Private data used by the target vector implementation. */ /* Private data used by the target vector implementation. */
@ -221,8 +222,7 @@ extern void save_infrun_state (ptid_t ptid,
int proceed_to_finish, int proceed_to_finish,
int stop_step, int stop_step,
int step_multi, int step_multi,
enum target_signal stop_signal, enum target_signal stop_signal);
bpstat stop_bpstat);
/* infrun context switch: load the debugger state previously saved /* infrun context switch: load the debugger state previously saved
for the given thread. */ for the given thread. */
@ -232,8 +232,7 @@ extern void load_infrun_state (ptid_t ptid,
int *proceed_to_finish, int *proceed_to_finish,
int *stop_step, int *stop_step,
int *step_multi, int *step_multi,
enum target_signal *stop_signal, enum target_signal *stop_signal);
bpstat *stop_bpstat);
/* Switch from one thread to another. */ /* Switch from one thread to another. */
extern void switch_to_thread (ptid_t ptid); extern void switch_to_thread (ptid_t ptid);

View file

@ -115,7 +115,7 @@ inferior_event_handler (enum inferior_event_type event_type,
be informed. */ be informed. */
TRY_CATCH (e, RETURN_MASK_ALL) TRY_CATCH (e, RETURN_MASK_ALL)
{ {
bpstat_do_actions (&stop_bpstat); bpstat_do_actions ();
} }
if (!was_sync && !is_running (inferior_ptid) && exec_done_display_p) if (!was_sync && !is_running (inferior_ptid) && exec_done_display_p)

View file

@ -35,6 +35,7 @@
#include "infcall.h" #include "infcall.h"
#include "dummy-frame.h" #include "dummy-frame.h"
#include "ada-lang.h" #include "ada-lang.h"
#include "gdbthread.h"
/* NOTE: cagney/2003-04-16: What's the future of this code? /* NOTE: cagney/2003-04-16: What's the future of this code?
@ -263,12 +264,13 @@ find_function_addr (struct value *function, struct type **retval_type)
} }
/* Call breakpoint_auto_delete on the current contents of the bpstat /* Call breakpoint_auto_delete on the current contents of the bpstat
pointed to by arg (which is really a bpstat *). */ of the current thread. */
static void static void
breakpoint_auto_delete_contents (void *arg) breakpoint_auto_delete_contents (void *arg)
{ {
breakpoint_auto_delete (*(bpstat *) arg); if (!ptid_equal (inferior_ptid, null_ptid))
breakpoint_auto_delete (inferior_thread ()->stop_bpstat);
} }
static CORE_ADDR static CORE_ADDR
@ -712,7 +714,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
/* If all error()s out of proceed ended up calling normal_stop /* If all error()s out of proceed ended up calling normal_stop
(and perhaps they should; it already does in the special case (and perhaps they should; it already does in the special case
of error out of resume()), then we wouldn't need this. */ of error out of resume()), then we wouldn't need this. */
make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat); make_cleanup (breakpoint_auto_delete_contents, NULL);
disable_watchpoints_before_interactive_call_start (); disable_watchpoints_before_interactive_call_start ();
proceed_to_finish = 1; /* We want stop_registers, please... */ proceed_to_finish = 1; /* We want stop_registers, please... */

View file

@ -155,10 +155,6 @@ enum target_signal stop_signal;
CORE_ADDR stop_pc; CORE_ADDR stop_pc;
/* Chain containing status of breakpoint(s) that we have stopped at. */
bpstat stop_bpstat;
/* Flag indicating that a command has proceeded the inferior past the /* Flag indicating that a command has proceeded the inferior past the
current breakpoint. */ current breakpoint. */
@ -673,9 +669,23 @@ Can't resume all threads and specify proceed count simultaneously."));
stopped at. */ stopped at. */
if (args != NULL) if (args != NULL)
{ {
bpstat bs = stop_bpstat; bpstat bs = NULL;
int num, stat; int num, stat;
int stopped = 0; int stopped = 0;
struct thread_info *tp;
if (non_stop)
tp = find_thread_pid (inferior_ptid);
else
{
ptid_t last_ptid;
struct target_waitstatus ws;
get_last_target_status (&last_ptid, &ws);
tp = find_thread_pid (last_ptid);
}
if (tp != NULL)
bs = tp->stop_bpstat;
while ((stat = bpstat_num (&bs, &num)) != 0) while ((stat = bpstat_num (&bs, &num)) != 0)
if (stat > 0) if (stat > 0)
@ -1319,7 +1329,14 @@ finish_command_continuation (void *arg)
{ {
struct finish_command_continuation_args *a = arg; struct finish_command_continuation_args *a = arg;
if (bpstat_find_breakpoint (stop_bpstat, a->breakpoint) != NULL bpstat bs = NULL;
if (!ptid_equal (inferior_ptid, null_ptid)
&& target_has_execution
&& is_stopped (inferior_ptid))
bs = inferior_thread ()->stop_bpstat;
if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL
&& a->function != NULL) && a->function != NULL)
{ {
struct type *value_type; struct type *value_type;
@ -1339,7 +1356,7 @@ finish_command_continuation (void *arg)
next stop will be in the same thread that we started doing a next stop will be in the same thread that we started doing a
finish on. This suppressing (or some other replacement means) finish on. This suppressing (or some other replacement means)
should be a thread property. */ should be a thread property. */
observer_notify_normal_stop (stop_bpstat); observer_notify_normal_stop (bs);
suppress_stop_observer = 0; suppress_stop_observer = 0;
delete_breakpoint (a->breakpoint); delete_breakpoint (a->breakpoint);
} }
@ -1436,9 +1453,10 @@ finish_command (char *arg, int from_tty)
static void static void
program_info (char *args, int from_tty) program_info (char *args, int from_tty)
{ {
bpstat bs = stop_bpstat; bpstat bs;
int num; int num, stat;
int stat = bpstat_num (&bs, &num); struct thread_info *tp;
ptid_t ptid;
if (!target_has_execution) if (!target_has_execution)
{ {
@ -1446,6 +1464,23 @@ program_info (char *args, int from_tty)
return; return;
} }
if (non_stop)
ptid = inferior_ptid;
else
{
struct target_waitstatus ws;
get_last_target_status (&ptid, &ws);
}
if (ptid_equal (ptid, null_ptid) || is_exited (ptid))
error (_("Invalid selected thread."));
else if (is_running (ptid))
error (_("Selected thread is running."));
tp = find_thread_pid (ptid);
bs = tp->stop_bpstat;
stat = bpstat_num (&bs, &num);
target_files_info (); target_files_info ();
printf_filtered (_("Program stopped at %s.\n"), printf_filtered (_("Program stopped at %s.\n"),
hex_string ((unsigned long) stop_pc)); hex_string ((unsigned long) stop_pc));

View file

@ -287,10 +287,6 @@ extern enum target_signal stop_signal;
extern CORE_ADDR stop_pc; extern CORE_ADDR stop_pc;
/* Chain containing status of breakpoint(s) that we have stopped at. */
extern bpstat stop_bpstat;
/* Flag indicating that a command has proceeded the inferior past the /* Flag indicating that a command has proceeded the inferior past the
current breakpoint. */ current breakpoint. */

View file

@ -1105,6 +1105,9 @@ clear_proceed_status (void)
tp->step_range_end = 0; tp->step_range_end = 0;
tp->step_frame_id = null_frame_id; tp->step_frame_id = null_frame_id;
tp->step_over_calls = STEP_OVER_UNDEBUGGABLE; tp->step_over_calls = STEP_OVER_UNDEBUGGABLE;
/* Discard any remaining commands or status from previous
stop. */
bpstat_clear (&tp->stop_bpstat);
} }
stop_after_trap = 0; stop_after_trap = 0;
@ -1117,9 +1120,6 @@ clear_proceed_status (void)
regcache_xfree (stop_registers); regcache_xfree (stop_registers);
stop_registers = NULL; stop_registers = NULL;
} }
/* Discard any remaining commands or status from previous stop. */
bpstat_clear (&stop_bpstat);
} }
/* This should be suitable for any targets that support threads. */ /* This should be suitable for any targets that support threads. */
@ -1717,8 +1717,7 @@ context_switch (ptid_t ptid)
proceed_to_finish, proceed_to_finish,
stop_step, stop_step,
step_multi, step_multi,
stop_signal, stop_signal);
stop_bpstat);
/* Load infrun state for the new thread. */ /* Load infrun state for the new thread. */
load_infrun_state (ptid, load_infrun_state (ptid,
@ -1726,8 +1725,7 @@ context_switch (ptid_t ptid)
&proceed_to_finish, &proceed_to_finish,
&stop_step, &stop_step,
&step_multi, &step_multi,
&stop_signal, &stop_signal);
&stop_bpstat);
} }
switch_to_thread (ptid); switch_to_thread (ptid);
@ -2065,9 +2063,9 @@ handle_inferior_event (struct execution_control_state *ecs)
stop_pc = read_pc (); stop_pc = read_pc ();
stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
ecs->random_signal = !bpstat_explains_signal (stop_bpstat); ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
/* If no catchpoint triggered for this, then keep going. */ /* If no catchpoint triggered for this, then keep going. */
if (ecs->random_signal) if (ecs->random_signal)
@ -2101,9 +2099,9 @@ handle_inferior_event (struct execution_control_state *ecs)
ptid_t saved_inferior_ptid = inferior_ptid; ptid_t saved_inferior_ptid = inferior_ptid;
inferior_ptid = ecs->ptid; inferior_ptid = ecs->ptid;
stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
ecs->random_signal = !bpstat_explains_signal (stop_bpstat); ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
inferior_ptid = saved_inferior_ptid; inferior_ptid = saved_inferior_ptid;
} }
@ -2499,7 +2497,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
ecs->stop_func_start ecs->stop_func_start
+= gdbarch_deprecated_function_start_offset (current_gdbarch); += gdbarch_deprecated_function_start_offset (current_gdbarch);
ecs->event_thread->stepping_over_breakpoint = 0; ecs->event_thread->stepping_over_breakpoint = 0;
bpstat_clear (&stop_bpstat); bpstat_clear (&ecs->event_thread->stop_bpstat);
stop_step = 0; stop_step = 0;
stop_print_frame = 1; stop_print_frame = 1;
ecs->random_signal = 0; ecs->random_signal = 0;
@ -2612,7 +2610,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
} }
/* See if there is a breakpoint at the current PC. */ /* See if there is a breakpoint at the current PC. */
stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
/* Following in case break condition called a /* Following in case break condition called a
function. */ function. */
@ -2640,13 +2638,13 @@ targets should add new threads to the thread list themselves in non-stop mode.")
if (stop_signal == TARGET_SIGNAL_TRAP) if (stop_signal == TARGET_SIGNAL_TRAP)
ecs->random_signal ecs->random_signal
= !(bpstat_explains_signal (stop_bpstat) = !(bpstat_explains_signal (ecs->event_thread->stop_bpstat)
|| ecs->event_thread->trap_expected || ecs->event_thread->trap_expected
|| (ecs->event_thread->step_range_end || (ecs->event_thread->step_range_end
&& ecs->event_thread->step_resume_breakpoint == NULL)); && ecs->event_thread->step_resume_breakpoint == NULL));
else else
{ {
ecs->random_signal = !bpstat_explains_signal (stop_bpstat); ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
if (!ecs->random_signal) if (!ecs->random_signal)
stop_signal = TARGET_SIGNAL_TRAP; stop_signal = TARGET_SIGNAL_TRAP;
} }
@ -2760,7 +2758,7 @@ process_event_stop_test:
CORE_ADDR jmp_buf_pc; CORE_ADDR jmp_buf_pc;
struct bpstat_what what; struct bpstat_what what;
what = bpstat_what (stop_bpstat); what = bpstat_what (ecs->event_thread->stop_bpstat);
if (what.call_dummy) if (what.call_dummy)
{ {
@ -2929,7 +2927,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
code or stubs in libdld.sl, such as "shl_load" and code or stubs in libdld.sl, such as "shl_load" and
friends) until we reach non-dld code. At that point, friends) until we reach non-dld code. At that point,
we can stop stepping. */ we can stop stepping. */
bpstat_get_triggered_catchpoints (stop_bpstat, bpstat_get_triggered_catchpoints (ecs->event_thread->stop_bpstat,
&ecs-> &ecs->
event_thread-> event_thread->
stepping_through_solib_catchpoints); stepping_through_solib_catchpoints);
@ -2984,8 +2982,9 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
/* Else, stop and report the catchpoint(s) whose triggering /* Else, stop and report the catchpoint(s) whose triggering
caused us to begin stepping. */ caused us to begin stepping. */
ecs->event_thread->stepping_through_solib_after_catch = 0; ecs->event_thread->stepping_through_solib_after_catch = 0;
bpstat_clear (&stop_bpstat); bpstat_clear (&ecs->event_thread->stop_bpstat);
stop_bpstat = bpstat_copy (ecs->event_thread->stepping_through_solib_catchpoints); ecs->event_thread->stop_bpstat
= bpstat_copy (ecs->event_thread->stepping_through_solib_catchpoints);
bpstat_clear (&ecs->event_thread->stepping_through_solib_catchpoints); bpstat_clear (&ecs->event_thread->stepping_through_solib_catchpoints);
stop_print_frame = 1; stop_print_frame = 1;
stop_stepping (ecs); stop_stepping (ecs);
@ -3831,8 +3830,9 @@ Further execution is probably impossible.\n"));
int bpstat_ret; int bpstat_ret;
int source_flag; int source_flag;
int do_frame_printing = 1; int do_frame_printing = 1;
struct thread_info *tp = inferior_thread ();
bpstat_ret = bpstat_print (stop_bpstat); bpstat_ret = bpstat_print (tp->stop_bpstat);
switch (bpstat_ret) switch (bpstat_ret)
{ {
case PRINT_UNKNOWN: case PRINT_UNKNOWN:
@ -3852,7 +3852,7 @@ Further execution is probably impossible.\n"));
(or should) carry around the function and does (or (or should) carry around the function and does (or
should) use that when doing a frame comparison. */ should) use that when doing a frame comparison. */
if (stop_step if (stop_step
&& frame_id_eq (inferior_thread ()->step_frame_id, && frame_id_eq (tp->step_frame_id,
get_frame_id (get_current_frame ())) get_frame_id (get_current_frame ()))
&& step_start_function == find_pc_function (stop_pc)) && step_start_function == find_pc_function (stop_pc))
source_flag = SRC_LINE; /* finished step, just print source line */ source_flag = SRC_LINE; /* finished step, just print source line */
@ -3931,15 +3931,20 @@ Further execution is probably impossible.\n"));
done: done:
annotate_stopped (); annotate_stopped ();
if (!suppress_stop_observer && !step_multi) if (!suppress_stop_observer && !step_multi)
observer_notify_normal_stop (stop_bpstat); {
/* Delete the breakpoint we stopped at, if it wants to be deleted. if (!ptid_equal (inferior_ptid, null_ptid))
Delete any breakpoint that is to be deleted at the next stop. */ observer_notify_normal_stop (inferior_thread ()->stop_bpstat);
breakpoint_auto_delete (stop_bpstat); else
observer_notify_normal_stop (NULL);
}
if (target_has_execution if (target_has_execution
&& last.kind != TARGET_WAITKIND_SIGNALLED && last.kind != TARGET_WAITKIND_SIGNALLED
&& last.kind != TARGET_WAITKIND_EXITED) && last.kind != TARGET_WAITKIND_EXITED)
{ {
/* Delete the breakpoint we stopped at, if it wants to be deleted.
Delete any breakpoint that is to be deleted at the next stop. */
breakpoint_auto_delete (inferior_thread ()->stop_bpstat);
if (!non_stop) if (!non_stop)
set_running (pid_to_ptid (-1), 0); set_running (pid_to_ptid (-1), 0);
else else
@ -4378,8 +4383,8 @@ save_inferior_status (int restore_stack_info)
If caller's caller is walking the chain, they'll be happier if we If caller's caller is walking the chain, they'll be happier if we
hand them back the original chain when restore_inferior_status is hand them back the original chain when restore_inferior_status is
called. */ called. */
inf_status->stop_bpstat = stop_bpstat; inf_status->stop_bpstat = tp->stop_bpstat;
stop_bpstat = bpstat_copy (stop_bpstat); tp->stop_bpstat = bpstat_copy (tp->stop_bpstat);
inf_status->breakpoint_proceeded = breakpoint_proceeded; inf_status->breakpoint_proceeded = breakpoint_proceeded;
inf_status->restore_stack_info = restore_stack_info; inf_status->restore_stack_info = restore_stack_info;
inf_status->proceed_to_finish = proceed_to_finish; inf_status->proceed_to_finish = proceed_to_finish;
@ -4428,8 +4433,8 @@ restore_inferior_status (struct inferior_status *inf_status)
tp->step_over_calls = inf_status->step_over_calls; tp->step_over_calls = inf_status->step_over_calls;
stop_after_trap = inf_status->stop_after_trap; stop_after_trap = inf_status->stop_after_trap;
stop_soon = inf_status->stop_soon; stop_soon = inf_status->stop_soon;
bpstat_clear (&stop_bpstat); bpstat_clear (&tp->stop_bpstat);
stop_bpstat = inf_status->stop_bpstat; tp->stop_bpstat = inf_status->stop_bpstat;
breakpoint_proceeded = inf_status->breakpoint_proceeded; breakpoint_proceeded = inf_status->breakpoint_proceeded;
proceed_to_finish = inf_status->proceed_to_finish; proceed_to_finish = inf_status->proceed_to_finish;

View file

@ -241,27 +241,18 @@ execute_gdb_command (PyObject *self, PyObject *args)
struct cmd_list_element *alias, *prefix, *cmd; struct cmd_list_element *alias, *prefix, *cmd;
char *arg, *newarg; char *arg, *newarg;
volatile struct gdb_exception except; volatile struct gdb_exception except;
struct cleanup *old_chain;
if (! PyArg_ParseTuple (args, "s", &arg)) if (! PyArg_ParseTuple (args, "s", &arg))
return NULL; return NULL;
old_chain = make_cleanup (null_cleanup, 0);
TRY_CATCH (except, RETURN_MASK_ALL) TRY_CATCH (except, RETURN_MASK_ALL)
{ {
execute_command (arg, 0); execute_command (arg, 0);
} }
GDB_PY_HANDLE_EXCEPTION (except); GDB_PY_HANDLE_EXCEPTION (except);
/* Do any commands attached to breakpoint we stopped at. Only if we /* Do any commands attached to breakpoint we stopped at. */
are always running synchronously. Or if we have just executed a bpstat_do_actions ();
command that doesn't start the target. */
if (!target_can_async_p () || !is_running (inferior_ptid))
{
bpstat_do_actions (&stop_bpstat);
do_cleanups (old_chain);
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }

View file

@ -448,8 +448,7 @@ load_infrun_state (ptid_t ptid,
int *proceed_to_finish, int *proceed_to_finish,
int *stop_step, int *stop_step,
int *step_multi, int *step_multi,
enum target_signal *stop_signal, enum target_signal *stop_signal)
bpstat *stop_bpstat)
{ {
struct thread_info *tp; struct thread_info *tp;
@ -471,11 +470,6 @@ load_infrun_state (ptid_t ptid,
*stop_step = tp->stop_step; *stop_step = tp->stop_step;
*step_multi = tp->step_multi; *step_multi = tp->step_multi;
*stop_signal = tp->stop_signal; *stop_signal = tp->stop_signal;
/* Swap instead of copy, so we only have to update one of
them. */
*stop_bpstat = tp->stop_bpstat;
tp->stop_bpstat = 0;
} }
} }
@ -488,8 +482,7 @@ save_infrun_state (ptid_t ptid,
int proceed_to_finish, int proceed_to_finish,
int stop_step, int stop_step,
int step_multi, int step_multi,
enum target_signal stop_signal, enum target_signal stop_signal)
bpstat stop_bpstat)
{ {
struct thread_info *tp; struct thread_info *tp;
@ -509,7 +502,6 @@ save_infrun_state (ptid_t ptid,
tp->stop_step = stop_step; tp->stop_step = stop_step;
tp->step_multi = step_multi; tp->step_multi = step_multi;
tp->stop_signal = stop_signal; tp->stop_signal = stop_signal;
tp->stop_bpstat = stop_bpstat;
} }
} }

View file

@ -534,8 +534,10 @@ command_loop (void)
} }
execute_command (command, instream == stdin); execute_command (command, instream == stdin);
/* Do any commands attached to breakpoint we stopped at. */
bpstat_do_actions (&stop_bpstat); /* Do any commands attached to breakpoint we are stopped at. */
bpstat_do_actions ();
do_cleanups (old_chain); do_cleanups (old_chain);
if (display_time) if (display_time)