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] Don't send queries to the MI interpreter


We have a little problem in Eclipse CDT related to queries being sent on
the MI channel.  GDB sends queries on the MI stream and waits for an
answer (y or n), but since CDT will never answer, it causes a deadlock.

Note that this is only a problem when using MI as a side-channel
(new-ui) on a dedicated tty.  It doesn't happen if GDB's input/output
streams are pipes, for example.  In that case, the queries are
auto-answered as they should.

The situation can be triggered by modifying a variable value while
replaying.  Roughly, the steps are:

  - Start recording (record-full)
  - Step forward a bit
  - Step backwards a bit
  - Change a variable using the Variables view in the UI

Changing the variable uses the -var-assign command.  Modifying the
memory while replaying causes the following query to be sent:

  ~"Because GDB is in replay mode, writing to memory will make the execution \
    log unusable from this point onward.  Write memory at address \
    0x7fffffffdabc?(y or n) "

In the past, the query would get auto-answered because GDB would
consider the input as non-interactive.  The criterion for this is
whether the input stream is a tty (ISATTY).  Now that we create the MI
channel with new-ui and pass it a tty (/dev/pts/X), GDB considers the
input as interactive, so the query is not auto answered.

I have a hard time defining what should be the right criteria for when
we should or shouldn't query.  I think we'll have to take into account
what is the originating interpreter, CLI or MI.

A special case is when we receive CLI through MI (either
-interpreter-exec console or typing directly CLI commands): it's
possible that it's a human at the other end, typing in a field in the
front-end, which then forwards the commands to GDB.  In that case, we
could want to query, since the user is there to respond.  However, it
would be very fragile, as the front-end should not send any command in
the mean time, not reply anything else than "y" or "n" and not wrap the
user response in -interpreter-exec...  Currently, we never query as a
result of CLI-in-MI commands anyway, because deprecated_query_hook is
set.  So I think we should just keep this behaviour: queries resulting
from CLI-in-MI commands get auto-answered.

Conveniently, when using CLI in MI, the current_interpreter stays MI
(unlike when using MI in CLI), so it allows to differentiate a CLI
command from a CLI-in-MI command easily.

So the criteria I came up with in order to decide whether we should
not auto answer are: the input should be interactive (ISATTY is true)
_and_  the originating interpreter should support queries.

In practice, it means the only time we are going to query is when it's
a CLI command typed in a CLI UI coming from a tty.

Currently, CLI supports queries and MI doesn't.  However, we could
imagine that some day GDB could send the query to the front-end through
MI, so that it displays a nice popup.  That's a whole separate topic
though, since it would require changing the MI paradigm a bit.

gdb/ChangeLog:

	* interps.h (interp::supports_queries): New.
	* cli-interp.h (cli_interp_base::supports_queries): New.
	* cli-interp.c (cli_interp_base::supports_queries): New.
	* utils.c (defaulted_query): Don't query if the current
	interpreter doesn't support queries.
---
 gdb/cli/cli-interp.c | 6 ++++++
 gdb/cli/cli-interp.h | 1 +
 gdb/interps.h        | 4 ++++
 gdb/utils.c          | 5 ++++-
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index 8712c75f39..709bfbbce3 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -356,6 +356,12 @@ cli_interp_base::supports_command_editing ()
   return true;
 }
 
+bool
+cli_interp_base::supports_queries ()
+{
+  return true;
+}
+
 static struct gdb_exception
 safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
 {
diff --git a/gdb/cli/cli-interp.h b/gdb/cli/cli-interp.h
index de9da83347..f1e966fe77 100644
--- a/gdb/cli/cli-interp.h
+++ b/gdb/cli/cli-interp.h
@@ -31,6 +31,7 @@ public:
   void set_logging (ui_file_up logfile, bool logging_redirect) override;
   void pre_command_loop () override;
   bool supports_command_editing () override;
+  bool supports_queries () override;
 };
 
 /* Make the output ui_file to use when logging is enabled.
diff --git a/gdb/interps.h b/gdb/interps.h
index 1b9580c118..d328163027 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -76,6 +76,10 @@ public:
   virtual bool supports_command_editing ()
   { return false; }
 
+  /* Returns true if this interpreter supports queries.  */
+  virtual bool supports_queries ()
+  { return false; }
+
   /* This is the name in "-i=" and "set interpreter".  */
   const char *name;
 
diff --git a/gdb/utils.c b/gdb/utils.c
index 3dc2f03d61..ba1db8a45b 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -1170,12 +1170,15 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
   if (!confirm || server_command)
     return def_value;
 
+  struct interp *interp = current_interpreter ();
+
   /* If input isn't coming from the user directly, just say what
      question we're asking, and then answer the default automatically.  This
      way, important error messages don't get lost when talking to GDB
      over a pipe.  */
   if (current_ui->instream != current_ui->stdin_stream
-      || !input_interactive_p (current_ui))
+      || !input_interactive_p (current_ui)
+      || !interp->supports_queries ())
     {
       old_chain = make_cleanup_restore_target_terminal ();
 
-- 
2.11.0


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