static int captured_command_loop (void *data) { struct ui *ui = current_ui; /* Top-level execution commands can be run in the background from here on. */ current_ui->async = 1; /* Give the interpreter a chance to print a prompt, if necessary */ if (ui->prompt_state != PROMPT_BLOCKED) interp_pre_command_loop (top_level_interpreter ()); /* Now it's time to start the event loop. */ start_event_loop (); /* FIXME: cagney/1999-11-05: A correct command_loop() implementaton would clean things up (restoring the cleanup chain) to the state they were just prior to the call. Technically, this means that the do_cleanups() below is redundant. Unfortunately, many FUNCs are not that well behaved. do_cleanups should either be replaced with a do_cleanups call (to cover the problem) or an assertion check to detect bad FUNCs code. */ do_cleanups (all_cleanups ()); /* If the command_loop returned, normally (rather than threw an error) we try to quit. If the quit is aborted, catch_errors() which called this catch the signal and restart the command loop. */ quit_command (NULL, ui->instream == ui->stdin_stream); return 1; }
static void mi_solib_loaded (struct so_list *solib) { struct mi_interp *mi = top_level_interpreter_data (); struct ui_out *uiout = interp_ui_out (top_level_interpreter ()); target_terminal_ours (); fprintf_unfiltered (mi->event_channel, "library-loaded"); ui_out_redirect (uiout, mi->event_channel); ui_out_field_string (uiout, "id", solib->so_original_name); ui_out_field_string (uiout, "target-name", solib->so_original_name); ui_out_field_string (uiout, "host-name", solib->so_name); ui_out_field_int (uiout, "symbols-loaded", solib->symbols_loaded); if (!gdbarch_has_global_solist (target_gdbarch ())) { ui_out_field_fmt (uiout, "thread-group", "i%d", current_inferior ()->num); } ui_out_redirect (uiout, NULL); gdb_flush (mi->event_channel); }
void change_line_handler (int editing) { struct ui *ui = current_ui; /* We can only have one instance of readline, so we only allow editing on the main UI. */ if (ui != main_ui) return; /* Don't try enabling editing if the interpreter doesn't support it (e.g., MI). */ if (!interp_supports_command_editing (top_level_interpreter ()) || !interp_supports_command_editing (command_interp ())) return; if (editing) { gdb_assert (ui == main_ui); /* Turn on editing by using readline. */ ui->call_readline = gdb_rl_callback_read_char_wrapper; } else { /* Turn off editing by using gdb_readline_no_editing_callback. */ if (ui->command_editing) gdb_rl_callback_handler_remove (); ui->call_readline = gdb_readline_no_editing_callback; } ui->command_editing = editing; }
static void mi_breakpoint_modified (struct breakpoint *b) { struct mi_interp *mi = top_level_interpreter_data (); struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); volatile struct gdb_exception e; if (mi_suppress_notification.breakpoint) return; if (b->number <= 0) return; target_terminal_ours (); fprintf_unfiltered (mi->event_channel, "breakpoint-modified"); /* We want the output from gdb_breakpoint_query to go to mi->event_channel. One approach would be to just call gdb_breakpoint_query, and then use mi_out_put to send the current content of mi_outout into mi->event_channel. However, that will break if anything is output to mi_uiout prior to calling the breakpoint_created notifications. So, we use ui_out_redirect. */ ui_out_redirect (mi_uiout, mi->event_channel); TRY_CATCH (e, RETURN_MASK_ERROR) gdb_breakpoint_query (mi_uiout, b->number, NULL); ui_out_redirect (mi_uiout, NULL); gdb_flush (mi->event_channel); }
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); }
SWITCH_THRU_ALL_UIS () { struct cli_interp *cli = as_cli_interp (top_level_interpreter ()); if (cli == NULL) continue; print_signal_received_reason (cli->cli_uiout, siggnal); }
SWITCH_THRU_ALL_UIS () { struct interp *tui = as_tui_interp (top_level_interpreter ()); if (tui == NULL) continue; print_signal_received_reason (tui_ui_out (tui), siggnal); }
static struct interp * find_mi_interpreter (void) { struct interp *interp; interp = top_level_interpreter (); if (ui_out_is_mi_like_p (interp_ui_out (interp))) return interp; interp = command_interp (); if (ui_out_is_mi_like_p (interp_ui_out (interp))) return interp; return NULL; }
static void cli_on_normal_stop (struct bpstats *bs, int print_frame) { if (!print_frame) return; SWITCH_THRU_ALL_UIS () { struct interp *interp = top_level_interpreter (); struct cli_interp *cli = as_cli_interp (interp); struct thread_info *thread; if (cli == NULL) continue; thread = inferior_thread (); if (should_print_stop_to_console (interp, thread)) print_stop_event (cli->cli_uiout); } }
static void mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr, ssize_t len, const bfd_byte *myaddr) { struct mi_interp *mi = top_level_interpreter_data (); struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); struct obj_section *sec; if (mi_suppress_notification.memory) return; target_terminal_ours (); fprintf_unfiltered (mi->event_channel, "memory-changed"); ui_out_redirect (mi_uiout, mi->event_channel); ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num); ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch (), memaddr); ui_out_field_fmt (mi_uiout, "len", "%s", hex_string (len)); /* Append 'type=code' into notification if MEMADDR falls in the range of sections contain code. */ sec = find_pc_section (memaddr); if (sec != NULL && sec->objfile != NULL) { flagword flags = bfd_get_section_flags (sec->objfile->obfd, sec->the_bfd_section); if (flags & SEC_CODE) ui_out_field_string (mi_uiout, "type", "code"); } ui_out_redirect (mi_uiout, NULL); gdb_flush (mi->event_channel); }
static void mi_tsv_modified (const struct trace_state_variable *tsv) { struct mi_interp *mi = top_level_interpreter_data (); struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); target_terminal_ours (); fprintf_unfiltered (mi->event_channel, "tsv-modified"); ui_out_redirect (mi_uiout, mi->event_channel); ui_out_field_string (mi_uiout, "name", tsv->name); ui_out_field_string (mi_uiout, "initial", plongest (tsv->initial_value)); if (tsv->value_known) ui_out_field_string (mi_uiout, "current", plongest (tsv->value)); ui_out_redirect (mi_uiout, NULL); gdb_flush (mi->event_channel); }
static void mi_command_param_changed (const char *param, const char *value) { struct mi_interp *mi = top_level_interpreter_data (); struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); if (mi_suppress_notification.cmd_param_changed) return; target_terminal_ours (); fprintf_unfiltered (mi->event_channel, "cmd-param-changed"); ui_out_redirect (mi_uiout, mi->event_channel); ui_out_field_string (mi_uiout, "param", param); ui_out_field_string (mi_uiout, "value", value); ui_out_redirect (mi_uiout, NULL); gdb_flush (mi->event_channel); }
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); }
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); }