From: Pedro Alves Date: Fri, 2 Sep 2011 16:56:30 +0000 (+0000) Subject: 2011-09-02 Pedro Alves X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b4a14fd09b84468e7d28a2889d99a27008781fb1;p=binutils-gdb.git 2011-09-02 Pedro Alves * top.c: Include interps.h. (execute_command): If the target can async, but the interpreter is in sync mode, synchronously wait for the command to finish before returning. (execute_command_to_string): Force the interpreter to sync mode. * infrun.c: Include interps.h. (fetch_inferior_event): Don't restore the prompt yet if the interpreter is in sync mode. * interps.c (interpreter_async): New global. * interps.h (interpreter_async): Declare. * inf-loop.c: Include interps.h. (inferior_event_handler): Don't print the language change or run breakpoint commands yet if the interpreter in is sync mode. * main.c (captured_command_loop): Flip the interpreter to async mode. * cli/cli-script.c: Include interps.h. (execute_user_command, while_command, if_command): Force the interpreter to sync mode. * python/python.c: Include interps.h. (python_command, execute_gdb_command): Force the interpreter to sync mode. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 376188fdf8f..1f278cbd8ae 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2011-09-02 Pedro Alves + + * top.c: Include interps.h. + (execute_command): If the target can async, but the interpreter is + in sync mode, synchronously wait for the command to finish before + returning. + (execute_command_to_string): Force the interpreter to sync mode. + * infrun.c: Include interps.h. + (fetch_inferior_event): Don't restore the prompt yet if the + interpreter is in sync mode. + * interps.c (interpreter_async): New global. + * interps.h (interpreter_async): Declare. + * inf-loop.c: Include interps.h. + (inferior_event_handler): Don't print the language change or run + breakpoint commands yet if the interpreter in is sync mode. + * main.c (captured_command_loop): Flip the interpreter to async + mode. + * cli/cli-script.c: Include interps.h. + (execute_user_command, while_command, if_command): Force the + interpreter to sync mode. + * python/python.c: Include interps.h. + (python_command, execute_gdb_command): Force the interpreter to + sync mode. + 2011-09-02 Pedro Alves * value.c (show_convenience): Catch errors thrown while printing diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c index 66fa220b310..790ce81cc90 100644 --- a/gdb/cli/cli-script.c +++ b/gdb/cli/cli-script.c @@ -35,6 +35,7 @@ #include "gdb_assert.h" #include "python/python.h" +#include "interps.h" /* Prototypes for local functions. */ @@ -338,6 +339,9 @@ execute_user_command (struct cmd_list_element *c, char *args) not confused with Insight. */ in_user_command = 1; + make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + command_nest_depth++; while (cmdlines) { @@ -598,6 +602,7 @@ void while_command (char *arg, int from_tty) { struct command_line *command = NULL; + struct cleanup *old_chain; control_level = 1; command = get_command_line (while_control, arg); @@ -605,8 +610,13 @@ while_command (char *arg, int from_tty) if (command == NULL) return; + old_chain = make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + execute_control_command_untraced (command); free_command_lines (&command); + + do_cleanups (old_chain); } /* "if" command support. Execute either the true or false arm depending @@ -616,6 +626,7 @@ void if_command (char *arg, int from_tty) { struct command_line *command = NULL; + struct cleanup *old_chain; control_level = 1; command = get_command_line (if_control, arg); @@ -623,8 +634,13 @@ if_command (char *arg, int from_tty) if (command == NULL) return; + old_chain = make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + execute_control_command_untraced (command); free_command_lines (&command); + + do_cleanups (old_chain); } /* Cleanup */ diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c index 670b966e7a6..50a739191e0 100644 --- a/gdb/inf-loop.c +++ b/gdb/inf-loop.c @@ -29,6 +29,7 @@ #include "language.h" #include "gdbthread.h" #include "continuations.h" +#include "interps.h" static int fetch_inferior_event_wrapper (gdb_client_data client_data); @@ -40,7 +41,6 @@ void inferior_event_handler (enum inferior_event_type event_type, gdb_client_data client_data) { - struct gdb_exception e; int was_sync = 0; struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup (); @@ -109,19 +109,26 @@ inferior_event_handler (enum inferior_event_type event_type, else do_all_continuations (0); - if (info_verbose - && 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) + /* When running a command list (from a user command, say), these + are only run when the command list is all done. */ + if (interpreter_async) { - bpstat_do_actions (); + volatile struct gdb_exception e; + + if (info_verbose + && 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 (); + } + exception_print (gdb_stderr, e); } - exception_print (gdb_stderr, e); if (!was_sync && exec_done_display_p diff --git a/gdb/infrun.c b/gdb/infrun.c index 6febe07301c..f9b814d74d7 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -55,6 +55,7 @@ #include "jit.h" #include "tracepoint.h" #include "continuations.h" +#include "interps.h" /* Prototypes for local functions */ @@ -2814,7 +2815,7 @@ fetch_inferior_event (void *client_data) /* If the inferior was in sync execution mode, and now isn't, restore the prompt. */ - if (was_sync && !sync_execution) + if (interpreter_async && was_sync && !sync_execution) display_gdb_prompt (0); } diff --git a/gdb/interps.c b/gdb/interps.c index f0428069d48..ff8daf8f7ba 100644 --- a/gdb/interps.c +++ b/gdb/interps.c @@ -43,6 +43,12 @@ #include "exceptions.h" #include "continuations.h" +/* True if the current interpreter in is async mode. See interps.h + for more details. This starts out disabled, until all the explicit + command line arguments (e.g., `gdb -ex "start" -ex "next"') are + processed. */ +int interpreter_async = 0; + struct interp { /* This is the name in "-i=" and set interpreter. */ diff --git a/gdb/interps.h b/gdb/interps.h index 97559d0acf1..a000ef787ec 100644 --- a/gdb/interps.h +++ b/gdb/interps.h @@ -69,6 +69,15 @@ extern void current_interp_command_loop (void); extern void *top_level_interpreter_data (void); extern struct interp *top_level_interpreter (void); +/* True if the current interpreter is in async mode, false if in sync + mode. If in sync mode, running a synchronous execution command + (with execute_command, e.g, "next") will not return until the + command is finished. If in async mode, then running a synchronous + command returns right after resuming the target. Waiting for the + command's completion is later done on the top event loop (using + continuations). */ +extern int interpreter_async; + extern void clear_interpreter_hooks (void); /* well-known interpreters */ diff --git a/gdb/main.c b/gdb/main.c index 187c690b31a..c3816ccde95 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -227,6 +227,10 @@ get_init_files (char **system_gdbinit, static int captured_command_loop (void *data) { + /* Top-level execution commands can be run on the background from + here on. */ + interpreter_async = 1; + current_interp_command_loop (); /* FIXME: cagney/1999-11-05: A correct command_loop() implementaton would clean things up (restoring the cleanup chain) to the state diff --git a/gdb/python/python.c b/gdb/python/python.c index 03edce9e9a2..360bed4ae94 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -52,6 +52,7 @@ static int gdbpy_should_print_stack = 0; #include "target.h" #include "gdbthread.h" #include "observer.h" +#include "interps.h" static PyMethodDef GdbMethods[]; @@ -199,6 +200,10 @@ python_command (char *arg, int from_tty) struct cleanup *cleanup; cleanup = ensure_python_env (get_current_arch (), current_language); + + make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + while (arg && *arg && isspace (*arg)) ++arg; if (arg && *arg) @@ -378,6 +383,9 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) char *copy = xstrdup (arg); struct cleanup *cleanup = make_cleanup (xfree, copy); + make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + prevent_dont_repeat (); if (to_string) result = execute_command_to_string (copy, from_tty); diff --git a/gdb/top.c b/gdb/top.c index 3112d393203..ac371763dc6 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -48,6 +48,7 @@ #include "event-loop.h" #include "gdbthread.h" #include "python/python.h" +#include "interps.h" /* readline include files. */ #include "readline/readline.h" @@ -441,7 +442,18 @@ execute_command (char *p, int from_tty) deprecated_call_command_hook (c, arg, from_tty & caution); else cmd_func (c, arg, from_tty & caution); - + + /* 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. */ + if (!interpreter_async && sync_execution && is_running (inferior_ptid)) + { + while (gdb_do_one_event () >= 0) + if (!sync_execution) + break; + } + /* If this command has been post-hooked, run the hook last. */ execute_cmd_post_hook (c); @@ -497,6 +509,9 @@ execute_command_to_string (char *p, int from_tty) restoration callbacks. */ cleanup = set_batch_flag_and_make_cleanup_restore_page_info (); + make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + str_file = mem_fileopen (); make_cleanup_ui_file_delete (str_file);