void mi_execute_command (char *cmd, int from_tty) { struct mi_parse *command; struct captured_mi_execute_command_args args; struct ui_out *saved_uiout = uiout; /* This is to handle EOF (^D). We just quit gdb. */ /* FIXME: we should call some API function here. */ if (cmd == 0) quit_force (NULL, from_tty); command = mi_parse (cmd); if (command != NULL) { struct gdb_exception result; if (do_timings) { command->cmd_start = (struct mi_timestamp *) xmalloc (sizeof (struct mi_timestamp)); timestamp (command->cmd_start); } /* FIXME: cagney/1999-11-04: Can this use of catch_exceptions either be pushed even further down or even eliminated? */ args.command = command; result = catch_exception (uiout, captured_mi_execute_command, &args, RETURN_MASK_ALL); exception_print (gdb_stderr, result); if (args.action == EXECUTE_COMMAND_SUPRESS_PROMPT) { /* The command is executing synchronously. Bail out early suppressing the finished prompt. */ mi_parse_free (command); return; } if (result.reason < 0) { /* The command execution failed and error() was called somewhere. */ fputs_unfiltered (command->token, raw_stdout); fputs_unfiltered ("^error,msg=\"", raw_stdout); if (result.message == NULL) fputs_unfiltered ("unknown error", raw_stdout); else fputstr_unfiltered (result.message, '"', raw_stdout); fputs_unfiltered ("\"\n", raw_stdout); mi_out_rewind (uiout); } mi_parse_free (command); } fputs_unfiltered ("(gdb) \n", raw_stdout); gdb_flush (raw_stdout); /* Print any buffered hook code. */ /* ..... */ }
/* Connect to the remote target. */ enum mi_cmd_result mi_cmd_target_select (char *args, int from_tty) { char *run; struct cleanup *old_cleanups = NULL; run = xstrprintf ("target %s", args); old_cleanups = make_cleanup (xfree, run); /* target-select is always synchronous. once the call has returned we know that we are connected. */ /* NOTE: At present all targets that are connected are also (implicitly) talking to a halted target. In the future this may change. */ execute_command (run, from_tty); do_cleanups (old_cleanups); /* Issue the completion message here. */ if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("^connected", raw_stdout); mi_out_put (uiout, raw_stdout); mi_out_rewind (uiout); fputs_unfiltered ("\n", raw_stdout); do_exec_cleanups (ALL_CLEANUPS); return MI_CMD_QUIET; }
static void mi_on_normal_stop (struct bpstats *bs, int print_frame) { /* Since this can be called when CLI command is executing, using cli interpreter, be sure to use MI uiout for output, not the current one. */ struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); if (print_frame) { int core; if (current_uiout != mi_uiout) { /* The normal_stop function has printed frame information into CLI uiout, or some other non-MI uiout. There's no way we can extract proper fields from random uiout object, so we print the frame again. In practice, this can only happen when running a CLI command in MI. */ struct ui_out *saved_uiout = current_uiout; struct target_waitstatus last; ptid_t last_ptid; current_uiout = mi_uiout; get_last_target_status (&last_ptid, &last); bpstat_print (bs, last.kind); print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1); current_uiout = saved_uiout; } ui_out_field_int (mi_uiout, "thread-id", pid_to_thread_id (inferior_ptid)); if (non_stop) { struct cleanup *back_to = make_cleanup_ui_out_list_begin_end (mi_uiout, "stopped-threads"); ui_out_field_int (mi_uiout, NULL, pid_to_thread_id (inferior_ptid)); do_cleanups (back_to); } else ui_out_field_string (mi_uiout, "stopped-threads", "all"); core = target_core_of_thread (inferior_ptid); if (core != -1) ui_out_field_int (mi_uiout, "core", core); } fputs_unfiltered ("*stopped", raw_stdout); mi_out_put (mi_uiout, raw_stdout); mi_out_rewind (mi_uiout); mi_print_timing_maybe (); fputs_unfiltered ("\n", raw_stdout); gdb_flush (raw_stdout); }
/* Interrupt the execution of the target. Note how we must play around with the token varialbes, in order to display the current token in the result of the interrupt command, and the previous execution token when the target finally stops. See comments in mi_cmd_execute. */ enum mi_cmd_result mi_cmd_exec_interrupt (char *args, int from_tty) { if (!target_executing) { mi_error_message = xstrprintf ("mi_cmd_exec_interrupt: Inferior not executing."); return MI_CMD_ERROR; } interrupt_target_command (args, from_tty); if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("^done", raw_stdout); xfree (last_async_command); if (previous_async_command) last_async_command = xstrdup (previous_async_command); xfree (previous_async_command); previous_async_command = NULL; mi_out_put (uiout, raw_stdout); mi_out_rewind (uiout); fputs_unfiltered ("\n", raw_stdout); return MI_CMD_QUIET; }
static void mi_on_normal_stop (struct bpstats *bs, int print_frame) { /* Since this can be called when CLI command is executing, using cli interpreter, be sure to use MI uiout for output, not the current one. */ struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); if (print_frame) { int core; if (current_uiout != mi_uiout) { /* The normal_stop function has printed frame information into CLI uiout, or some other non-MI uiout. There's no way we can extract proper fields from random uiout object, so we print the frame again. In practice, this can only happen when running a CLI command in MI. */ struct ui_out *saved_uiout = current_uiout; struct target_waitstatus last; ptid_t last_ptid; current_uiout = mi_uiout; get_last_target_status (&last_ptid, &last); print_stop_event (&last); current_uiout = saved_uiout; } /* Otherwise, frame information has already been printed by normal_stop. */ else { /* Breakpoint hits should always be mirrored to the console. Deciding what to mirror to the console wrt to breakpoints and random stops gets messy real fast. E.g., say "s" trips on a breakpoint. We'd clearly want to mirror the event to the console in this case. But what about more complicated cases like "s&; thread n; s&", and one of those steps spawning a new thread, and that thread hitting a breakpoint? It's impossible in general to track whether the thread had any relation to the commands that had been executed. So we just simplify and always mirror breakpoints and random events to the console. Also, CLI execution commands (-interpreter-exec console "next", for example) in async mode have the opposite issue as described in the "then" branch above -- normal_stop has already printed frame information to MI uiout, but nothing has printed the same information to the CLI channel. We should print the source line to the console when stepping or other similar commands, iff the step was started by a console command (but not if it was started with -exec-step or similar). */ struct thread_info *tp = inferior_thread (); if ((!tp->control.stop_step && !tp->control.proceed_to_finish) || (tp->control.command_interp != NULL && tp->control.command_interp != top_level_interpreter ())) { struct mi_interp *mi = top_level_interpreter_data (); struct target_waitstatus last; ptid_t last_ptid; struct cleanup *old_chain; /* Set the current uiout to CLI uiout temporarily. */ old_chain = make_cleanup (restore_current_uiout_cleanup, current_uiout); current_uiout = mi->cli_uiout; get_last_target_status (&last_ptid, &last); print_stop_event (&last); do_cleanups (old_chain); } } ui_out_field_int (mi_uiout, "thread-id", pid_to_thread_id (inferior_ptid)); if (non_stop) { struct cleanup *back_to = make_cleanup_ui_out_list_begin_end (mi_uiout, "stopped-threads"); ui_out_field_int (mi_uiout, NULL, pid_to_thread_id (inferior_ptid)); do_cleanups (back_to); } else ui_out_field_string (mi_uiout, "stopped-threads", "all"); core = target_core_of_thread (inferior_ptid); if (core != -1) ui_out_field_int (mi_uiout, "core", core); } fputs_unfiltered ("*stopped", raw_stdout); mi_out_put (mi_uiout, raw_stdout); mi_out_rewind (mi_uiout); mi_print_timing_maybe (); fputs_unfiltered ("\n", raw_stdout); gdb_flush (raw_stdout); }
enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty) { struct cleanup *old_cleanups; char *run; char *async_args; if (target_can_async_p ()) { async_args = (char *) xmalloc (strlen (args) + 2); make_exec_cleanup (free, async_args); strcpy (async_args, args); strcat (async_args, "&"); run = xstrprintf ("%s %s", mi, async_args); make_exec_cleanup (free, run); add_continuation (mi_exec_async_cli_cmd_continuation, NULL); old_cleanups = NULL; } else { run = xstrprintf ("%s %s", mi, args); old_cleanups = make_cleanup (xfree, run); } if (!target_can_async_p ()) { /* NOTE: For synchronous targets asynchronous behavour is faked by printing out the GDB prompt before we even try to execute the command. */ if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("^running\n", raw_stdout); fputs_unfiltered ("(gdb) \n", raw_stdout); gdb_flush (raw_stdout); } else { /* FIXME: cagney/1999-11-29: Printing this message before calling execute_command is wrong. It should only be printed once gdb has confirmed that it really has managed to send a run command to the target. */ if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("^running\n", raw_stdout); } execute_command ( /*ui */ run, 0 /*from_tty */ ); if (!target_can_async_p ()) { /* Do this before doing any printing. It would appear that some print code leaves garbage around in the buffer. */ do_cleanups (old_cleanups); /* If the target was doing the operation synchronously we fake the stopped message. */ if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("*stopped", raw_stdout); mi_out_put (uiout, raw_stdout); mi_out_rewind (uiout); fputs_unfiltered ("\n", raw_stdout); return MI_CMD_QUIET; } return MI_CMD_DONE; }
static void captured_mi_execute_command (struct ui_out *uiout, void *data) { struct captured_mi_execute_command_args *args = (struct captured_mi_execute_command_args *) data; struct mi_parse *context = args->command; switch (context->op) { case MI_COMMAND: /* A MI command was read from the input stream */ if (mi_debug_p) /* FIXME: gdb_???? */ fprintf_unfiltered (raw_stdout, " token=`%s' command=`%s' args=`%s'\n", context->token, context->command, context->args); /* FIXME: cagney/1999-09-25: Rather than this convoluted condition expression, each function should return an indication of what action is required and then switch on that. */ args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; args->rc = mi_cmd_execute (context); if (!target_can_async_p () || !target_executing) { /* print the result if there were no errors Remember that on the way out of executing a command, you have to directly use the mi_interp's uiout, since the command could have reset the interpreter, in which case the current uiout will most likely crash in the mi_out_* routines. */ if (args->rc == MI_CMD_DONE) { fputs_unfiltered (context->token, raw_stdout); fputs_unfiltered ("^done", raw_stdout); mi_out_put (uiout, raw_stdout); mi_out_rewind (uiout); fputs_unfiltered ("\n", raw_stdout); } else if (args->rc == MI_CMD_ERROR) { if (mi_error_message) { fputs_unfiltered (context->token, raw_stdout); fputs_unfiltered ("^error,msg=\"", raw_stdout); fputstr_unfiltered (mi_error_message, '"', raw_stdout); xfree (mi_error_message); fputs_unfiltered ("\"\n", raw_stdout); } mi_out_rewind (uiout); } else mi_out_rewind (uiout); } else if (sync_execution) { /* Don't print the prompt. We are executing the target in synchronous mode. */ args->action = EXECUTE_COMMAND_SUPRESS_PROMPT; return; } break; case CLI_COMMAND: { char *argv[2]; /* A CLI command was read from the input stream. */ /* This "feature" will be removed as soon as we have a complete set of mi commands. */ /* Echo the command on the console. */ fprintf_unfiltered (gdb_stdlog, "%s\n", context->command); /* Call the "console" interpreter. */ argv[0] = "console"; argv[1] = context->command; args->rc = mi_cmd_interpreter_exec ("-interpreter-exec", argv, 2); /* If we changed interpreters, DON'T print out anything. */ if (current_interp_named_p (INTERP_MI) || current_interp_named_p (INTERP_MI1) || current_interp_named_p (INTERP_MI2) || current_interp_named_p (INTERP_MI3)) { if (args->rc == MI_CMD_DONE) { fputs_unfiltered (context->token, raw_stdout); fputs_unfiltered ("^done", raw_stdout); mi_out_put (uiout, raw_stdout); mi_out_rewind (uiout); fputs_unfiltered ("\n", raw_stdout); args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; } else if (args->rc == MI_CMD_ERROR) { if (mi_error_message) { fputs_unfiltered (context->token, raw_stdout); fputs_unfiltered ("^error,msg=\"", raw_stdout); fputstr_unfiltered (mi_error_message, '"', raw_stdout); xfree (mi_error_message); fputs_unfiltered ("\"\n", raw_stdout); } mi_out_rewind (uiout); } else mi_out_rewind (uiout); } break; } } return; }
static void mi_on_normal_stop (struct bpstats *bs, int print_frame) { /* Since this can be called when CLI command is executing, using cli interpreter, be sure to use MI uiout for output, not the current one. */ struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); if (print_frame) { struct thread_info *tp; int core; tp = inferior_thread (); if (tp->thread_fsm != NULL && thread_fsm_finished_p (tp->thread_fsm)) { enum async_reply_reason reason; reason = thread_fsm_async_reply_reason (tp->thread_fsm); ui_out_field_string (mi_uiout, "reason", async_reason_lookup (reason)); } print_stop_event (mi_uiout); /* Breakpoint hits should always be mirrored to the console. Deciding what to mirror to the console wrt to breakpoints and random stops gets messy real fast. E.g., say "s" trips on a breakpoint. We'd clearly want to mirror the event to the console in this case. But what about more complicated cases like "s&; thread n; s&", and one of those steps spawning a new thread, and that thread hitting a breakpoint? It's impossible in general to track whether the thread had any relation to the commands that had been executed. So we just simplify and always mirror breakpoints and random events to the console. OTOH, we should print the source line to the console when stepping or other similar commands, iff the step was started by a console command, but not if it was started with -exec-step or similar. */ if ((bpstat_what (tp->control.stop_bpstat).main_action == BPSTAT_WHAT_STOP_NOISY) || !(tp->thread_fsm != NULL && thread_fsm_finished_p (tp->thread_fsm)) || (tp->control.command_interp != NULL && tp->control.command_interp != top_level_interpreter ())) { struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data (); print_stop_event (mi->cli_uiout); } ui_out_field_int (mi_uiout, "thread-id", pid_to_thread_id (inferior_ptid)); if (non_stop) { struct cleanup *back_to = make_cleanup_ui_out_list_begin_end (mi_uiout, "stopped-threads"); ui_out_field_int (mi_uiout, NULL, pid_to_thread_id (inferior_ptid)); do_cleanups (back_to); } else ui_out_field_string (mi_uiout, "stopped-threads", "all"); core = target_core_of_thread (inferior_ptid); if (core != -1) ui_out_field_int (mi_uiout, "core", core); } fputs_unfiltered ("*stopped", raw_stdout); mi_out_put (mi_uiout, raw_stdout); mi_out_rewind (mi_uiout); mi_print_timing_maybe (); fputs_unfiltered ("\n", raw_stdout); gdb_flush (raw_stdout); }