inferior_event_handler (enum inferior_event_type event_type,
gdb_client_data client_data)
{
+ struct gdb_exception e;
int was_sync = 0;
switch (event_type)
{
printf_unfiltered (_("error detected from target.\n"));
target_async (NULL, 0);
pop_target ();
- discard_all_continuations ();
- do_exec_error_cleanups (ALL_CLEANUPS);
+ do_all_continuations (1);
+ async_enable_stdin ();
break;
case INF_REG_EVENT:
{
target_async (NULL, 0);
pop_target ();
- discard_all_continuations ();
- do_exec_error_cleanups (ALL_CLEANUPS);
+ do_all_continuations (1);
+ async_enable_stdin ();
display_gdb_prompt (0);
}
break;
if (target_has_execution)
target_async (NULL, 0);
- /* Calls to do_exec_error_cleanup below will call async_enable_stdin,
- and that resets 'sync_execution'. However, if we were running
- in sync execution mode, we also need to display the prompt. */
+ /* The call to async_enable_stdin below resets 'sync_execution'.
+ However, if sync_execution is 1 now, we also need to show the
+ prompt below, so save the current value. */
was_sync = sync_execution;
-
- if (was_sync)
- do_exec_error_cleanups (ALL_CLEANUPS);
-
- do_all_continuations ();
-
- if (current_language != expected_language)
+ async_enable_stdin ();
+
+ /* If we were doing a multi-step (eg: step n, next n), but it
+ got interrupted by a breakpoint, still do the pending
+ continuations. The continuation itself is responsible for
+ distinguishing the cases. The continuations are allowed to
+ touch the inferior memory, e.g. to remove breakpoints, so run
+ them before running breakpoint commands, which may resume the
+ target. */
+ do_all_intermediate_continuations (0);
+
+ /* Always finish the previous command before running any
+ breakpoint commands. Any stop cancels the previous command.
+ E.g. a "finish" or "step-n" command interrupted by an
+ unrelated breakpoint is canceled. */
+ do_all_continuations (0);
+
+ if (current_language != expected_language
+ && language_mode == language_mode_auto)
+ language_info (1); /* Print what changed. */
+
+ /* Don't propagate breakpoint commands errors. Either we're
+ stopping or some command resumes the inferior. The user will
+ be informed. */
+ TRY_CATCH (e, RETURN_MASK_ALL)
{
- if (language_mode == language_mode_auto)
- {
- language_info (1); /* Print what changed. */
- }
+ bpstat_do_actions (&stop_bpstat);
}
- /* If the continuation did not start the target again,
- prepare for interation with the user. */
+ /* If no breakpoint command resumed the inferior, prepare for
+ interaction with the user. */
if (!target_executing)
{
if (was_sync)
case INF_EXEC_CONTINUE:
/* Is there anything left to do for the command issued to
complete? */
- do_all_intermediate_continuations ();
+ do_all_intermediate_continuations (0);
break;
case INF_QUIT_REQ: