This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] 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.

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]