This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFC 3/3] GDB/MI: Add new "--language LANG" command option.
- From: Joel Brobecker <brobecker at adacore dot com>
- To: gdb-patches at sourceware dot org
- Date: Mon, 11 Nov 2013 10:55:31 +0400
- Subject: Re: [RFC 3/3] GDB/MI: Add new "--language LANG" command option.
- Authentication-results: sourceware.org; auth=none
- References: <1384151855-12926-1-git-send-email-brobecker at adacore dot com> <1384151855-12926-3-git-send-email-brobecker at adacore dot com>
I just realized that I forgot to add an entry in the NEWS file.
Argh! New patch attached.
gdb/ChangeLog:
* mi/mi-parse.h (struct mi_parse) [language]: New field.
* mi/mi-main.c (mi_cmd_execute): Temporarily set language to
PARSE->LANGUAGE during command execution, if set.
* mi/mi-parse.c: Add "language.h" #include.
(mi_parse): Add parsing of "--language" command option.
* NEWS: Add entry mentioning the new "--language" command option.
gdb/testsuite/ChangeLog:
* gdb.mi/mi-language.exp: New file.
gdb/doc/ChangeLog:
* gdb.texinfo (Show): Add xref anchor for "show language" command.
(Context management): Place current subsection text into its own
subsubsection. Add new subsubsection describing the "--language"
command option.
Thanks,
--
Joel
>From f562a28284d5c45f9b67359dd50cb823be484302 Mon Sep 17 00:00:00 2001
From: Joel Brobecker <brobecker@adacore.com>
Date: Mon, 11 Nov 2013 09:21:44 +0400
Subject: [PATCH] GDB/MI: Add new "--language LANG" command option.
Frontend sometimes need to evaluate expressions that are
language-specific. For instance, Eclipse uses the following
expression to determine the size of an address on the target:
-data-evaluate-expression "sizeof (void*)"
Unfortunately, if the main of the program being debugged is not C,
this may not work. For instance, if the main is in Ada, you get...
-data-evaluate-expression "sizeof (void*)"
^error,msg="No definition of \"sizeof\" in current context."
... and apparently decides to stop the debugging session as a result.
The recommendation sent was to specifically set the language to C
before trying to evaluate the expression. Something such as:
1. save current language
2. set language c
3. -data-evaluate-expression "sizeof (void*)"
4. Restore language
This has the same disadvantages as the ones outlined in the "Context
Management" section of the GDB/MI documentation regarding setting
the current thread or the current frame, thus recommending the use of
general command-line switches such as --frame, or --thread instead.
This patch follows the same steps for the language, adding a similar
new command option: --language LANG. Example of use:
-data-evaluate-expression --language c "sizeof (void*)"
^done,value="4"
gdb/ChangeLog:
* mi/mi-parse.h (struct mi_parse) [language]: New field.
* mi/mi-main.c (mi_cmd_execute): Temporarily set language to
PARSE->LANGUAGE during command execution, if set.
* mi/mi-parse.c: Add "language.h" #include.
(mi_parse): Add parsing of "--language" command option.
* NEWS: Add entry mentioning the new "--language" command option.
gdb/testsuite/ChangeLog:
* gdb.mi/mi-language.exp: New file.
gdb/doc/ChangeLog:
* gdb.texinfo (Show): Add xref anchor for "show language" command.
(Context management): Place current subsection text into its own
subsubsection. Add new subsubsection describing the "--language"
command option.
---
gdb/NEWS | 2 ++
gdb/doc/gdb.texinfo | 22 +++++++++++++
gdb/mi/mi-main.c | 7 ++++
gdb/mi/mi-parse.c | 25 ++++++++++++++-
gdb/mi/mi-parse.h | 4 +++
gdb/testsuite/gdb.mi/mi-language.exp | 62 ++++++++++++++++++++++++++++++++++++
6 files changed, 121 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.mi/mi-language.exp
diff --git a/gdb/NEWS b/gdb/NEWS
index 6c3c272..cc7ae1b 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -145,6 +145,8 @@ show startup-with-shell
* MI changes
+ ** All MI commands now accept an optional "--language" option.
+
** The -trace-save MI command can optionally save trace buffer in Common
Trace Format now.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 9731bbf..37c313d 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -13340,6 +13340,7 @@ working language, and also what language source files were written in.
@table @code
@item show language
+@anchor{show language}
@kindex show language
Display the current working language. This is the
language you can use with commands such as @code{print} to
@@ -28706,6 +28707,8 @@ the user interface.
@node Context management
@subsection Context management
+@subsubsection Threads and Frames
+
In most cases when @value{GDBN} accesses the target, this access is
done in context of a specific thread and frame (@pxref{Frames}).
Often, even when accessing global data, the target requires that a thread
@@ -28756,6 +28759,25 @@ all subsequent commands. No frontend is known to do this exactly
right, so it is suggested to just always pass the @samp{--thread} and
@samp{--frame} options.
+@subsubsection Language
+
+The execution of several commands depends on which language is selected.
+By default, the current language (@pxref{show language}) is used.
+But for commands known to be language-sensitive, it is recommended
+to use the @samp{--language} option. This option takes one argument,
+which is the name of the language to use while executing the command.
+For instance:
+
+@smallexample
+-data-evaluate-expression --language c "sizeof (void*)"
+^done,value="4"
+(gdb)
+@end smallexample
+
+The valid language names are the same names accepted by the
+@samp{set language} command (@pxref{Manually}), excluding @samp{auto},
+@samp{local} or @samp{unknown}.
+
@node Asynchronous and non-stop modes
@subsection Asynchronous command execution and non-stop mode
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 8ff7f27..35573af 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2123,6 +2123,7 @@ static void
mi_cmd_execute (struct mi_parse *parse)
{
struct cleanup *cleanup;
+ enum language saved_language;
cleanup = prepare_execute_command ();
@@ -2184,6 +2185,12 @@ mi_cmd_execute (struct mi_parse *parse)
error (_("Invalid frame id: %d"), frame);
}
+ if (parse->language != language_unknown)
+ {
+ make_cleanup_restore_current_language ();
+ set_language (parse->language);
+ }
+
current_context = parse;
if (parse->cmd->suppress_notification != NULL)
diff --git a/gdb/mi/mi-parse.c b/gdb/mi/mi-parse.c
index a3c1849..9994307 100644
--- a/gdb/mi/mi-parse.c
+++ b/gdb/mi/mi-parse.c
@@ -27,6 +27,7 @@
#include <ctype.h>
#include "gdb_string.h"
#include "cli/cli-utils.h"
+#include "language.h"
static const char mi_no_values[] = "--no-values";
static const char mi_simple_values[] = "--simple-values";
@@ -244,6 +245,7 @@ mi_parse (const char *cmd, char **token)
parse->thread_group = -1;
parse->thread = -1;
parse->frame = -1;
+ parse->language = language_unknown;
cleanup = make_cleanup (mi_parse_cleanup, parse);
@@ -292,7 +294,10 @@ mi_parse (const char *cmd, char **token)
some important commands, like '-break-*' are implemented by
forwarding to the CLI layer directly. We want to parse --thread
and --frame here, so as not to leave those option in the string
- that will be passed to CLI. */
+ that will be passed to CLI.
+
+ Same for the --language option. */
+
for (;;)
{
const char *option;
@@ -300,6 +305,7 @@ mi_parse (const char *cmd, char **token)
size_t tgs = sizeof ("--thread-group ") - 1;
size_t ts = sizeof ("--thread ") - 1;
size_t fs = sizeof ("--frame ") - 1;
+ size_t ls = sizeof ("--language ") - 1;
if (strncmp (chp, "--all ", as) == 0)
{
@@ -348,6 +354,23 @@ mi_parse (const char *cmd, char **token)
parse->frame = strtol (chp, &endp, 10);
chp = endp;
}
+ else if (strncmp (chp, "--language ", ls) == 0)
+ {
+ char *lang_name;
+ struct cleanup *old_chain;
+
+ option = "--language";
+ chp += ls;
+ lang_name = extract_arg_const (&chp);
+ old_chain = make_cleanup (xfree, lang_name);
+
+ parse->language = language_enum (lang_name);
+ if (parse->language == language_unknown
+ || parse->language == language_auto)
+ error (_("Invalid --language argument: %s"), lang_name);
+
+ do_cleanups (old_chain);
+ }
else
break;
diff --git a/gdb/mi/mi-parse.h b/gdb/mi/mi-parse.h
index b20a389..325c1e1 100644
--- a/gdb/mi/mi-parse.h
+++ b/gdb/mi/mi-parse.h
@@ -50,6 +50,10 @@ struct mi_parse
int thread_group; /* At present, the same as inferior number. */
int thread;
int frame;
+
+ /* The language that should be used to evaluate the MI command.
+ Ignored if set to language_unknown. */
+ enum language language;
};
/* Attempts to parse CMD returning a ``struct mi_parse''. If CMD is
diff --git a/gdb/testsuite/gdb.mi/mi-language.exp b/gdb/testsuite/gdb.mi/mi-language.exp
new file mode 100644
index 0000000..550beec
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-language.exp
@@ -0,0 +1,62 @@
+# Copyright 2013 Free Software Foundation, Inc.
+
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+mi_gdb_test "set lang ada" \
+ ".*=cmd-param-changed,param=\"language\",value=\"ada\".*" \
+ "set lang ada"
+
+# Evaluate an expression that the Ada language is unable to parse.
+mi_gdb_test "-data-evaluate-expression \"sizeof (void*)\"" \
+ "\\^error,.*" \
+ "sizeof expression using current language"
+
+# Now, ask for the same expression to be parsed, but using the C
+# language.
+mi_gdb_test "-data-evaluate-expression --language c \"sizeof (void*)\"" \
+ "\\^done,value=\"$decimal\"" \
+ "sizeof expression using C language"
+
+# Double-check that the current language has not changed.
+mi_gdb_test "show lang ada" \
+ ".*The current source language is \\\\\"ada\\\\\".*" \
+ "set lang ada"
+
+# Test what happens when specifying an invalid language name...
+mi_gdb_test "-data-evaluate-expression --language invlang \"sizeof (void*)\"" \
+ "\\^error,msg=\"Invalid --language argument: invlang\"" \
+ "data-evaluate-expression with invalid language name"
+
+# Make sure that "--language auto" is also rejected.
+mi_gdb_test "-data-evaluate-expression --language auto \"sizeof (void*)\"" \
+ "\\^error,msg=\"Invalid --language argument: auto\"" \
+ "data-evaluate-expression with language auto"
+
+# Make sure that "--language local" is also rejected.
+mi_gdb_test "-data-evaluate-expression --language local \"sizeof (void*)\"" \
+ "\\^error,msg=\"Invalid --language argument: local\"" \
+ "data-evaluate-expression with language local"
+
+# Make sure that "--language unknown" is also rejected.
+mi_gdb_test "-data-evaluate-expression --language unknown \"sizeof (void*)\"" \
+ "\\^error,msg=\"Invalid --language argument: unknown\"" \
+ "data-evaluate-expression with language unknown"
--
1.8.1.2