X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Finf-loop.c;h=e19056766f8c3d7d810da2c6dbb359929688c2cb;hb=b7f6bf22997d7ff8b9218e82c90d2e3dfcb08d62;hp=b6f8bb8d728556fb96b170b76003357d3a53b09c;hpb=b18392efbed6c18ecb7430dee65308e96e35cbf7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c index b6f8bb8d72..e19056766f 100644 --- a/gdb/inf-loop.c +++ b/gdb/inf-loop.c @@ -1,5 +1,5 @@ /* Handling of inferior events for the event loop for GDB, the GNU debugger. - Copyright (C) 1999, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 1999, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Elena Zannoni of Cygnus Solutions. This file is part of GDB. @@ -25,9 +25,10 @@ #include "inf-loop.h" #include "remote.h" #include "exceptions.h" +#include "language.h" +#include "gdbthread.h" static int fetch_inferior_event_wrapper (gdb_client_data client_data); -static void complete_execution (void); void inferior_event_handler_wrapper (gdb_client_data client_data) @@ -43,14 +44,16 @@ void 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) { case INF_ERROR: printf_unfiltered (_("error detected from target.\n")); - target_async (NULL, 0); - pop_target (); + pop_all_targets_above (file_stratum, 0); + discard_all_intermediate_continuations (); discard_all_continuations (); - do_exec_error_cleanups (ALL_CLEANUPS); + async_enable_stdin (); break; case INF_REG_EVENT: @@ -61,26 +64,88 @@ inferior_event_handler (enum inferior_event_type event_type, if (!catch_errors (fetch_inferior_event_wrapper, client_data, "", RETURN_MASK_ALL)) { - target_async (NULL, 0); - pop_target (); + pop_all_targets_above (file_stratum, 0); + discard_all_intermediate_continuations (); discard_all_continuations (); - do_exec_error_cleanups (ALL_CLEANUPS); + async_enable_stdin (); display_gdb_prompt (0); } break; case INF_EXEC_COMPLETE: - /* Is there anything left to do for the command issued to - complete? */ - do_all_continuations (); - /* Reset things after target has stopped for the async commands. */ - complete_execution (); + + if (!non_stop) + { + /* Unregister the inferior from the event loop. This is done + so that when the inferior is not running we don't get + distracted by spurious inferior output. */ + if (target_has_execution) + target_async (NULL, 0); + } + + /* 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; + async_enable_stdin (); + + /* Do all continuations associated with the whole inferior (not + a particular thread). */ + if (!ptid_equal (inferior_ptid, null_ptid)) + do_all_inferior_continuations (); + + /* 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. */ + if (non_stop + && target_has_execution + && !ptid_equal (inferior_ptid, null_ptid)) + do_all_intermediate_continuations_thread (inferior_thread ()); + else + do_all_intermediate_continuations (); + + /* 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. */ + if (non_stop + && target_has_execution + && !ptid_equal (inferior_ptid, null_ptid)) + do_all_continuations_thread (inferior_thread ()); + else + do_all_continuations (); + + 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) + { + bpstat_do_actions (); + } + + if (!was_sync + && exec_done_display_p + && (ptid_equal (inferior_ptid, null_ptid) + || !is_running (inferior_ptid))) + printf_unfiltered (_("completed.\n")); break; case INF_EXEC_CONTINUE: /* Is there anything left to do for the command issued to complete? */ - do_all_intermediate_continuations (); + + if (non_stop) + do_all_intermediate_continuations_thread (inferior_thread ()); + else + do_all_intermediate_continuations (); break; case INF_QUIT_REQ: @@ -103,29 +168,3 @@ fetch_inferior_event_wrapper (gdb_client_data client_data) fetch_inferior_event (client_data); return 1; } - -/* Reset proper settings after an asynchronous command has finished. - If the execution command was in synchronous mode, register stdin - with the event loop, and reset the prompt. */ - -static void -complete_execution (void) -{ - target_executing = 0; - - /* Unregister the inferior from the event loop. This is done so that - when the inferior is not running we don't get distracted by - spurious inferior output. */ - target_async (NULL, 0); - - if (sync_execution) - { - do_exec_error_cleanups (ALL_CLEANUPS); - display_gdb_prompt (0); - } - else - { - if (exec_done_display_p) - printf_unfiltered (_("completed.\n")); - } -}