Re: [PATCH v4 8/9] fix py-finish-breakpoint.exp with always-async

Pedro Alves
2013-11-11T19:46:55Z

On 10/22/2013 06:59 PM, Tom Tromey wrote:
> With target async enabled, py-finish-breakpoint.exp will trigger an
> assertion failure.
>
> The failure occurs because execute_command re-enters the event loop in
> some circumstances, and in this case resets the sync_execution flag.
> Then later gdb reaches this assertion in normal_stop:
>
> gdb_assert (sync_execution || !target_can_async_p ());
>
> execute_command has a comment explaining why it dispatches events:
>
> /* If the interpreter is in sync mode (we're running a user
> command's list, running command hooks or similars), and we
> just ran a synchronous command that started the target, wait
> for that command to end. */
>
> However, the code did not follow this comment -- it didn't check to
> see if the command started the target, just whether the target was
> executing a sync command at this point.

Can you explain this a little better, please?

IIUC (I haven't really stepped through the code):

- A synchronous execution command is run. sync_execution is set.

- A python breakpoint is hit, and the corresponding stop
method is executed. While python commands are executed,
interpreter_async is forced to 0.

- The Python stop method happens to execute a not-execution-related
gdb command ("where 1").

- Seeing that sync_execution is set, GDB nests a new event loop,
although that wasn't necessary.

- Some event that causes a stop triggers in the inferior, and
normal_stop is called.

- the nested event loop unwinds/ends, and normal_stop is called
again. (IOW, normal_stop was called
twice for the same event.) The assertion triggers.

Is that accurate?

What happens if the Python stop method actually does run an
execution command?

--
Pedro Alves