summaryrefslogtreecommitdiff
path: root/gdb/top.c
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@ericsson.com>2016-07-25 11:01:54 -0400
committerSimon Marchi <simon.marchi@ericsson.com>2016-07-25 11:01:54 -0400
commit8194e927cc66e8cceb9890240ad75363b3ca6d53 (patch)
tree78d5de04cfbaff40c14511416e12885a4295527f /gdb/top.c
parent0e1a6a5169023ee0c19de2c9160b469e43634b21 (diff)
downloadbinutils-gdb-8194e927cc66e8cceb9890240ad75363b3ca6d53.tar.gz
Handle correctly passing a bad interpreter name to new-ui
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. Changes in v2: - Use with_test_prefix to namespace test procedures - Give an explicit stable test name - Add a "bad terminal path" test - Remove useless runto_main - Add missing intro comments I did not factor out the pty spawn, as there is some magic involved I don't quite understand. But it wouldn't bring that much anyway. 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_args): New procedure.
Diffstat (limited to 'gdb/top.c')
-rw-r--r--gdb/top.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/gdb/top.c b/gdb/top.c
index d5666778733..36c300e8ce1 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -324,6 +324,24 @@ delete_ui (struct ui *todel)
free_ui (ui);
}
+/* Cleanup that deletes a UI. */
+
+static void
+delete_ui_cleanup (void *void_ui)
+{
+ struct ui *ui = (struct ui *) void_ui;
+
+ delete_ui (ui);
+}
+
+/* See top.h. */
+
+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 +371,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 +386,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 +399,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");
}