X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Finf-loop.c;h=a730aed8e5067506cdd0f85d20fcc0dfc433e18c;hb=8234eceb5e01be43eca70dbacdb869fc66dbed0a;hp=04989a2478eafe7bf5f8cbe5c09e2362d19c45ca;hpb=01f0fe5e0450edf168c1f612feb93cf588e4e7ea;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c index 04989a2478..a730aed8e5 100644 --- a/gdb/inf-loop.c +++ b/gdb/inf-loop.c @@ -1,12 +1,12 @@ /* Handling of inferior events for the event loop for GDB, the GNU debugger. - Copyright (C) 1999 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. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,9 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "inferior.h" /* For fetch_inferior_event. */ @@ -27,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) @@ -45,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: @@ -63,26 +64,85 @@ 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 && !is_running (inferior_ptid) && exec_done_display_p) + 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: @@ -105,29 +165,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")); - } -}