[RFC] New GDB/MI command "-info-gdb-mi-command"

Pedro Alves palves@redhat.com
Thu Nov 14 19:37:00 GMT 2013


On 11/14/2013 06:44 PM, Pedro Alves wrote:

> Yeah.  I think that points out that errors like "Undefined MI command:" and
> "Usage:" errors are in a different class of errors from errors caused
> by user input though.  The former should never ever be seen by the user.
> They're "internal" gdb<->frontend errors.  We could/should tag these
> differently somehow, so that the frontend doesn't have to parse a
> free form string.  Like:
> 
>  "^error,msg="..."
>  "^error,msg="...",code="unknown-command"
>  "^error,msg="...",code="usage"
> 
> or some such.
> 
> This does not invalidate listing features in -list-features, as
> it's often useful to know upfront whether some feature is supported,
> so the frontend can disable parts of the GUI that won't make sense
> for the current target/session.
> 

Something like this:

-whatever
^error,msg="Undefined MI command: whatever",error="unknown-command"
(gdb)
-list-thread-groups --frame 1 --frame 1
^error,msg="Duplicate '--frame' option",error="command-usage"
(gdb)

Frontends must ignore unknown attributes, so it's backwards
compatible.

Just a POC.  Of course, we'd have to go audit all MI "error" calls.

---

 gdb/exceptions.h  |    6 ++++++
 gdb/mi/mi-main.c  |   13 ++++++++++++-
 gdb/mi/mi-parse.c |   20 +++++++++++++-------
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/gdb/exceptions.h b/gdb/exceptions.h
index 129d29a..07599ae 100644
--- a/gdb/exceptions.h
+++ b/gdb/exceptions.h
@@ -93,6 +93,12 @@ enum errors {
      aborted as the inferior state is no longer valid.  */
   TARGET_CLOSE_ERROR,

+  /* An unknown command was executed.  */
+  UNKNOWN_COMMAND_ERROR,
+
+  /* Wrong command usage.  */
+  COMMAND_USAGE_ERROR,
+
   /* Add more errors here.  */
   NR_ERRORS
 };
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index bbf944a..c2a3988 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2021,7 +2021,18 @@ mi_print_exception (const char *token, struct gdb_exception exception)
     fputs_unfiltered ("unknown error", raw_stdout);
   else
     fputstr_unfiltered (exception.message, '"', raw_stdout);
-  fputs_unfiltered ("\"\n", raw_stdout);
+  fputs_unfiltered ("\"", raw_stdout);
+
+  switch (exception.error)
+    {
+      case UNKNOWN_COMMAND_ERROR:
+	fputs_unfiltered (",error=\"unknown-command\"", raw_stdout);
+	break;
+      case COMMAND_USAGE_ERROR:
+	fputs_unfiltered (",error=\"command-usage\"", raw_stdout);
+	break;
+    }
+  fputs_unfiltered ("\n", raw_stdout);
 }

 void
diff --git a/gdb/mi/mi-parse.c b/gdb/mi/mi-parse.c
index 9994307..2c9d267 100644
--- a/gdb/mi/mi-parse.c
+++ b/gdb/mi/mi-parse.c
@@ -285,7 +285,8 @@ mi_parse (const char *cmd, char **token)
   /* Find the command in the MI table.  */
   parse->cmd = mi_lookup (parse->command);
   if (parse->cmd == NULL)
-    error (_("Undefined MI command: %s"), parse->command);
+    throw_error (UNKNOWN_COMMAND_ERROR,
+		 _("Undefined MI command: %s"), parse->command);

   /* Skip white space following the command.  */
   chp = skip_spaces_const (chp);
@@ -324,7 +325,8 @@ mi_parse (const char *cmd, char **token)

 	  option = "--thread-group";
 	  if (parse->thread_group != -1)
-	    error (_("Duplicate '--thread-group' option"));
+	    throw_error (COMMAND_USAGE_ERROR,
+			 _("Duplicate '--thread-group' option"));
 	  chp += tgs;
 	  if (*chp != 'i')
 	    error (_("Invalid thread group id"));
@@ -338,7 +340,8 @@ mi_parse (const char *cmd, char **token)

 	  option = "--thread";
 	  if (parse->thread != -1)
-	    error (_("Duplicate '--thread' option"));
+	    throw_error (COMMAND_USAGE_ERROR,
+			 _("Duplicate '--thread' option"));
 	  chp += ts;
 	  parse->thread = strtol (chp, &endp, 10);
 	  chp = endp;
@@ -349,7 +352,8 @@ mi_parse (const char *cmd, char **token)

 	  option = "--frame";
 	  if (parse->frame != -1)
-	    error (_("Duplicate '--frame' option"));
+	    throw_error (COMMAND_USAGE_ERROR,
+			 _("Duplicate '--frame' option"));
 	  chp += fs;
 	  parse->frame = strtol (chp, &endp, 10);
 	  chp = endp;
@@ -367,7 +371,8 @@ mi_parse (const char *cmd, char **token)
 	  parse->language = language_enum (lang_name);
 	  if (parse->language == language_unknown
 	      || parse->language == language_auto)
-	    error (_("Invalid --language argument: %s"), lang_name);
+	    throw_error (COMMAND_USAGE_ERROR,
+			 _("Invalid --language argument: %s"), lang_name);

 	  do_cleanups (old_chain);
 	}
@@ -414,7 +419,8 @@ mi_parse_print_values (const char *name)
 	    || strcmp (name, mi_simple_values) == 0)
      return PRINT_SIMPLE_VALUES;
    else
-     error (_("Unknown value for PRINT_VALUES: must be: \
+     throw_error (COMMAND_USAGE_ERROR,
+		  _("Unknown value for PRINT_VALUES: must be: \
 0 or \"%s\", 1 or \"%s\", 2 or \"%s\""),
-	    mi_no_values, mi_all_values, mi_simple_values);
+		  mi_no_values, mi_all_values, mi_simple_values);
 }



More information about the Gdb-patches mailing list