This is the mail archive of the gdb-patches@sources.redhat.com 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]

Re: MI handshaking


On Tue, Jan 04, 2005 at 09:34:23PM -0500, Bob Rossi wrote:
> Here is a patch for the MI handshaking code. In case you forgot, here is
> how it acts from the client's perspective,
>    $ ./gdb -i=mi
>    handshake={stable_protocols={mi2}}
>    ~"GNU gdb 6.3.50.20050105-cvs\n"
>    ~"Copyright 2004 Free Software Foundation, Inc.\n"
>    ~"GDB is free software, covered by the GNU General Public License, and you are\n"
>    ~"welcome to change it and/or distribute copies of it under certain conditions.\n"
>    ~"Type \"show copying\" to see the conditions.\n"
>    ~"There is absolutely no warranty for GDB.  Type \"show warranty\" for details.\n"
>    ~"This GDB was configured as \"i686-pc-linux-gnu\"."
>    ~"\n"
>    ~"Setting up the environment for debugging gdb.\n"
>    &"No symbol table is loaded.  Use the \"file\" command.\n"
>    &"No symbol table is loaded.  Use the \"file\" command.\n"
>    &".gdbinit:8: Error in sourced command file:\n"
>    &"No breakpoint number 0.\n"
>    (gdb) 
>    -handshake-info
>    ^done,stable_protocol="2"
>    (gdb) 
>    
> There are several things to note from this patch,
> 
>    1. The new 'handshake-info' command. It is intended to give all the
>    information that the user selected during the handshaking phase of
>    the MI protocol. So far the only thing worth showing is the protocol
>    version that was selected
> 
>    2. If the GDB being queried was tested with and supports multiple
>    protocols of MI, then GDB will block waiting for a response.
> 
>    3. The handshaking protocol is not in the typical MI syntax. Is this
>    OK?
> 
> Finally, the testsuite will have to change before this commit is OK. Any
> pointers on how to add the 'handshake={stable_protocols={mi2}}' to every
> testcase?

I'm rusty, here's the patch I forgot to add. Also, the contents of the
new file I added (mi-cmd-handshake).

Is there a better place to add the new command? Currently I'm adding a
new file.

2005-01-04  Bob Rossi  <bob@brasko.net>

    * interps.c (struct interp): add field, handshake
    (interp_new): Add parameter, handshake
    (interp_can_handshake,interp_handshake): add function definitions
    * interps.h (interp_handshake_ftype): add typedef
    (interp_new): Add parameter, handshake
    (interp_can_handshake,interp_handshake): add function prototype
    * main.c (captured_main): Add the handshaking code
    * cli/cli-interp.c (_initialize_cli_interp): changed interface to
    interp_new
    * mi/mi-interp.c (stable_mi_versions): add table of stable MI versions
    (mi_handshake): Add function to do handshaking
    (_initialize_mi_interp): changed interface to interp_new
    * tui/tui-interp.c (_initialize_tui_interp): changed interface to
    interp_new
    * Makefile.in (SUBDIR_MI_OBJS,SUBDIR_MI_SRCS): added file mi-cmd-handshake
    (gdb/mi/ dependencies): same as above
    * mi/mi-cmd-file.c (mi_cmd_file_list_exec_source_file): removed unused
    variables in function.
    * mi/mi-cmds.c (mi_cmds): Add command handshake-info
    * mi/mi-cmds.h (mi_cmd-handshake-info): Add extern for new command above
    * mi/mi-cmd-handshake.c: Add new file for new handshake-info command.

