From 9204d6922cb80f34dd799e57f7f0c74bc86e7027 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Tue, 21 Jun 2016 01:11:50 +0100 Subject: Make raw_stdout be per MI instance Each MI instance should obviously have its own raw output channel, along with save_raw_stdout. gdb/ChangeLog: 2016-06-21 Pedro Alves * interps.c (current_interpreter): New function. * interps.h (current_interpreter): New declaration. * mi/mi-cmds.h (raw_stdout): Delete declaration. * mi/mi-common.h (struct mi_interp) : New field. * mi/mi-interp.c (display_mi_prompt): New parameter 'mi'. Adjust to per-UI raw_stdout. (mi_interpreter_init): Adjust to per-UI raw_stdout. (mi_on_sync_execution_done, mi_execute_command_input_handler) (mi_command_loop): Pass MI instance to display_mi_prompt. (mi_on_normal_stop_1, mi_output_running_pid, mi_on_resume_1) (mi_on_resume): Adjust to per-UI raw_stdout. (saved_raw_stdout): Delete. (mi_set_logging): Adjust to per-UI raw_stdout and saved_raw_stdout. * mi/mi-main.c (raw_stdout): Delete. (mi_cmd_gdb_exit, captured_mi_execute_command) (mi_print_exception, mi_load_progress): Adjust to per-UI raw_stdout. (print_diff_now, mi_print_timing_maybe): New ui_file parameter. Pass it along. (print_diff): New ui_file parameter. Send output there instead of raw_stdout. * mi/mi-main.h (struct ui_file): Forward declare. (mi_print_timing_maybe): Add ui_file parameter. --- gdb/mi/mi-cmds.h | 3 -- gdb/mi/mi-common.h | 7 ++++ gdb/mi/mi-interp.c | 95 +++++++++++++++++++++++++----------------------------- gdb/mi/mi-main.c | 93 ++++++++++++++++++++++++++++------------------------ gdb/mi/mi-main.h | 4 ++- 5 files changed, 105 insertions(+), 97 deletions(-) (limited to 'gdb/mi') diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h index c3bc777..69472a9 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -157,9 +157,6 @@ extern struct mi_cmd *mi_lookup (const char *command); /* Debug flag */ extern int mi_debug_p; -/* Raw console output - FIXME: should this be a parameter? */ -extern struct ui_file *raw_stdout; - extern void mi_execute_command (const char *cmd, int from_tty); #endif diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h index 7bb706c..c7e4855 100644 --- a/gdb/mi/mi-common.h +++ b/gdb/mi/mi-common.h @@ -57,6 +57,13 @@ struct mi_interp struct ui_file *targ; struct ui_file *event_channel; + /* Raw console output. */ + struct ui_file *raw_stdout; + + /* Save the original value of raw_stdout here when logging, so we + can restore correctly when done. */ + struct ui_file *saved_raw_stdout; + /* MI's builder. */ struct ui_out *mi_uiout; diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index 18f5677..63f05c3 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -92,10 +92,10 @@ static int report_initial_inferior (struct inferior *inf, void *closure); /* Display the MI prompt. */ static void -display_mi_prompt (void) +display_mi_prompt (struct mi_interp *mi) { - fputs_unfiltered ("(gdb) \n", raw_stdout); - gdb_flush (raw_stdout); + fputs_unfiltered ("(gdb) \n", mi->raw_stdout); + gdb_flush (mi->raw_stdout); } /* Returns the INTERP's data cast as mi_interp if INTERP is an MI, and @@ -116,20 +116,18 @@ mi_interpreter_init (struct interp *interp, int top_level) const char *name; int mi_version; - /* Assign the output channel created at startup to its own global, - so that we can create a console channel that encapsulates and - prefixes all gdb_output-type bits coming from the rest of the - debugger. */ - - raw_stdout = gdb_stdout; + /* Store the current output channel, so that we can create a console + channel that encapsulates and prefixes all gdb_output-type bits + coming from the rest of the debugger. */ + mi->raw_stdout = gdb_stdout; /* Create MI console channels, each with a different prefix so they can be distinguished. */ - mi->out = mi_console_file_new (raw_stdout, "~", '"'); - mi->err = mi_console_file_new (raw_stdout, "&", '"'); + mi->out = mi_console_file_new (mi->raw_stdout, "~", '"'); + mi->err = mi_console_file_new (mi->raw_stdout, "&", '"'); mi->log = mi->err; - mi->targ = mi_console_file_new (raw_stdout, "@", '"'); - mi->event_channel = mi_console_file_new (raw_stdout, "=", 0); + mi->targ = mi_console_file_new (mi->raw_stdout, "@", '"'); + mi->event_channel = mi_console_file_new (mi->raw_stdout, "=", 0); name = interp_name (interp); /* INTERP_MI selects the most recent released version. "mi2" was @@ -309,7 +307,7 @@ mi_on_sync_execution_done (void) /* If MI is sync, then output the MI prompt now, indicating we're ready for further input. */ if (!mi_async_p ()) - display_mi_prompt (); + display_mi_prompt (mi); } /* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */ @@ -317,6 +315,8 @@ mi_on_sync_execution_done (void) static void mi_execute_command_input_handler (char *cmd) { + struct mi_interp *mi = as_mi_interp (top_level_interpreter ()); + mi_execute_command_wrapper (cmd); /* Print a prompt, indicating we're ready for further input, unless @@ -325,18 +325,20 @@ mi_execute_command_input_handler (char *cmd) 'synchronous_command_done' observer when the target next stops. */ if (!sync_execution) - display_mi_prompt (); + display_mi_prompt (mi); } static void mi_command_loop (void *data) { + struct mi_interp *mi = (struct mi_interp *) data; + /* Turn off 8 bit strings in quoted output. Any character with the high bit set is printed using C's octal format. */ sevenbit_strings = 1; /* Tell the world that we're alive. */ - display_mi_prompt (); + display_mi_prompt (mi); start_event_loop (); } @@ -682,6 +684,7 @@ mi_on_normal_stop_1 (struct bpstats *bs, int print_frame) 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 ()); + struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data (); if (print_frame) { @@ -723,12 +726,7 @@ mi_on_normal_stop_1 (struct bpstats *bs, int print_frame) && 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); - } + print_stop_event (mi->cli_uiout); tp = inferior_thread (); ui_out_field_int (mi_uiout, "thread-id", tp->global_num); @@ -748,12 +746,12 @@ mi_on_normal_stop_1 (struct bpstats *bs, int print_frame) ui_out_field_int (mi_uiout, "core", core); } - fputs_unfiltered ("*stopped", raw_stdout); - mi_out_put (mi_uiout, raw_stdout); + fputs_unfiltered ("*stopped", mi->raw_stdout); + mi_out_put (mi_uiout, mi->raw_stdout); mi_out_rewind (mi_uiout); - mi_print_timing_maybe (); - fputs_unfiltered ("\n", raw_stdout); - gdb_flush (raw_stdout); + mi_print_timing_maybe (mi->raw_stdout); + fputs_unfiltered ("\n", mi->raw_stdout); + gdb_flush (mi->raw_stdout); } static void @@ -1079,7 +1077,7 @@ mi_output_running_pid (struct thread_info *info, void *arg) continue; if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid)) - fprintf_unfiltered (raw_stdout, + fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"%d\"\n", info->global_num); } @@ -1100,7 +1098,7 @@ mi_inferior_count (struct inferior *inf, void *arg) } static void -mi_on_resume_1 (ptid_t ptid) +mi_on_resume_1 (struct mi_interp *mi, ptid_t ptid) { /* To cater for older frontends, emit ^running, but do it only once per each command. We do it here, since at this point we know @@ -1112,12 +1110,12 @@ mi_on_resume_1 (ptid_t ptid) In future (MI3), we'll be outputting "^done" here. */ if (!running_result_record_printed && mi_proceeded) { - fprintf_unfiltered (raw_stdout, "%s^running\n", + fprintf_unfiltered (mi->raw_stdout, "%s^running\n", current_token ? current_token : ""); } if (ptid_get_pid (ptid) == -1) - fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n"); + fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n"); else if (ptid_is_pid (ptid)) { int count = 0; @@ -1128,7 +1126,7 @@ mi_on_resume_1 (ptid_t ptid) iterate_over_inferiors (mi_inferior_count, &count); if (count == 1) - fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n"); + fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n"); else iterate_over_threads (mi_output_running_pid, &ptid); } @@ -1137,7 +1135,7 @@ mi_on_resume_1 (ptid_t ptid) struct thread_info *ti = find_thread_ptid (ptid); gdb_assert (ti); - fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", + fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"%d\"\n", ti->global_num); } @@ -1150,9 +1148,9 @@ mi_on_resume_1 (ptid_t ptid) checked here because we only need to emit a prompt if a synchronous command was issued when the target is async. */ if (!target_can_async_p () || sync_execution) - fputs_unfiltered ("(gdb) \n", raw_stdout); + fputs_unfiltered ("(gdb) \n", mi->raw_stdout); } - gdb_flush (raw_stdout); + gdb_flush (mi->raw_stdout); } static void @@ -1181,7 +1179,7 @@ mi_on_resume (ptid_t ptid) old_chain = make_cleanup_restore_target_terminal (); target_terminal_ours_for_output (); - mi_on_resume_1 (ptid); + mi_on_resume_1 (mi, ptid); do_cleanups (old_chain); } @@ -1391,11 +1389,6 @@ mi_ui_out (struct interp *interp) return mi->mi_uiout; } -/* Save the original value of raw_stdout here when logging, so we can - restore correctly when done. */ - -static struct ui_file *saved_raw_stdout; - /* Do MI-specific logging actions; save raw_stdout, and change all the consoles to use the supplied ui-file(s). */ @@ -1418,23 +1411,23 @@ mi_set_logging (struct interp *interp, int start_log, if (logfile) { ui_file_delete (out); - out = tee_file_new (raw_stdout, 0, logfile, 0); + out = tee_file_new (mi->raw_stdout, 0, logfile, 0); } - saved_raw_stdout = raw_stdout; - raw_stdout = out; + mi->saved_raw_stdout = mi->raw_stdout; + mi->raw_stdout = out; } else { - raw_stdout = saved_raw_stdout; - saved_raw_stdout = NULL; + mi->raw_stdout = mi->saved_raw_stdout; + mi->saved_raw_stdout = NULL; } - mi_console_set_raw (mi->out, raw_stdout); - mi_console_set_raw (mi->err, raw_stdout); - mi_console_set_raw (mi->log, raw_stdout); - mi_console_set_raw (mi->targ, raw_stdout); - mi_console_set_raw (mi->event_channel, raw_stdout); + mi_console_set_raw (mi->out, mi->raw_stdout); + mi_console_set_raw (mi->err, mi->raw_stdout); + mi_console_set_raw (mi->log, mi->raw_stdout); + mi_console_set_raw (mi->targ, mi->raw_stdout); + mi_console_set_raw (mi->event_channel, mi->raw_stdout); return 1; } diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index d53bcc7..8e51edc 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -72,8 +72,6 @@ enum int mi_debug_p; -struct ui_file *raw_stdout; - /* This is used to pass the current command timestamp down to continuation routines. */ static struct mi_timestamp *current_command_ts; @@ -149,18 +147,21 @@ mi_async_p (void) static void timestamp (struct mi_timestamp *tv); -static void print_diff_now (struct mi_timestamp *start); -static void print_diff (struct mi_timestamp *start, struct mi_timestamp *end); +static void print_diff (struct ui_file *file, struct mi_timestamp *start, + struct mi_timestamp *end); void mi_cmd_gdb_exit (char *command, char **argv, int argc) { + struct mi_interp *mi + = (struct mi_interp *) interp_data (current_interpreter ()); + /* We have to print everything right here because we never return. */ if (current_token) - fputs_unfiltered (current_token, raw_stdout); - fputs_unfiltered ("^exit\n", raw_stdout); - mi_out_put (current_uiout, raw_stdout); - gdb_flush (raw_stdout); + fputs_unfiltered (current_token, mi->raw_stdout); + fputs_unfiltered ("^exit\n", mi->raw_stdout); + mi_out_put (current_uiout, mi->raw_stdout); + gdb_flush (mi->raw_stdout); /* FIXME: The function called is not yet a formal libgdb function. */ quit_force (NULL, FROM_TTY); } @@ -1983,6 +1984,7 @@ mi_cmd_remove_inferior (char *command, char **argv, int argc) static void captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context) { + struct mi_interp *mi = (struct mi_interp *) interp_data (command_interp ()); struct cleanup *cleanup; if (do_timings) @@ -1999,7 +2001,8 @@ captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context) /* 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", + fprintf_unfiltered (mi->raw_stdout, + " token=`%s' command=`%s' args=`%s'\n", context->token, context->command, context->args); mi_cmd_execute (context); @@ -2012,15 +2015,15 @@ captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context) uiout will most likely crash in the mi_out_* routines. */ if (!running_result_record_printed) { - fputs_unfiltered (context->token, raw_stdout); + fputs_unfiltered (context->token, mi->raw_stdout); /* There's no particularly good reason why target-connect results in not ^done. Should kill ^connected for MI3. */ fputs_unfiltered (strcmp (context->command, "target-select") == 0 - ? "^connected" : "^done", raw_stdout); - mi_out_put (uiout, raw_stdout); + ? "^connected" : "^done", mi->raw_stdout); + mi_out_put (uiout, mi->raw_stdout); mi_out_rewind (uiout); - mi_print_timing_maybe (); - fputs_unfiltered ("\n", raw_stdout); + mi_print_timing_maybe (mi->raw_stdout); + fputs_unfiltered ("\n", mi->raw_stdout); } else /* The command does not want anything to be printed. In that @@ -2051,12 +2054,12 @@ captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context) { if (!running_result_record_printed) { - fputs_unfiltered (context->token, raw_stdout); - fputs_unfiltered ("^done", raw_stdout); - mi_out_put (uiout, raw_stdout); + fputs_unfiltered (context->token, mi->raw_stdout); + fputs_unfiltered ("^done", mi->raw_stdout); + mi_out_put (uiout, mi->raw_stdout); mi_out_rewind (uiout); - mi_print_timing_maybe (); - fputs_unfiltered ("\n", raw_stdout); + mi_print_timing_maybe (mi->raw_stdout); + fputs_unfiltered ("\n", mi->raw_stdout); } else mi_out_rewind (uiout); @@ -2073,22 +2076,25 @@ captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context) static void mi_print_exception (const char *token, struct gdb_exception exception) { - fputs_unfiltered (token, raw_stdout); - fputs_unfiltered ("^error,msg=\"", raw_stdout); + struct mi_interp *mi + = (struct mi_interp *) interp_data (current_interpreter ()); + + fputs_unfiltered (token, mi->raw_stdout); + fputs_unfiltered ("^error,msg=\"", mi->raw_stdout); if (exception.message == NULL) - fputs_unfiltered ("unknown error", raw_stdout); + fputs_unfiltered ("unknown error", mi->raw_stdout); else - fputstr_unfiltered (exception.message, '"', raw_stdout); - fputs_unfiltered ("\"", raw_stdout); + fputstr_unfiltered (exception.message, '"', mi->raw_stdout); + fputs_unfiltered ("\"", mi->raw_stdout); switch (exception.error) { case UNDEFINED_COMMAND_ERROR: - fputs_unfiltered (",code=\"undefined-command\"", raw_stdout); + fputs_unfiltered (",code=\"undefined-command\"", mi->raw_stdout); break; } - fputs_unfiltered ("\n", raw_stdout); + fputs_unfiltered ("\n", mi->raw_stdout); } void @@ -2358,6 +2364,8 @@ mi_load_progress (const char *section_name, int new_section; struct ui_out *saved_uiout; struct ui_out *uiout; + struct mi_interp *mi + = (struct mi_interp *) interp_data (current_interpreter ()); /* This function is called through deprecated_show_load_progress which means uiout may not be correct. Fix it for the duration @@ -2399,16 +2407,16 @@ mi_load_progress (const char *section_name, previous_sect_name = xstrdup (section_name); if (current_token) - fputs_unfiltered (current_token, raw_stdout); - fputs_unfiltered ("+download", raw_stdout); + fputs_unfiltered (current_token, mi->raw_stdout); + fputs_unfiltered ("+download", mi->raw_stdout); cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "section", section_name); ui_out_field_int (uiout, "section-size", total_section); ui_out_field_int (uiout, "total-size", grand_total); do_cleanups (cleanup_tuple); - mi_out_put (uiout, raw_stdout); - fputs_unfiltered ("\n", raw_stdout); - gdb_flush (raw_stdout); + mi_out_put (uiout, mi->raw_stdout); + fputs_unfiltered ("\n", mi->raw_stdout); + gdb_flush (mi->raw_stdout); } if (delta.tv_sec >= update_threshold.tv_sec && @@ -2419,8 +2427,8 @@ mi_load_progress (const char *section_name, last_update.tv_sec = time_now.tv_sec; last_update.tv_usec = time_now.tv_usec; if (current_token) - fputs_unfiltered (current_token, raw_stdout); - fputs_unfiltered ("+download", raw_stdout); + fputs_unfiltered (current_token, mi->raw_stdout); + fputs_unfiltered ("+download", mi->raw_stdout); cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "section", section_name); ui_out_field_int (uiout, "section-sent", sent_so_far); @@ -2428,9 +2436,9 @@ mi_load_progress (const char *section_name, ui_out_field_int (uiout, "total-sent", total_sent); ui_out_field_int (uiout, "total-size", grand_total); do_cleanups (cleanup_tuple); - mi_out_put (uiout, raw_stdout); - fputs_unfiltered ("\n", raw_stdout); - gdb_flush (raw_stdout); + mi_out_put (uiout, mi->raw_stdout); + fputs_unfiltered ("\n", mi->raw_stdout); + gdb_flush (mi->raw_stdout); } xfree (uiout); @@ -2460,21 +2468,21 @@ timestamp (struct mi_timestamp *tv) } static void -print_diff_now (struct mi_timestamp *start) +print_diff_now (struct ui_file *file, struct mi_timestamp *start) { struct mi_timestamp now; timestamp (&now); - print_diff (start, &now); + print_diff (file, start, &now); } void -mi_print_timing_maybe (void) +mi_print_timing_maybe (struct ui_file *file) { /* If the command is -enable-timing then do_timings may be true whilst current_command_ts is not initialized. */ if (do_timings && current_command_ts) - print_diff_now (current_command_ts); + print_diff_now (file, current_command_ts); } static long @@ -2485,10 +2493,11 @@ timeval_diff (struct timeval start, struct timeval end) } static void -print_diff (struct mi_timestamp *start, struct mi_timestamp *end) +print_diff (struct ui_file *file, struct mi_timestamp *start, + struct mi_timestamp *end) { fprintf_unfiltered - (raw_stdout, + (file, ",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}", timeval_diff (start->wallclock, end->wallclock) / 1000000.0, timeval_diff (start->utime, end->utime) / 1000000.0, diff --git a/gdb/mi/mi-main.h b/gdb/mi/mi-main.h index b2face1..18000cf 100644 --- a/gdb/mi/mi-main.h +++ b/gdb/mi/mi-main.h @@ -20,13 +20,15 @@ #ifndef MI_MAIN_H #define MI_MAIN_H +struct ui_file; + extern void mi_load_progress (const char *section_name, unsigned long sent_so_far, unsigned long total_section, unsigned long total_sent, unsigned long grand_total); -extern void mi_print_timing_maybe (void); +extern void mi_print_timing_maybe (struct ui_file *file); /* Whether MI is in async mode. */ -- cgit v1.1