Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(534)

Unified Diff: gdb/mi/mi-interp.c

Issue 11969036: Merge GDB 7.5.1 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gdb/mi/mi-getopt.c ('k') | gdb/mi/mi-main.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gdb/mi/mi-interp.c
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index c9cd24d676a850f35982cccaeb9a1168b88e630e..b48713676e12470b69e7a8bedca3d4fdd694e09b 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -36,15 +36,19 @@
#include "solist.h"
#include "gdb.h"
-/* These are the interpreter setup, etc. functions for the MI interpreter */
+/* These are the interpreter setup, etc. functions for the MI
+ interpreter. */
+
static void mi_execute_command_wrapper (char *cmd);
+static void mi_execute_command_input_handler (char *cmd);
static void mi_command_loop (int mi_version);
/* These are hooks that we put in place while doing interpreter_exec
- so we can report interesting things that happened "behind the mi's
- back" in this command */
+ so we can report interesting things that happened "behind the MI's
+ back" in this command. */
+
static int mi_interp_query_hook (const char *ctlstr, va_list ap)
- ATTRIBUTE_PRINTF (1, 0);
+ ATTRIBUTE_PRINTF (1, 0);
static void mi3_command_loop (void);
static void mi2_command_loop (void);
@@ -77,14 +81,15 @@ mi_interpreter_init (struct interp *interp, int top_level)
const char *name;
int mi_version;
- /* HACK: We need to force stdout/stderr to point at the console. This avoids
- any potential side effects caused by legacy code that is still
- using the TUI / fputs_unfiltered_hook. So we set up output channels for
- this now, and swap them in when we are run. */
+ /* 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 = stdio_fileopen (stdout);
+ raw_stdout = gdb_stdout;
- /* Create MI channels */
+ /* 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->log = mi->err;
@@ -124,9 +129,10 @@ mi_interpreter_init (struct interp *interp, int top_level)
observer_attach_breakpoint_deleted (mi_breakpoint_deleted);
observer_attach_breakpoint_modified (mi_breakpoint_modified);
- /* The initial inferior is created before this function is called, so we
- need to report it explicitly. Use iteration in case future version
- of GDB creates more than one inferior up-front. */
+ /* The initial inferior is created before this function is
+ called, so we need to report it explicitly. Use iteration in
+ case future version of GDB creates more than one inferior
+ up-front. */
iterate_over_inferiors (report_initial_inferior, mi);
}
@@ -138,13 +144,14 @@ mi_interpreter_resume (void *data)
{
struct mi_interp *mi = data;
- /* As per hack note in mi_interpreter_init, swap in the output channels... */
+ /* As per hack note in mi_interpreter_init, swap in the output
+ channels... */
gdb_setup_readline ();
/* These overwrite some of the initialization done in
_intialize_event_loop. */
call_readline = gdb_readline2;
- input_handler = mi_execute_command_wrapper;
+ input_handler = mi_execute_command_input_handler;
add_file_handler (input_fd, stdin_event_handler, 0);
async_command_editing_p = 0;
/* FIXME: This is a total hack for now. PB's use of the MI
@@ -156,12 +163,12 @@ mi_interpreter_resume (void *data)
sync_execution = 0;
gdb_stdout = mi->out;
- /* Route error and log output through the MI */
+ /* Route error and log output through the MI. */
gdb_stderr = mi->err;
gdb_stdlog = mi->log;
- /* Route target output through the MI. */
+ /* Route target output through the MI. */
gdb_stdtarg = mi->targ;
- /* Route target error through the MI as well. */
+ /* Route target error through the MI as well. */
gdb_stdtargerr = mi->targ;
/* Replace all the hooks that we know about. There really needs to
@@ -170,7 +177,7 @@ mi_interpreter_resume (void *data)
deprecated_show_load_progress = mi_load_progress;
- /* If we're _the_ interpreter, take control. */
+ /* If we're _the_ interpreter, take control. */
if (current_interp_named_p (INTERP_MI1))
deprecated_command_loop_hook = mi1_command_loop;
else if (current_interp_named_p (INTERP_MI2))
@@ -200,7 +207,8 @@ mi_interpreter_exec (void *data, const char *command)
return exception_none;
}
-/* Never display the default gdb prompt in mi case. */
+/* Never display the default GDB prompt in MI case. */
+
static int
mi_interpreter_prompt_p (void *data)
{
@@ -229,13 +237,14 @@ mi_cmd_interpreter_exec (char *command, char **argv, int argc)
"does not support command execution"),
argv[0]);
- /* Insert the MI out hooks, making sure to also call the interpreter's hooks
- if it has any. */
- /* KRS: We shouldn't need this... Events should be installed and they should
- just ALWAYS fire something out down the MI channel... */
+ /* Insert the MI out hooks, making sure to also call the
+ interpreter's hooks if it has any. */
+ /* KRS: We shouldn't need this... Events should be installed and
+ they should just ALWAYS fire something out down the MI
+ channel. */
mi_insert_notify_hooks ();
- /* Now run the code... */
+ /* Now run the code. */
old_chain = make_cleanup (null_cleanup, 0);
for (i = 1; i < argc; i++)
@@ -257,14 +266,12 @@ mi_cmd_interpreter_exec (char *command, char **argv, int argc)
do_cleanups (old_chain);
}
-/*
- * mi_insert_notify_hooks - This inserts a number of hooks that are
- * meant to produce async-notify ("=") MI messages while running
- * commands in another interpreter using mi_interpreter_exec. The
- * canonical use for this is to allow access to the gdb CLI
- * interpreter from within the MI, while still producing MI style
- * output when actions in the CLI command change gdb's state.
-*/
+/* This inserts a number of hooks that are meant to produce
+ async-notify ("=") MI messages while running commands in another
+ interpreter using mi_interpreter_exec. The canonical use for this
+ is to allow access to the gdb CLI interpreter from within the MI,
+ while still producing MI style output when actions in the CLI
+ command change GDB's state. */
static void
mi_insert_notify_hooks (void)
@@ -290,6 +297,17 @@ mi_execute_command_wrapper (char *cmd)
mi_execute_command (cmd, stdin == instream);
}
+/* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */
+
+static void
+mi_execute_command_input_handler (char *cmd)
+{
+ mi_execute_command_wrapper (cmd);
+
+ fputs_unfiltered ("(gdb) \n", raw_stdout);
+ gdb_flush (raw_stdout);
+}
+
static void
mi1_command_loop (void)
{
@@ -312,11 +330,13 @@ static void
mi_command_loop (int mi_version)
{
/* Turn off 8 bit strings in quoted output. Any character with the
- high bit set is printed using C's octal format. */
+ high bit set is printed using C's octal format. */
sevenbit_strings = 1;
- /* Tell the world that we're alive */
+
+ /* Tell the world that we're alive. */
fputs_unfiltered ("(gdb) \n", raw_stdout);
gdb_flush (raw_stdout);
+
start_event_loop ();
}
@@ -420,11 +440,11 @@ mi_on_normal_stop (struct bpstats *bs, int print_frame)
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. */
+ /* 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;
@@ -483,15 +503,17 @@ mi_about_to_proceed (void)
/* When non-zero, no MI notifications will be emitted in
response to breakpoint change observers. */
+
int mi_suppress_breakpoint_notifications = 0;
/* Emit notification about a created breakpoint. */
+
static void
mi_breakpoint_created (struct breakpoint *b)
{
struct mi_interp *mi = top_level_interpreter_data ();
struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
- struct gdb_exception e;
+ volatile struct gdb_exception e;
if (mi_suppress_breakpoint_notifications)
return;
@@ -503,12 +525,12 @@ mi_breakpoint_created (struct breakpoint *b)
fprintf_unfiltered (mi->event_channel,
"breakpoint-created");
/* 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 the calling the breakpoint_created notifications.
- So, we use ui_out_redirect. */
+ 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);
@@ -518,6 +540,7 @@ mi_breakpoint_created (struct breakpoint *b)
}
/* Emit notification about deleted breakpoint. */
+
static void
mi_breakpoint_deleted (struct breakpoint *b)
{
@@ -538,12 +561,13 @@ mi_breakpoint_deleted (struct breakpoint *b)
}
/* Emit notification about modified breakpoint. */
+
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 ());
- struct gdb_exception e;
+ volatile struct gdb_exception e;
if (mi_suppress_breakpoint_notifications)
return;
@@ -555,12 +579,12 @@ mi_breakpoint_modified (struct breakpoint *b)
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 the calling the breakpoint_created notifications.
- So, we use ui_out_redirect. */
+ 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);
@@ -569,7 +593,6 @@ mi_breakpoint_modified (struct breakpoint *b)
gdb_flush (mi->event_channel);
}
-
static int
mi_output_running_pid (struct thread_info *info, void *arg)
{
@@ -732,20 +755,69 @@ mi_ui_out (struct interp *interp)
return 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). */
+
+static int
+mi_set_logging (struct interp *interp, int start_log,
+ struct ui_file *out, struct ui_file *logfile)
+{
+ struct mi_interp *mi = interp_data (interp);
+
+ if (!mi)
+ return 0;
+
+ if (start_log)
+ {
+ /* The tee created already is based on gdb_stdout, which for MI
+ is a console and so we end up in an infinite loop of console
+ writing to ui_file writing to console etc. So discard the
+ existing tee (it hasn't been used yet, and MI won't ever use
+ it), and create one based on raw_stdout instead. */
+ if (logfile)
+ {
+ ui_file_delete (out);
+ out = tee_file_new (raw_stdout, 0, logfile, 0);
+ }
+
+ saved_raw_stdout = raw_stdout;
+ raw_stdout = out;
+ }
+ else
+ {
+ raw_stdout = saved_raw_stdout;
+ 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);
+
+ return 1;
+}
+
extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
void
_initialize_mi_interp (void)
{
static const struct interp_procs procs =
- {
- mi_interpreter_init, /* init_proc */
- mi_interpreter_resume, /* resume_proc */
- mi_interpreter_suspend, /* suspend_proc */
- mi_interpreter_exec, /* exec_proc */
- mi_interpreter_prompt_p, /* prompt_proc_p */
- mi_ui_out /* ui_out_proc */
- };
+ {
+ mi_interpreter_init, /* init_proc */
+ mi_interpreter_resume, /* resume_proc */
+ mi_interpreter_suspend, /* suspend_proc */
+ mi_interpreter_exec, /* exec_proc */
+ mi_interpreter_prompt_p, /* prompt_proc_p */
+ mi_ui_out, /* ui_out_proc */
+ mi_set_logging /* set_logging_proc */
+ };
/* The various interpreter levels. */
interp_add (interp_new (INTERP_MI1, &procs));
« no previous file with comments | « gdb/mi/mi-getopt.c ('k') | gdb/mi/mi-main.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698