mi/mi-cmd-handshake.c
/* MI Command Set - breakpoint and watchpoint commands.
   Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions (a Red Hat company).

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "mi-cmds.h"
#include "mi-getopt.h"
#include "ui-out.h"
#include "mi-out.h"

enum mi_cmd_result
mi_cmd_handshake_info(char *command, char **argv, int argc)
{
  if ( !mi_valid_noargs("mi_cmd_file_list_exec_source_file", argc, argv) )
    error ("mi_cmd_file_list_exec_source_file: Usage: No args");

  ui_out_field_int (uiout, "stable_protocol", mi_version(uiout));

  return MI_CMD_DONE;
}

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.681
diff -w -u -r1.681 Makefile.in
--- Makefile.in	4 Jan 2005 22:59:44 -0000	1.681
+++ Makefile.in	5 Jan 2005 02:35:16 -0000
@@ -169,14 +169,14 @@
 SUBDIR_MI_OBS = \
 	mi-out.o mi-console.o \
 	mi-cmds.o mi-cmd-env.o mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \
-	mi-cmd-file.o mi-cmd-disas.o mi-symbol-cmds.o \
+	mi-cmd-file.o mi-cmd-handshake.o mi-cmd-disas.o mi-symbol-cmds.o \
 	mi-interp.o \
 	mi-main.o mi-parse.o mi-getopt.o
 SUBDIR_MI_SRCS = \
 	mi/mi-out.c mi/mi-console.c \
 	mi/mi-cmds.c mi/mi-cmd-env.c \
 	mi/mi-cmd-var.c mi/mi-cmd-break.c mi/mi-cmd-stack.c \
-	mi/mi-cmd-file.c mi/mi-cmd-disas.c mi/mi-symbol-cmds.c \
+	mi/mi-cmd-file.c mi/mi-cmd-handshake.c mi/mi-cmd-disas.c mi/mi-symbol-cmds.c \
 	mi/mi-interp.c \
 	mi/mi-main.c mi/mi-parse.c mi/mi-getopt.c
 SUBDIR_MI_DEPS =
@@ -2915,6 +2915,9 @@
 mi-cmd-file.o: $(srcdir)/mi/mi-cmd-file.c $(defs_h) $(mi_cmds_h) \
 	$(mi_getopt_h) $(ui_out_h) $(symtab_h) $(source_h) $(objfiles_h)
 	$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-file.c
+mi-cmd-handshake.o: $(srcdir)/mi/mi-cmd-handshake.c $(defs_h) $(mi_cmds_h) \
+	$(mi_getopt_h) $(ui_out_h) $(mi_out_h)
+	$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-handshake.c
 mi-cmds.o: $(srcdir)/mi/mi-cmds.c $(defs_h) $(top_h) $(mi_cmds_h) \
 	$(gdb_string_h)
 	$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmds.c
Index: interps.c
===================================================================
RCS file: /cvs/src/src/gdb/interps.c,v
retrieving revision 1.8
diff -w -u -r1.8 interps.c
--- interps.c	13 Sep 2004 18:26:30 -0000	1.8
+++ interps.c	5 Jan 2005 02:35:17 -0000
@@ -68,6 +68,8 @@
 
   const struct interp_procs *procs;
   int quiet_p;
+
+  interp_handshake_ftype *handshake;
 };
 
 /* Functions local to this file. */
@@ -90,7 +92,7 @@
    interpreter. */
 struct interp *
 interp_new (const char *name, void *data, struct ui_out *uiout,
-	    const struct interp_procs *procs)
+	    const struct interp_procs *procs, interp_handshake_ftype *handshake)
 {
   struct interp *new_interp;
 
@@ -102,6 +104,7 @@
   new_interp->quiet_p = 0;
   new_interp->procs = procs;
   new_interp->inited = 0;
+  new_interp->handshake = handshake;
 
   return new_interp;
 }
@@ -239,6 +242,22 @@
   return current_interpreter->interpreter_out;
 }
 
+int
+interp_can_handshake (struct interp *interp)
+{
+  if (interp != NULL)
+    if (interp->handshake)
+      return 1;
+
+  return 0;
+}
+
+struct interp *
+interp_handshake (struct interp *interp) 
+{
+    return interp_lookup (interp->handshake (gdb_stdout, gdb_stdin));
+}
+
 /* Returns true if the current interp is the passed in name. */
 int
 current_interp_named_p (const char *interp_name)
Index: interps.h
===================================================================
RCS file: /cvs/src/src/gdb/interps.h,v
retrieving revision 1.6
diff -w -u -r1.6 interps.h
--- interps.h	18 Feb 2004 19:01:36 -0000	1.6
+++ interps.h	5 Jan 2005 02:35:17 -0000
@@ -40,6 +40,7 @@
 typedef int (interp_prompt_p_ftype) (void *data);
 typedef int (interp_exec_ftype) (void *data, const char *command);
 typedef void (interp_command_loop_ftype) (void *data);
+typedef const char *(interp_handshake_ftype) (struct ui_file *gdb_stdout, struct ui_file *gdb_stdin);
 
 struct interp_procs
 {
@@ -53,11 +54,14 @@
 
 extern struct interp *interp_new (const char *name, void *data,
 				  struct ui_out *uiout,
-				  const struct interp_procs *procs);
+		const struct interp_procs *procs,
+		interp_handshake_ftype *handshake);
 extern void interp_add (struct interp *interp);
 extern int interp_set (struct interp *interp);
 extern struct interp *interp_lookup (const char *name);
 extern struct ui_out *interp_ui_out (struct interp *interp);
+extern int interp_can_handshake (struct interp *interp);
+extern struct interp *interp_handshake (struct interp *interp);
 
 extern int current_interp_named_p (const char *name);
 extern int current_interp_display_prompt_p (void);
Index: main.c
===================================================================
RCS file: /cvs/src/src/gdb/main.c,v
retrieving revision 1.45
diff -w -u -r1.45 main.c
--- main.c	7 Dec 2004 11:06:03 -0000	1.45
+++ main.c	5 Jan 2005 02:35:18 -0000
@@ -562,8 +562,13 @@
   {
     /* Find it.  */
     struct interp *interp = interp_lookup (interpreter_p);
+
+    if (interp && interp_can_handshake (interp))
+		interp = interp_handshake (interp);
+
     if (interp == NULL)
       error ("Interpreter `%s' unrecognized", interpreter_p);
+
     /* Install it.  */
     if (!interp_set (interp))
       {
Index: cli/cli-interp.c
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-interp.c,v
retrieving revision 1.4
diff -w -u -r1.4 cli-interp.c
--- cli/cli-interp.c	3 Jul 2003 14:49:26 -0000	1.4
+++ cli/cli-interp.c	5 Jan 2005 02:35:18 -0000
@@ -151,7 +151,7 @@
 
   /* Create a default uiout builder for the CLI. */
   cli_uiout = cli_out_new (gdb_stdout);
-  cli_interp = interp_new (INTERP_CONSOLE, NULL, cli_uiout, &procs);
+  cli_interp = interp_new (INTERP_CONSOLE, NULL, cli_uiout, &procs, NULL);
 
   interp_add (cli_interp);
 }
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.229
diff -w -u -r1.229 gdb.texinfo
--- doc/gdb.texinfo	8 Dec 2004 05:28:31 -0000	1.229
+++ doc/gdb.texinfo	5 Jan 2005 02:35:30 -0000
@@ -15022,6 +15022,7 @@
 @menu
 * GDB/MI Command Syntax::
 * GDB/MI Compatibility with CLI::
+* GDB/MI Handshaking Interface::
 * GDB/MI Output Records::
 * GDB/MI Command Description Format::
 * GDB/MI Breakpoint Table Commands::
@@ -15046,11 +15047,53 @@
 @section @sc{gdb/mi} Command Syntax
 
 @menu
+* GDB/MI Handshaking Syntax::
 * GDB/MI Input Syntax::
 * GDB/MI Output Syntax::
 * GDB/MI Simple Examples::
 @end menu
 
+@node GDB/MI Handshaking Syntax
+@subsection @sc{gdb/mi} Handshaking Syntax
+
+@cindex handshaking syntax for @sc{gdb/mi}
+@cindex @sc{gdb/mi}, handshaking syntax
+@table @code
+@item @var{handshake_output} @expansion{}
+@code{"handshake=@{stable_protocols=@{" @var{mi-protocol-list} 
+"@}" @var{nl}}
+
+@item @var{mi-protocol-list} @expansion{}
+@code{ epsilon | @var{mi-protocol} | @var{mi-protocol-list} "," @var{mi-protocol} }
+
+@item @var{mi-protocol} @expansion{}
+@code{ "mi" @var{token} }
+
+@item @var{token} @expansion{}
+"any sequence of digits"
+
+@item @var{nl} @expansion{}
+@code{CR | CR-LF}
+@end table
+
+@noindent
+Notes:
+
+@itemize @bullet
+@item
+If only one stable @sc{mi} protocol is supported by a particular release of 
+@value{GDBN}, then that release is used and the caller does not have to
+do anything.
+
+@item
+If there is more than one stable @sc{mi} protocol supported by a particular 
+release of @value{GDBN}, then the caller has to specify which version of the
+@sc{mi} protocol it wants @value{GDBN} to communicate with.
+
+@end itemize
+
+For more information on handshaking see @ref{GDB/MI Handshaking Interface}.
+
 @node GDB/MI Input Syntax
 @subsection @sc{gdb/mi} Input Syntax
 
@@ -15339,6 +15382,51 @@
 an un-supported hybrid of @sc{gdb/mi} and CLI output.
 
 @c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Handshaking Interface
+@section @sc{gdb/mi} Handshaking Interface
+
+@cindex @sc{gdb/mi}, handshaking interface
+@value{GDBN} is capable of speaking several MI protocols at a time.  This
+interface is intended to help developers understand what version of the MI
+protocol that a particular @value{GDBN} is going to communicate with.
+
+It is possible to start the @sc{gdb/mi} interpreter using @samp{-i=mi@var{n}}, 
+where @var{n} is the MI protocol version (@pxref{Interpreters}).  When invoked 
+with a specific version of the MI interpreter, @value{GDBN} will bypass the 
+handshaking mode and go directly into the version of the MI that it requested.  
+However, if @value{GDBN} is started with the @samp{-i=mi} flag, then this tells 
+@value{GDBN} to go into its handshaking mode with the client to determine the 
+correct MI protocol to communicate with.
+
+@value{GDBN} will output all of the stable versions of the MI protocol that
+it supports.  The term @dfn{stable MI protocol} simply means that the protocol
+was tested when this particular release was made.  Protocols that are no longer
+tested in the @value{GDBN} testsuite will not be considered a stable release.  
+If the caller still wishes to communicate with @value{GDBN} using one of these
+untested protocols, they could simply try to invoke @value{GDBN} with 
+@samp{-i=mi@var{n}}, where @var{n} is version they wish to communicate with.
+
+@value{GDBN} will output all of the stable MI versions that it supports.  
+If a specific version of @value{GDBN} speaks only one stable MI protocol then
+it will begin communicating with that version of the protocol.  The front end
+has no way to change this version.  However, if @value{GDBN} speaks several 
+versions of the MI protocol, then it will output a list of these protocols 
+and the front end then has to choose the version that it wants @value{GDBN}
+to communicate with.
+
+@cindex stable MI protocol
+You could have a @value{GDBN} version that is capable of communicating with
+several versions of the @sc{mi} protocol.  In general, an official release or
+a CVS snapshot will have deprecated @sc{mi} protocols, stable @sc{mi} 
+protocols and development @sc{mi} protocols.  The deprecated @sc{mi} protocols
+are kept around in @value{GDBN} for some period of time and then will 
+eventually get removed.  The stable MI protocols are considered stable
+because they were tested when the particular @value{GDBN} program you have was
+created.  The development @sc{mi} protocols are not ready to be used since
+there is a good change there will be incompatible changes made to it before it
+can become a stable protocol.
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 @node GDB/MI Output Records
 @section @sc{gdb/mi} Output Records
 
Index: mi/mi-cmd-file.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-file.c,v
retrieving revision 1.2
diff -w -u -r1.2 mi-cmd-file.c
--- mi/mi-cmd-file.c	10 Jun 2004 20:05:45 -0000	1.2
+++ mi/mi-cmd-file.c	5 Jan 2005 02:35:30 -0000
@@ -34,8 +34,6 @@
 mi_cmd_file_list_exec_source_file(char *command, char **argv, int argc)
 {
   struct symtab_and_line st;
-  int optind = 0;
-  char *optarg;
   
   if ( !mi_valid_noargs("mi_cmd_file_list_exec_source_file", argc, argv) )
     error ("mi_cmd_file_list_exec_source_file: Usage: No args");
Index: mi/mi-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.c,v
retrieving revision 1.15
diff -w -u -r1.15 mi-cmds.c
--- mi/mi-cmds.c	10 Jun 2004 20:05:45 -0000	1.15
+++ mi/mi-cmds.c	5 Jan 2005 02:35:30 -0000
@@ -91,6 +91,7 @@
   { "gdb-show", { "show", 1 }, NULL, NULL },
   { "gdb-source", { NULL, 0 }, NULL, NULL },
   { "gdb-version", { "show version", 0 }, 0 },
+  { "handshake-info", { NULL, 0 }, 0, mi_cmd_handshake_info},
   { "interpreter-exec", { NULL, 0 }, 0, mi_cmd_interpreter_exec},
   { "kod-info", { NULL, 0 }, NULL, NULL },
   { "kod-list", { NULL, 0 }, NULL, NULL },
Index: mi/mi-cmds.h
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.h,v
retrieving revision 1.14
diff -w -u -r1.14 mi-cmds.h
--- mi/mi-cmds.h	10 Jun 2004 20:05:45 -0000	1.14
+++ mi/mi-cmds.h	5 Jan 2005 02:35:30 -0000
@@ -89,6 +89,7 @@
 extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_file;
 extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_files;
 extern mi_cmd_argv_ftype mi_cmd_gdb_exit;
+extern mi_cmd_argv_ftype mi_cmd_handshake_info;
 extern mi_cmd_argv_ftype mi_cmd_interpreter_exec;
 extern mi_cmd_argv_ftype mi_cmd_stack_info_depth;
 extern mi_cmd_argv_ftype mi_cmd_stack_list_args;
Index: mi/mi-interp.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-interp.c,v
retrieving revision 1.11
diff -w -u -r1.11 mi-interp.c
--- mi/mi-interp.c	13 Sep 2004 18:26:31 -0000	1.11
+++ mi/mi-interp.c	5 Jan 2005 02:35:30 -0000
@@ -364,6 +364,66 @@
   start_event_loop ();
 }
 
+/* The latest stable mi version that is being tested.
+   There could potentially be several versions of MI that are stable
+   at a time. */
+static const int stable_mi_versions[] = 
+{
+  2,
+  0
+};
+
+/* Allows MI and the front end to agree on an MI protocol.
+   
+   All of the stable MI versions are currently printed. If there is more
+   than one stable MI version, than it is expected the user will write
+   back the version they want to communicate with. 
+   
+   Returns the MI version string the user requested, or if there is only
+   one version, that string is returned. */
+static const char *mi_handshake (struct ui_file *gdb_stdout,
+	struct ui_file *gdb_stdin)
+{
+  static char mi_buf[32]; 
+  int i;
+
+  if (!gdb_stdout || !gdb_stdin)
+	  return NULL;
+
+  /* Output the header, can't use mi_out stuff because no mi has
+	 been chosen and initialized yet. */
+  fprintf_unfiltered ( gdb_stdout, "handshake={stable_protocols={" );
+
+  /* Output all the stable versions */
+  for (i = 0; stable_mi_versions[i] != 0; ++i ) 
+    {
+      if (i > 0)
+        fprintf_unfiltered (gdb_stdout, ",");
+
+        fprintf_unfiltered (gdb_stdout, "mi%d", stable_mi_versions[i] );
+    }
+
+  fprintf_unfiltered ( gdb_stdout, "}}\n" );
+	
+  /* If there was more than one stable version outputted, ask the front
+	 end which one it should use */
+  if ( i > 1 ) 
+  {
+    int size;
+	size = ui_file_read ( gdb_stdin, mi_buf, 31 );
+	mi_buf[size--] = 0; /* null terminate, and remove new line */
+	while ( size >= 0 && (mi_buf[size] == '\n' || mi_buf[size] == '\r') )
+      mi_buf[size--] = 0;
+
+	/* The mi option is not valid in this mode. */
+	if ( strcmp ( mi_buf, "mi" ) == 0 )
+      return NULL;
+  } else
+    sprintf ( mi_buf, "mi%d", stable_mi_versions[0] );
+
+  return mi_buf;
+}
+
 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
 
 void
@@ -379,11 +439,11 @@
   };
 
   /* The various interpreter levels.  */
-  interp_add (interp_new (INTERP_MI1, NULL, mi_out_new (1), &procs));
-  interp_add (interp_new (INTERP_MI2, NULL, mi_out_new (2), &procs));
-  interp_add (interp_new (INTERP_MI3, NULL, mi_out_new (3), &procs));
+  interp_add (interp_new (INTERP_MI1, NULL, mi_out_new (1), &procs, NULL));
+  interp_add (interp_new (INTERP_MI2, NULL, mi_out_new (2), &procs, NULL));
+  interp_add (interp_new (INTERP_MI3, NULL, mi_out_new (3), &procs, NULL));
 
   /* "mi" selects the most recent released version.  "mi2" was
      released as part of GDB 6.0.  */
-  interp_add (interp_new (INTERP_MI, NULL, mi_out_new (2), &procs));
+  interp_add (interp_new (INTERP_MI, NULL, mi_out_new (stable_mi_versions[0]), &procs, mi_handshake));
 }
Index: tui/tui-interp.c
===================================================================
RCS file: /cvs/src/src/gdb/tui/tui-interp.c,v
retrieving revision 1.5
diff -w -u -r1.5 tui-interp.c
--- tui/tui-interp.c	7 Feb 2004 04:40:36 -0000	1.5
+++ tui/tui-interp.c	5 Jan 2005 02:35:31 -0000
@@ -198,7 +198,7 @@
 
   /* Create a default uiout builder for the TUI. */
   tui_out = tui_out_new (gdb_stdout);
-  interp_add (interp_new ("tui", NULL, tui_out, &procs));
+  interp_add (interp_new ("tui", NULL, tui_out, &procs, NULL));
   if (interpreter_p && strcmp (interpreter_p, "tui") == 0)
     tui_start_enabled = 1;
 


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