Fix double prompt
If an error is thrown while handling a target event (within fetch_inferior_event), and, the interpreter is not async (but the target is), then GDB prints the prompt twice. One way to see that in action is throw a QUIT while in a pagination prompt issued from within fetch_inferior_event (or one of its callees). E.g. from the test: ---Type <return> to continue, or q <return> to quit--- ^CQuit (gdb) (gdb) p 1 ^^^^^^^^^^^ $1 = 1 (gdb) The issue is that inferior_event_handler swallows errors and notifies the observers (the interpreters) about the command error, even if the interpreter is forced sync while we're handling a nested event loop (for execute_command). The observers print a prompt, and then when we get back to the top event loop, we print another (in start_event_loop). I see no reason the error should be swallowed here. Just cancel the execution related bits and let the error propagate to the top level (start_event_loop), which re-enables stdin and notifies observers. gdb/ 2014-07-14 Pedro Alves <palves@redhat.com> * inf-loop.c (inferior_event_handler): Use TRY_CATCH instead of catch_errors. Don't re-enable stdin or notify observers where, and rethrow error. (fetch_inferior_event_wrapper): Delete. gdb/testsuite/ 2014-07-14 Pedro Alves <palves@redhat.com> * gdb.base/double-prompt-target-event-error.c: New file. * gdb.base/double-prompt-target-event-error.exp: New file.
This commit is contained in:
parent
93d6eb10ed
commit
1e9735707b
5 changed files with 165 additions and 19 deletions
|
@ -33,8 +33,6 @@
|
|||
#include "top.h"
|
||||
#include "observer.h"
|
||||
|
||||
static int fetch_inferior_event_wrapper (gdb_client_data client_data);
|
||||
|
||||
/* General function to handle events in the inferior. So far it just
|
||||
takes care of detecting errors reported by select() or poll(),
|
||||
otherwise it assumes that all is OK, and goes on reading data from
|
||||
|
@ -48,19 +46,26 @@ inferior_event_handler (enum inferior_event_type event_type,
|
|||
switch (event_type)
|
||||
{
|
||||
case INF_REG_EVENT:
|
||||
/* Use catch errors for now, until the inner layers of
|
||||
/* Catch errors for now, until the inner layers of
|
||||
fetch_inferior_event (i.e. readchar) can return meaningful
|
||||
error status. If an error occurs while getting an event from
|
||||
the target, just cancel the current command. */
|
||||
if (!catch_errors (fetch_inferior_event_wrapper,
|
||||
client_data, "", RETURN_MASK_ALL))
|
||||
{
|
||||
bpstat_clear_actions ();
|
||||
do_all_intermediate_continuations (1);
|
||||
do_all_continuations (1);
|
||||
async_enable_stdin ();
|
||||
observer_notify_command_error ();
|
||||
}
|
||||
{
|
||||
volatile struct gdb_exception ex;
|
||||
|
||||
TRY_CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
fetch_inferior_event (client_data);
|
||||
}
|
||||
if (ex.reason < 0)
|
||||
{
|
||||
bpstat_clear_actions ();
|
||||
do_all_intermediate_continuations (1);
|
||||
do_all_continuations (1);
|
||||
|
||||
throw_exception (ex);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case INF_EXEC_COMPLETE:
|
||||
|
@ -140,10 +145,3 @@ inferior_event_handler (enum inferior_event_type event_type,
|
|||
|
||||
discard_cleanups (cleanup_if_error);
|
||||
}
|
||||
|
||||
static int
|
||||
fetch_inferior_event_wrapper (gdb_client_data client_data)
|
||||
{
|
||||
fetch_inferior_event (client_data);
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue