This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] Handle correctly passing a bad interpreter name to new-ui
- From: Simon Marchi <simon dot marchi at ericsson dot com>
- To: <gdb-patches at sourceware dot org>
- Cc: Simon Marchi <simon dot marchi at ericsson dot com>
- Date: Wed, 13 Jul 2016 10:13:44 -0400
- Subject: [PATCH] Handle correctly passing a bad interpreter name to new-ui
- Authentication-results: sourceware.org; auth=none
When a bad interpreter name is passed to new-ui, such as:
(gdb) new-ui bloop /dev/pts/10
A partially created UI is left in the UI list, with interp set to NULL.
Trying to do anything that will print on this UI (such as "start") will
cause a segmentation fault.
gdb/ChangeLog:
* top.h (make_delete_ui_cleanup): New declaration.
* top.c (delete_ui_cleanup): New function.
(make_delete_ui_cleanup): New function.
(new_ui_command): Create restore_ui cleanup earlier, create a
delete_ui cleanup and discard it on success.
gdb/testsuite/ChangeLog:
* gdb.base/new-ui.exp (do_test_invalid_interpreter): New
procedure.
---
gdb/testsuite/gdb.base/new-ui.exp | 23 +++++++++++++++++++++++
gdb/top.c | 34 +++++++++++++++++++++++++---------
gdb/top.h | 3 +++
3 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/gdb/testsuite/gdb.base/new-ui.exp b/gdb/testsuite/gdb.base/new-ui.exp
index f3f66db..ddff8c4 100644
--- a/gdb/testsuite/gdb.base/new-ui.exp
+++ b/gdb/testsuite/gdb.base/new-ui.exp
@@ -143,4 +143,27 @@ proc do_test {} {
}
}
+proc do_test_invalid_interpreter {} {
+ global testfile
+
+ clean_restart $testfile
+
+ spawn -pty
+ set extra_tty_name $spawn_out(slave,name)
+
+ if ![runto_main] {
+ untested "could not run to main"
+ return -1
+ }
+
+ # Test that asking for a wrong interpreter is properly reported.
+ gdb_test "new-ui bloop $extra_tty_name" "Interpreter `bloop' unrecognized"
+
+ # Test that we can continue normally (this used to crash).
+ if ![runto_main] {
+ fail "could not run to main"
+ }
+}
+
do_test
+do_test_invalid_interpreter
diff --git a/gdb/top.c b/gdb/top.c
index 3174f3c..cf0b544 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -324,6 +324,20 @@ delete_ui (struct ui *todel)
free_ui (ui);
}
+static void
+delete_ui_cleanup (void *void_ui)
+{
+ struct ui *ui = (struct ui *) void_ui;
+
+ delete_ui (ui);
+}
+
+struct cleanup *
+make_delete_ui_cleanup (struct ui *ui)
+{
+ return make_cleanup (delete_ui_cleanup, ui);
+}
+
/* Open file named NAME for read/write, making sure not to make it the
controlling terminal. */
@@ -353,13 +367,13 @@ new_ui_command (char *args, int from_tty)
char **argv;
const char *interpreter_name;
const char *tty_name;
- struct cleanup *back_to;
- struct cleanup *streams_chain;
+ struct cleanup *success_chain;
+ struct cleanup *failure_chain;
dont_repeat ();
argv = gdb_buildargv (args);
- back_to = make_cleanup_freeargv (argv);
+ success_chain = make_cleanup_freeargv (argv);
argc = countargv (argv);
if (argc < 2)
@@ -368,7 +382,9 @@ new_ui_command (char *args, int from_tty)
interpreter_name = argv[0];
tty_name = argv[1];
- streams_chain = make_cleanup (null_cleanup, NULL);
+ make_cleanup (restore_ui_cleanup, current_ui);
+
+ failure_chain = make_cleanup (null_cleanup, NULL);
/* Open specified terminal, once for each of
stdin/stdout/stderr. */
@@ -379,20 +395,20 @@ new_ui_command (char *args, int from_tty)
}
ui = new_ui (stream[0], stream[1], stream[2]);
-
- discard_cleanups (streams_chain);
+ make_cleanup (delete_ui_cleanup, ui);
ui->async = 1;
- make_cleanup (restore_ui_cleanup, current_ui);
current_ui = ui;
set_top_level_interpreter (interpreter_name);
interp_pre_command_loop (top_level_interpreter ());
- /* This restores the previous UI. */
- do_cleanups (back_to);
+ discard_cleanups (failure_chain);
+
+ /* This restores the previous UI and frees argv. */
+ do_cleanups (success_chain);
printf_unfiltered ("New UI allocated\n");
}
diff --git a/gdb/top.h b/gdb/top.h
index 64f7211..bdc3529 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -185,6 +185,9 @@ extern void switch_thru_all_uis_next (struct switch_thru_all_uis *state);
extern struct ui *new_ui (FILE *instream, FILE *outstream, FILE *errstream);
extern void delete_ui (struct ui *todel);
+/* Cleanup that deletes a UI. */
+extern struct cleanup *make_delete_ui_cleanup (struct ui *ui);
+
/* Cleanup that restores the current UI. */
extern void restore_ui_cleanup (void *data);
--
2.9.0