X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Finf-loop.c;h=e19056766f8c3d7d810da2c6dbb359929688c2cb;hb=27a9c0bfdcff1e641d05925de78c5d2b661b326e;hp=4c61daeb003edc751d5ff003d0cdeb90dbd521bf;hpb=f107f56344531e3fa4cc74cac1fe7dd7b056edab;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c index 4c61daeb00..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. @@ -26,6 +26,7 @@ #include "remote.h" #include "exceptions.h" #include "language.h" +#include "gdbthread.h" static int fetch_inferior_event_wrapper (gdb_client_data client_data); @@ -43,14 +44,15 @@ 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 (); - do_all_continuations (1); + pop_all_targets_above (file_stratum, 0); + discard_all_intermediate_continuations (); + discard_all_continuations (); async_enable_stdin (); break; @@ -62,9 +64,9 @@ 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 (); - do_all_continuations (1); + pop_all_targets_above (file_stratum, 0); + discard_all_intermediate_continuations (); + discard_all_continuations (); async_enable_stdin (); display_gdb_prompt (0); } @@ -72,18 +74,14 @@ inferior_event_handler (enum inferior_event_type event_type, case INF_EXEC_COMPLETE: - /* This is the first thing to do -- so that continuations know that - the target is stopped. For example, command_line_handler_continuation - will run breakpoint commands, and if we think that the target is - running, we'll refuse to execute most commands. MI continuation - presently uses target_executing to either print or not print *stopped. */ - 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. */ - if (target_has_execution) - target_async (NULL, 0); + 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 @@ -91,42 +89,63 @@ inferior_event_handler (enum inferior_event_type event_type, 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. */ - do_all_intermediate_continuations (0); - - do_all_continuations (0); - - if (current_language != expected_language) + 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) { - if (language_mode == language_mode_auto) - { - language_info (1); /* Print what changed. */ - } + bpstat_do_actions (); } - /* If the continuation did not start the target again, - prepare for interation with the user. */ - if (!target_executing) - { - if (was_sync) - { - display_gdb_prompt (0); - } - else - { - if (exec_done_display_p) - printf_unfiltered (_("completed.\n")); - } - } + 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 (0); + + if (non_stop) + do_all_intermediate_continuations_thread (inferior_thread ()); + else + do_all_intermediate_continuations (); break; case INF_QUIT_REQ: