[RFC 2/2] gdb/mi: add new async events =target-connected and =target-disconnected

Jan Vrany jan.vrany@fit.cvut.cz
Sun Oct 14 12:56:00 GMT 2018


Whenever a target is connected or disconnected, emit new asynchronous
event =target-connected and =target-disconnected. Events report
both short name and full name of connected or disconnected target.
In addition, =target-connected report a set of target features.

This allows frontends to keep track of current target and its features
regardless whether target is changed explicitly by MI -target-select
command, CLI target command or implicitly by  native target auto-connect.

gdb/Changelog:

	* mi/mi-interp.c (mi_target_connected): New function.
	(mi_target_disconnected): New function.
	(_initialize_mi_interp): Register new observers.

gdb/doc/Changelog

	* gdb.texinfo (GDB/MI Async Records): Document new async
	records =target-connected and target-disconnected.
---
 gdb/ChangeLog       | 12 +++++--
 gdb/doc/ChangeLog   |  5 +++
 gdb/doc/gdb.texinfo |  7 +++++
 gdb/mi/mi-interp.c  | 77 +++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 96 insertions(+), 5 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d13ce2097d..cd0ae9443e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,10 @@
-2018-07-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
+2018-10-13  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* mi/mi-interp.c (mi_target_connected): New function.
+	(mi_target_disconnected): New function.
+	(_initialize_mi_interp): Register new observers.
+
+2018-10-13  Jan Vrany  <jan.vrany@fit.cvut.cz>
 
 	* observable.h: Define new observables target_connected and
 	target_disconnected.
@@ -8021,7 +8027,7 @@
 	of the new expedite_regs parameter to init_target_desc.
 
 2018-05-10  Omair Javaid  <omair.javaid@linaro.org>
-    
+
 	PR gdb/23127
 	* aarch64-linux-tdep.c (aarch64_linux_init_abi): Add call to
 	set_gdbarch_significant_addr_bit.
@@ -11228,7 +11234,7 @@
 2018-04-02  Weimin Pan  <weimin.pan@oracle.com>
 
 	PR gdb/16959
-	* cp-valprint.c: (cp_print_static_field) Fix infinite recursion when 
+	* cp-valprint.c: (cp_print_static_field) Fix infinite recursion when
 	printing static type.
 
 2018-04-01  Tom Tromey  <tom@tromey.com>
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 0cab170456..cefc4c439b 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2018-10-13  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* gdb.texinfo (GDB/MI Async Records): Document new async
+	records =target-connected and target-disconnected.
+
 2018-10-09  Tom Tromey  <tom@tromey.com>
 
 	* python.texi (Inferiors In Python): Link to "Frames In Python",
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index b0dc3bf67c..4579a00967 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -27902,6 +27902,13 @@ written in an inferior.  The @var{id} is the identifier of the
 thread group corresponding to the affected inferior.  The optional
 @code{type="code"} part is reported if the memory written to holds
 executable code.
+
+@item =target-connected,type="@var{type}",name="@var{name}",features=[@var{features},...]
+@itemx =target-disconnected,type="@var{type}",name="@var{name}"
+Report that a target has been connected or disconnected. The @var{type} is
+the internal target type, the @var{name} is a name of the target to be
+used for printing. The @var{features} lists connected target's features.
+See @ref{GDB/MI Support Commands} for existing target features.
 @end table
 
 @node GDB/MI Breakpoint Information
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index e055dce59e..6429184a2d 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -38,6 +38,7 @@
 #include "cli-out.h"
 #include "thread-fsm.h"
 #include "cli/cli-interp.h"
+#include "target.h"
 
 /* These are the interpreter setup, etc. functions for the MI
    interpreter.  */
@@ -85,6 +86,9 @@ static void mi_command_param_changed (const char *param, const char *value);
 static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
 			       ssize_t len, const bfd_byte *myaddr);
 static void mi_on_sync_execution_done (void);
+static void mi_target_connected (struct target_ops *target);
+static void mi_target_disconnected (struct target_ops *target);
+
 
 static int report_initial_inferior (struct inferior *inf, void *closure);
 
@@ -658,7 +662,7 @@ mi_on_normal_stop_1 (struct bpstats *bs, int print_frame)
       if (core != -1)
 	mi_uiout->field_int ("core", core);
     }
-  
+
   fputs_unfiltered ("*stopped", mi->raw_stdout);
   mi_out_put (mi_uiout, mi->raw_stdout);
   mi_out_rewind (mi_uiout);
@@ -1271,6 +1275,73 @@ mi_user_selected_context_changed (user_selected_what selection)
     }
 }
 
+static void
+mi_target_connected (struct target_ops *target)
+{
+  SWITCH_THRU_ALL_UIS ()
+    {
+      struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
+      struct ui_out *mi_uiout;
+
+      if (mi == NULL)
+        continue;
+
+      mi_uiout = top_level_interpreter ()->interp_ui_out ();
+
+      target_terminal::scoped_restore_terminal_state term_state;
+      target_terminal::ours_for_output ();
+
+      fprintf_unfiltered (mi->event_channel,"target-connected");
+
+      mi_uiout->redirect (mi->event_channel);
+
+      mi_uiout->field_string ("type", target->shortname());
+      mi_uiout->field_string ("name", target->longname());
+
+      {
+        ui_out_emit_list list_emitter (mi_uiout, "features");
+
+        if (mi_async_p ())
+          mi_uiout->field_string (NULL, "async");
+        if (target_can_execute_reverse)
+          mi_uiout->field_string (NULL, "reverse");
+      }
+
+      mi_uiout->redirect (NULL);
+
+      gdb_flush (mi->event_channel);
+    }
+}
+
+static void
+mi_target_disconnected (struct target_ops *target)
+{
+  SWITCH_THRU_ALL_UIS ()
+    {
+      struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
+      struct ui_out *mi_uiout;
+
+      if (mi == NULL)
+        continue;
+
+      mi_uiout = top_level_interpreter ()->interp_ui_out ();
+
+      target_terminal::scoped_restore_terminal_state term_state;
+      target_terminal::ours_for_output ();
+
+      fprintf_unfiltered (mi->event_channel, "target-disonnected");
+
+      mi_uiout->redirect (mi->event_channel);
+
+      mi_uiout->field_string ("type", target->shortname());
+      mi_uiout->field_string ("name", target->longname());
+
+      mi_uiout->redirect (NULL);
+
+      gdb_flush (mi->event_channel);
+    }
+}
+
 static int
 report_initial_inferior (struct inferior *inf, void *closure)
 {
@@ -1319,7 +1390,7 @@ mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)
       mi->raw_stdout = mi->saved_raw_stdout;
       mi->saved_raw_stdout = NULL;
     }
-  
+
   mi->out->set_raw (mi->raw_stdout);
   mi->err->set_raw (mi->raw_stdout);
   mi->log->set_raw (mi->raw_stdout);
@@ -1373,4 +1444,6 @@ _initialize_mi_interp (void)
   gdb::observers::sync_execution_done.attach (mi_on_sync_execution_done);
   gdb::observers::user_selected_context_changed.attach
     (mi_user_selected_context_changed);
+  gdb::observers::target_connected.attach (mi_target_connected);
+  gdb::observers::target_disconnected.attach (mi_target_disconnected);
 }
-- 
2.19.1



More information about the Gdb-patches mailing list