From 4801a9a3568ed8ffcb4b2fa03d086193bc9ba647 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 12 Sep 2011 21:25:22 +0000 Subject: [PATCH] gdb/ 2011-09-12 Pedro Alves Matt Rice PR gdb/13175 * interps.c (struct interp) : Delete field. (interp_new): Remove the data and uiout parameters and adjust. (interp_set): Only set the current_uiout from the interpreter's uiout after initializing the interpreter. Adjust call to init_proc. (interp_ui_out): Adjust to call procs->ui_out_proc. (interp_data, interp_name): New. * interps.h (interp_init_ftype): Add `self' parameter. (interp_ui_out_ftype): New typedef. (struct interp_procs) : New method pointer. (interp_new): Remove the data and uiout parameters. (interp_data, interp_name): Declare. * tui/tui-interp.c (tui_init): Adjust prototype. (tui_ui_out): New. (_initialize_tui_interp): Install tui_ui_out. Don't instanciate tui_out here. Adjust call to interp_new. * tui/tui-io.c (tui_initialize_io): Don't set current_uiout here. * cli/cli-interp.c (cli_interpreter_init): Adjust prototype. (cli_ui_out): New. (_initialize_cli_interp): Install it. Adjust call to interp_new. * mi/mi-common.h (struct mi_interp) : New field. * mi/mi-interp.c (mi_interpreter_init): Adjust prototype. Initialize mi->uiout depending on the mi_version as extracted from the interpreter's name. (mi_ui_out): New. (_initialize_mi_interp): Install mi_ui_out. Adjust calls to interp_new. Don't allocate the ui_out's of the interpreters here. gdb/testsuite/ 2011-09-12 Matt Rice Pedro Alves PR gdb/13175 * gdb.base/interp.exp: New tests. * gdb.base/interp.c: New file. --- gdb/ChangeLog | 33 ++++++++++++++++++++ gdb/cli/cli-interp.c | 12 +++++-- gdb/interps.c | 38 +++++++++++++--------- gdb/interps.h | 16 +++++++--- gdb/mi/mi-common.h | 3 ++ gdb/mi/mi-interp.c | 42 +++++++++++++++++++------ gdb/testsuite/ChangeLog | 8 +++++ gdb/testsuite/gdb.base/interp.c | 24 ++++++++++++++ gdb/testsuite/gdb.base/interp.exp | 52 ++++++++++++++++++++++++++++++- gdb/tui/tui-interp.c | 17 ++++++++-- gdb/tui/tui-io.c | 2 +- 11 files changed, 212 insertions(+), 35 deletions(-) create mode 100644 gdb/testsuite/gdb.base/interp.c diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8854ae21d6..b49d76c507 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,36 @@ +2011-09-12 Pedro Alves + Matt Rice + + PR gdb/13175 + + * interps.c (struct interp) : Delete field. + (interp_new): Remove the data and uiout parameters and adjust. + (interp_set): Only set the current_uiout from the interpreter's + uiout after initializing the interpreter. Adjust call to + init_proc. + (interp_ui_out): Adjust to call procs->ui_out_proc. + (interp_data, interp_name): New. + * interps.h (interp_init_ftype): Add `self' parameter. + (interp_ui_out_ftype): New typedef. + (struct interp_procs) : New method pointer. + (interp_new): Remove the data and uiout parameters. + (interp_data, interp_name): Declare. + * tui/tui-interp.c (tui_init): Adjust prototype. + (tui_ui_out): New. + (_initialize_tui_interp): Install tui_ui_out. Don't instanciate + tui_out here. Adjust call to interp_new. + * tui/tui-io.c (tui_initialize_io): Don't set current_uiout here. + * cli/cli-interp.c (cli_interpreter_init): Adjust prototype. + (cli_ui_out): New. + (_initialize_cli_interp): Install it. Adjust call to interp_new. + * mi/mi-common.h (struct mi_interp) : New field. + * mi/mi-interp.c (mi_interpreter_init): Adjust prototype. + Initialize mi->uiout depending on the mi_version as extracted from + the interpreter's name. + (mi_ui_out): New. + (_initialize_mi_interp): Install mi_ui_out. Adjust calls to + interp_new. Don't allocate the ui_out's of the interpreters here. + 2011-09-12 Aleksandar Ristovski * solib.c (solib_used): New function. diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c index 32848495f0..6e02934231 100644 --- a/gdb/cli/cli-interp.c +++ b/gdb/cli/cli-interp.c @@ -40,7 +40,7 @@ static struct gdb_exception safe_execute_command (struct ui_out *uiout, /* These implement the cli out interpreter: */ static void * -cli_interpreter_init (int top_level) +cli_interpreter_init (struct interp *self, int top_level) { return NULL; } @@ -135,6 +135,11 @@ safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty) return e; } +static struct ui_out * +cli_ui_out (struct interp *self) +{ + return cli_uiout; +} /* Standard gdb initialization hook. */ extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */ @@ -147,13 +152,14 @@ _initialize_cli_interp (void) cli_interpreter_resume, /* resume_proc */ cli_interpreter_suspend, /* suspend_proc */ cli_interpreter_exec, /* exec_proc */ - cli_interpreter_display_prompt_p /* prompt_proc_p */ + cli_interpreter_display_prompt_p, /* prompt_proc_p */ + cli_ui_out /* ui_out_proc */ }; struct interp *cli_interp; /* Create a default uiout builder for the CLI. */ cli_uiout = cli_out_new (gdb_stdout); - cli_interp = interp_new (INTERP_CONSOLE, NULL, cli_uiout, &procs); + cli_interp = interp_new (INTERP_CONSOLE, &procs); interp_add (cli_interp); } diff --git a/gdb/interps.c b/gdb/interps.c index ff8daf8f7b..4878a6ab8d 100644 --- a/gdb/interps.c +++ b/gdb/interps.c @@ -67,11 +67,6 @@ struct interp /* Has the init_proc been run? */ int inited; - /* This is the ui_out used to collect results for this interpreter. - It can be a formatter for stdout, as is the case for the console - & mi outputs, or it might be a result formatter. */ - struct ui_out *interpreter_out; - const struct interp_procs *procs; int quiet_p; }; @@ -97,16 +92,14 @@ static int interpreter_initialized = 0; fills the fields from the inputs, and returns a pointer to the interpreter. */ struct interp * -interp_new (const char *name, void *data, struct ui_out *uiout, - const struct interp_procs *procs) +interp_new (const char *name, const struct interp_procs *procs) { struct interp *new_interp; new_interp = XMALLOC (struct interp); new_interp->name = xstrdup (name); - new_interp->data = data; - new_interp->interpreter_out = uiout; + new_interp->data = NULL; new_interp->quiet_p = 0; new_interp->procs = procs; new_interp->inited = 0; @@ -184,19 +177,20 @@ interp_set (struct interp *interp, int top_level) interpreter_p = xstrdup (current_interpreter->name); } - current_uiout = interp->interpreter_out; - /* Run the init proc. If it fails, try to restore the old interp. */ if (!interp->inited) { if (interp->procs->init_proc != NULL) { - interp->data = interp->procs->init_proc (top_level); + interp->data = interp->procs->init_proc (interp, top_level); } interp->inited = 1; } + /* Do this only after the interpreter is initialized. */ + current_uiout = interp->procs->ui_out_proc (interp); + /* Clear out any installed interpreter hooks/event handlers. */ clear_interpreter_hooks (); @@ -254,9 +248,25 @@ struct ui_out * interp_ui_out (struct interp *interp) { if (interp != NULL) - return interp->interpreter_out; + return interp->procs->ui_out_proc (interp); + + return current_interpreter->procs->ui_out_proc (current_interpreter); +} + +/* Returns the interpreter's cookie. */ - return current_interpreter->interpreter_out; +void * +interp_data (struct interp *interp) +{ + return interp->data; +} + +/* Returns the interpreter's name. */ + +const char * +interp_name (struct interp *interp) +{ + return interp->name; } /* Returns true if the current interp is the passed in name. */ diff --git a/gdb/interps.h b/gdb/interps.h index a000ef787e..a63c2f501e 100644 --- a/gdb/interps.h +++ b/gdb/interps.h @@ -36,13 +36,14 @@ extern struct gdb_exception interp_exec (struct interp *interp, const char *command); extern int interp_quiet_p (struct interp *interp); -typedef void *(interp_init_ftype) (int top_level); +typedef void *(interp_init_ftype) (struct interp *self, int top_level); typedef int (interp_resume_ftype) (void *data); typedef int (interp_suspend_ftype) (void *data); typedef int (interp_prompt_p_ftype) (void *data); typedef struct gdb_exception (interp_exec_ftype) (void *data, const char *command); typedef void (interp_command_loop_ftype) (void *data); +typedef struct ui_out *(interp_ui_out_ftype) (struct interp *self); struct interp_procs { @@ -51,16 +52,23 @@ struct interp_procs interp_suspend_ftype *suspend_proc; interp_exec_ftype *exec_proc; interp_prompt_p_ftype *prompt_proc_p; + + /* Returns the ui_out currently used to collect results for this + interpreter. It can be a formatter for stdout, as is the case + for the console & mi outputs, or it might be a result + formatter. */ + interp_ui_out_ftype *ui_out_proc; + interp_command_loop_ftype *command_loop_proc; }; -extern struct interp *interp_new (const char *name, void *data, - struct ui_out *uiout, - const struct interp_procs *procs); +extern struct interp *interp_new (const char *name, const struct interp_procs *procs); extern void interp_add (struct interp *interp); extern int interp_set (struct interp *interp, int top_level); extern struct interp *interp_lookup (const char *name); extern struct ui_out *interp_ui_out (struct interp *interp); +extern void *interp_data (struct interp *interp); +extern const char *interp_name (struct interp *interp); extern int current_interp_named_p (const char *name); extern int current_interp_display_prompt_p (void); diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h index e3aab7d785..dc5fc8e170 100644 --- a/gdb/mi/mi-common.h +++ b/gdb/mi/mi-common.h @@ -52,6 +52,9 @@ struct mi_interp struct ui_file *targ; struct ui_file *event_channel; + /* MI's builder. */ + struct ui_out *uiout; + /* This is the interpreter for the mi... */ struct interp *mi2_interp; struct interp *mi1_interp; diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index ac8c171b62..805e3f8bcf 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -72,9 +72,11 @@ static void mi_breakpoint_modified (struct breakpoint *b); static int report_initial_inferior (struct inferior *inf, void *closure); static void * -mi_interpreter_init (int top_level) +mi_interpreter_init (struct interp *interp, int top_level) { struct mi_interp *mi = XMALLOC (struct mi_interp); + 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 @@ -90,6 +92,22 @@ mi_interpreter_init (int top_level) mi->targ = mi_console_file_new (raw_stdout, "@", '"'); mi->event_channel = mi_console_file_new (raw_stdout, "=", 0); + name = interp_name (interp); + /* INTERP_MI selects the most recent released version. "mi2" was + released as part of GDB 6.0. */ + if (strcmp (name, INTERP_MI) == 0) + mi_version = 2; + else if (strcmp (name, INTERP_MI1) == 0) + mi_version = 1; + else if (strcmp (name, INTERP_MI2) == 0) + mi_version = 2; + else if (strcmp (name, INTERP_MI3) == 0) + mi_version = 3; + else + gdb_assert_not_reached ("unhandled MI version"); + + mi->uiout = mi_out_new (mi_version); + if (top_level) { observer_attach_new_thread (mi_new_thread); @@ -701,6 +719,14 @@ report_initial_inferior (struct inferior *inf, void *closure) return 0; } +static struct ui_out * +mi_ui_out (struct interp *interp) +{ + struct mi_interp *mi = interp_data (interp); + + return mi->uiout; +} + extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */ void @@ -712,15 +738,13 @@ _initialize_mi_interp (void) mi_interpreter_resume, /* resume_proc */ mi_interpreter_suspend, /* suspend_proc */ mi_interpreter_exec, /* exec_proc */ - mi_interpreter_prompt_p /* prompt_proc_p */ + mi_interpreter_prompt_p, /* prompt_proc_p */ + mi_ui_out /* ui_out_proc */ }; /* The various interpreter levels. */ - interp_add (interp_new (INTERP_MI1, NULL, mi_out_new (1), &procs)); - interp_add (interp_new (INTERP_MI2, NULL, mi_out_new (2), &procs)); - interp_add (interp_new (INTERP_MI3, NULL, mi_out_new (3), &procs)); - - /* "mi" selects the most recent released version. "mi2" was - released as part of GDB 6.0. */ - interp_add (interp_new (INTERP_MI, NULL, mi_out_new (2), &procs)); + interp_add (interp_new (INTERP_MI1, &procs)); + interp_add (interp_new (INTERP_MI2, &procs)); + interp_add (interp_new (INTERP_MI3, &procs)); + interp_add (interp_new (INTERP_MI, &procs)); } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index cdd232d3b5..9d85d02332 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2011-09-12 Matt Rice + Pedro Alves + + PR gdb/13175 + + * gdb.base/interp.exp: New tests. + * gdb.base/interp.c: New file. + 2011-09-12 Doug Evans * gdb.dwarf2/clztest.exp: Fix initialization of tests array. diff --git a/gdb/testsuite/gdb.base/interp.c b/gdb/testsuite/gdb.base/interp.c new file mode 100644 index 0000000000..f374f14fb3 --- /dev/null +++ b/gdb/testsuite/gdb.base/interp.c @@ -0,0 +1,24 @@ +/* This test program is part of GDB, the GNU debugger. + + Copyright 2011 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +int +main (int argc, const char **argv) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/interp.exp b/gdb/testsuite/gdb.base/interp.exp index bb11f04c30..6bb2642604 100644 --- a/gdb/testsuite/gdb.base/interp.exp +++ b/gdb/testsuite/gdb.base/interp.exp @@ -20,7 +20,11 @@ if $tracelevel then { strace $tracelevel } -gdb_start +set testfile "interp" + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c {debug}] } { + return -1 +} # Do not use gdb_test for this test, since it has two prompts. set cmd "interpreter-exec mi \"-var-update *\"" @@ -45,4 +49,50 @@ gdb_test_multiple "interpreter-exec mi \"-break-insert --thread a\"" \ } } +set cmd "interpreter-exec mi \"-stack-info-frame\"" +gdb_test_multiple $cmd $cmd { + -re ".error,msg=.No registers\..\r\n$gdb_prompt " { + pass "$cmd" + gdb_expect 1 { + -re "\r\n$gdb_prompt $" { } + } + } +} + +set cmd "interpreter-exec mi1 \"-break-insert main\"" +gdb_test_multiple $cmd $cmd { + -re ".done.bkpt=.number=.\[0-9\]\[^\n\]+\r\n$gdb_prompt " { + pass "$cmd" + gdb_expect 1 { + -re "\r\n$gdb_prompt $" { } + } + } +} + +set cmd "interpreter-exec mi2 \"-break-insert main\"" +gdb_test_multiple $cmd $cmd { + -re ".done.bkpt=.number=.\[0-9\]\[^\n\]+\r\n$gdb_prompt " { + pass "$cmd" + gdb_expect 1 { + -re "\r\n$gdb_prompt $" { } + } + } +} + +set cmd "interpreter-exec mi3 \"-break-insert main\"" +gdb_test_multiple $cmd $cmd { + -re ".done.bkpt=.number=.\[0-9\]\[^\n\]+\r\n$gdb_prompt " { + pass "$cmd" + gdb_expect 1 { + -re "\r\n$gdb_prompt $" { } + } + } +} + +if ![runto_main] then { + fail "run to main" + return -1; +} + +gdb_test "list" ".*\[0-9\].*main \\(int argc.*" "can list sources" gdb_exit diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c index 78b8aca3d0..b25b53b16c 100644 --- a/gdb/tui/tui-interp.c +++ b/gdb/tui/tui-interp.c @@ -52,7 +52,7 @@ static int tui_is_toplevel = 0; /* These implement the TUI interpreter. */ static void * -tui_init (int top_level) +tui_init (struct interp *self, int top_level) { tui_is_toplevel = top_level; @@ -126,6 +126,15 @@ tui_display_prompt_p (void *data) return 1; } +static struct ui_out * +tui_ui_out (struct interp *self) +{ + if (tui_active) + return tui_out; + else + return tui_old_uiout; +} + static struct gdb_exception tui_exec (void *data, const char *command_str) { @@ -144,11 +153,13 @@ _initialize_tui_interp (void) tui_suspend, tui_exec, tui_display_prompt_p, + tui_ui_out, }; + struct interp *tui_interp; /* Create a default uiout builder for the TUI. */ - tui_out = tui_out_new (gdb_stdout); - interp_add (interp_new (INTERP_TUI, NULL, tui_out, &procs)); + tui_interp = interp_new (INTERP_TUI, &procs); + interp_add (tui_interp); if (interpreter_p && strcmp (interpreter_p, INTERP_TUI) == 0) tui_start_enabled = 1; diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c index 5fcb39540f..1ab28f1049 100644 --- a/gdb/tui/tui-io.c +++ b/gdb/tui/tui-io.c @@ -607,7 +607,7 @@ tui_initialize_io (void) /* Create the default UI. It is not created because we installed a deprecated_init_ui_hook. */ - tui_old_uiout = current_uiout = cli_out_new (gdb_stdout); + tui_old_uiout = cli_out_new (gdb_stdout); #ifdef TUI_USE_PIPE_FOR_READLINE /* Temporary solution for readline writing to stdout: redirect -- 2.34.1