continuations and breakpoint commands

Pedro Alves
2008-04-29T21:22:21Z

[-- Attachment #1: Type: text/plain, Size: 1514 bytes --]

This patch fixes continuation handling in async mode, by making
the handling sequence match the sync code path.

Exec commands sequence should be:

execute command -> wait for stop -> rest of command

After that, if the stop was due to a breakpoint, we check for
any breakpoint commands associated with it. Any command is
allowed, so it's possible that one command be another exec
command, which resumes the target:

break main
commands
continue
end

execute command
-> wait for stop
-> rest of command
-> breakpoint commands
execute command -> ...

breakpoint commands used to be ran in the
command_line_handler_continuation. Now they're ran before
the continuations, which is wrong. If the continuation
has to pull a breakpoint out of the inferior, and a breakpoint
command resumed the inferior, the removal will fail (on targets
where writing inferior memory on a running target is not
possible, like linux).

Looking at top.c to copy the exact sync sequence also shows that
any language change is printed before running breakpoint commands.

This patch applies on top of this one:
[RFA] bpstat_do_actions in one place
http://sourceware.org/ml/gdb-patches/2008-04/msg00557.html

This fixes commands.exp failures. There's one case where the
removing a breakpoint from a running target was triggering, due
to a breakpoint command.

Tested on i686-pc-linux-gnu/async.

Ok, after the dependencies are in?

--
Pedro Alves

[-- Attachment #2: fix_commands.exp.diff --]
[-- Type: text/x-diff, Size: 2443 bytes --]

2008-04-29 Pedro Alves <pedro@codesourcery.com>

* inf-loop.c (inferior_event_handler): Run all continuations and
print any language change before running the breakpoint commands.

---
gdb/inf-loop.c | 33 +++++++++++++++++++--------------
1 file changed, 19 insertions(+), 14 deletions(-)

Index: src/gdb/inf-loop.c
===================================================================
--- src.orig/gdb/inf-loop.c 2008-04-29 20:45:35.000000000 +0100
+++ src/gdb/inf-loop.c 2008-04-29 22:04:03.000000000 +0100
@@ -92,30 +92,35 @@ inferior_event_handler (enum inferior_ev
was_sync = sync_execution;
async_enable_stdin ();

- /* If there's an error doing breakpoint commands, we don't
- want to throw -- continuation might still do something. */
- TRY_CATCH (e, RETURN_MASK_ERROR)
- {
- bpstat_do_actions (&stop_bpstat);
- }
/* 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. */
+ 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)
+ 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_ERROR)
{
- 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
+ interation with the user. */
if (!target_executing)
{
if (was_sync)