Discussion:
[RFA 0/5] Use language mode in 'info [functions|variables|types]|rbreak'
Philippe Waroquiers
2018-10-28 14:46:09 UTC
Permalink
The commands 'info [functions|variables|types]|rbreak' work
on the global program, not only in the current frame.
So in in mixed languages program, these commands examine and print
entities defined in different languages.

Now, GDB uses the current language to print all the results of
these commands, which is somewhat surprising.

For example, when the current frame is in Ada,
info function gethostbyname gives:
File ../nss/getXXbyYY.c:
87: function gethostbyname (a1: access char) return access hostent;

This patch series ensures that these commands respect the 'set language auto'
setup, to print the results in the language used to define the printed
entities.
Philippe Waroquiers
2018-10-28 14:46:10 UTC
Permalink
The class scoped_switch_auto_to_sym_language allows to switch in a scope
the current language to the language of a symbol when language mode is
set to auto.

2018-10-27 Philippe Waroquiers <***@skynet.be>

* language.h (scoped_switch_auto_to_sym_language): new class.
---
gdb/language.h | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)

diff --git a/gdb/language.h b/gdb/language.h
index 02a84ff9a2..47a88de756 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -707,4 +707,43 @@ private:
enum language m_lang;
};

+/* If language_mode is language_mode_auto,
+ then switches current language to the language of SYM
+ and restore current language upon destruction.
+
+ Else does nothing. */
+
+class scoped_switch_auto_to_sym_language
+{
+public:
+
+ explicit scoped_switch_auto_to_sym_language (const struct symbol *sym)
+ {
+ if (language_mode == language_mode_auto)
+ {
+ m_lang = current_language->la_language;
+ m_switched = true;
+ set_language (SYMBOL_LANGUAGE (sym));
+ }
+ else
+ m_switched = false;
+ }
+
+ ~scoped_switch_auto_to_sym_language ()
+ {
+ if (m_switched)
+ set_language (m_lang);
+ }
+
+ scoped_switch_auto_to_sym_language
+ (const scoped_switch_auto_to_sym_language &)
+ = delete;
+ scoped_switch_auto_to_sym_language &operator=
+ (const scoped_switch_auto_to_sym_language &) = delete;
+
+private:
+ bool m_switched;
+ enum language m_lang;
+};
+
#endif /* defined (LANGUAGE_H) */
--
2.19.1
Pedro Alves
2018-11-16 18:27:48 UTC
Permalink
Post by Philippe Waroquiers
The class scoped_switch_auto_to_sym_language allows to switch in a scope
the current language to the language of a symbol when language mode is
set to auto.
* language.h (scoped_switch_auto_to_sym_language): new class.
s/new/New/
Post by Philippe Waroquiers
---
gdb/language.h | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/gdb/language.h b/gdb/language.h
index 02a84ff9a2..47a88de756 100644
--- a/gdb/language.h
+++ b/gdb/language.h
enum language m_lang;
};
+/* If language_mode is language_mode_auto,
+ then switches current language to the language of SYM
+ and restore current language upon destruction.
+
+ Else does nothing. */
Either
s/switches/switch/
s/does/do/
or
s/restore/restores/

I'd go with the former.
Post by Philippe Waroquiers
+
+class scoped_switch_auto_to_sym_language
I have to admit that I had trouble grokking the class's name
for a bit. I don't have a much better suggestion, though
this would read a bit better to me:

scoped_switch_to_sym_language_if_auto
scoped_switch_to_sym_lang_if_auto

But may well be just me. Feel free to ignore.
Post by Philippe Waroquiers
+{
+
+ explicit scoped_switch_auto_to_sym_language (const struct symbol *sym)
+ {
+ if (language_mode == language_mode_auto)
+ {
+ m_lang = current_language->la_language;
+ m_switched = true;
+ set_language (SYMBOL_LANGUAGE (sym));
+ }
+ else
+ m_switched = false;
+ }
+
+ ~scoped_switch_auto_to_sym_language ()
+ {
+ if (m_switched)
+ set_language (m_lang);
+ }
+
+ scoped_switch_auto_to_sym_language
+ (const scoped_switch_auto_to_sym_language &)
+ = delete;
+ scoped_switch_auto_to_sym_language &operator=
+ (const scoped_switch_auto_to_sym_language &) = delete;
Use DISABLE_COPY_AND_ASSIGN instead.

Otherwise OK.
Post by Philippe Waroquiers
+
+ bool m_switched;
+ enum language m_lang;
+};
+
#endif /* defined (LANGUAGE_H) */
Thanks,
Pedro Alves
Philippe Waroquiers
2018-10-28 14:46:11 UTC
Permalink
Use scoped_switch_auto_to_sym_language in treg_matches_sym_type_name to
replace the local logic that was doing the same as the new class
scoped_switch_auto_to_sym_language.

Use scoped_switch_auto_to_sym_language inside print_symbol_info, so
that symbol information is printed in the symbol language when
language mode is auto.
This modifies the behaviour of the test dw2-case-insensitive.exp,
as the function FUNC_lang is now printed with the Fortran syntax
(as declared in the .S file).

gdb/ChangeLog
2018-10-27 Philippe Waroquiers <***@skynet.be>

* symtab.c (treg_matches_sym_type_name): Use
scoped_switch_auto_to_sym_language instead of local logic.
(print_symbol_info): Use scoped_switch_auto_to_sym_language
to switch to SYM language when language mode is auto.

gdb/testsuite/ChangeLOg
2018-10-27 Philippe Waroquiers <***@skynet.be>

* gdb.dwarf2/dw2-case-insensitive.exp: Update due to auto switch to
FUNC_lang language syntax.
---
gdb/symtab.c | 12 +++++-------
gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp | 4 +++-
2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gdb/symtab.c b/gdb/symtab.c
index cd27a75e8c..0f9d562c84 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4288,15 +4288,12 @@ treg_matches_sym_type_name (const compiled_regex &treg,
if (sym_type == NULL)
return false;

- if (language_mode == language_mode_auto)
- {
- scoped_restore_current_language l;
+ {
+ scoped_switch_auto_to_sym_language l (sym);

- set_language (SYMBOL_LANGUAGE (sym));
- printed_sym_type_name = type_to_string (sym_type);
- }
- else
printed_sym_type_name = type_to_string (sym_type);
+ }
+

if (symbol_lookup_debug > 1)
{
@@ -4601,6 +4598,7 @@ print_symbol_info (enum search_domain kind,
struct symbol *sym,
int block, const char *last)
{
+ scoped_switch_auto_to_sym_language l (sym);
struct symtab *s = symbol_symtab (sym);

if (last != NULL)
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
index b15dcafa00..2e3397865a 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
@@ -42,8 +42,10 @@ gdb_test "info functions fUnC_lang" \
gdb_test "set case-sensitive off" {warning: the current case sensitivity setting does not match the language\.}

# The dot-leading symbol is for ppc64 function descriptors.
+# Note that info functions gives the FUNC_lang result using the fortran syntax
+# as specific in dw-case-insensitive-debug.S DW_AT_language.
gdb_test "info functions fUnC_lang" \
- "All functions matching regular expression \"fUnC_lang\":\[\r\n\]+File file1.txt:\r\n\tfoo FUNC_lang\\(void\\);(\r\n\r\nNon-debugging symbols:\r\n0x\[0-9a-f\]+ +\\.FUNC_lang)?" \
+ "All functions matching regular expression \"fUnC_lang\":\[\r\n\]+File file1.txt:\r\n\tfoo FUNC_lang\\(\\);(\r\n\r\nNon-debugging symbols:\r\n0x\[0-9a-f\]+ +\\.FUNC_lang)?" \
"regexp case-sensitive off"

gdb_test "p fuNC_lang" { = {foo \(void\)} 0x[0-9a-f]+ <FUNC_lang>}
--
2.19.1
Pedro Alves
2018-11-16 18:28:28 UTC
Permalink
Post by Philippe Waroquiers
Use scoped_switch_auto_to_sym_language in treg_matches_sym_type_name to
replace the local logic that was doing the same as the new class
scoped_switch_auto_to_sym_language.
Use scoped_switch_auto_to_sym_language inside print_symbol_info, so
that symbol information is printed in the symbol language when
language mode is auto.
This modifies the behaviour of the test dw2-case-insensitive.exp,
as the function FUNC_lang is now printed with the Fortran syntax
(as declared in the .S file).
+
if (symbol_lookup_debug > 1)
{
@@ -4601,6 +4598,7 @@ print_symbol_info (enum search_domain kind,
struct symbol *sym,
int block, const char *last)
{
+ scoped_switch_auto_to_sym_language l (sym);
Sounds unnecessarily inefficient to use the scoped switch here
instead of at the caller to avoid the back and forth for each
symbol, but probably this isn't in any hot path, so it's fine.
Post by Philippe Waroquiers
struct symtab *s = symbol_symtab (sym);
if (last != NULL)
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
index b15dcafa00..2e3397865a 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
@@ -42,8 +42,10 @@ gdb_test "info functions fUnC_lang" \
gdb_test "set case-sensitive off" {warning: the current case sensitivity setting does not match the language\.}
# The dot-leading symbol is for ppc64 function descriptors.
+# Note that info functions gives the FUNC_lang result using the fortran syntax
+# as specific in dw-case-insensitive-debug.S DW_AT_language.
gdb_test "info functions fUnC_lang" \
- "All functions matching regular expression \"fUnC_lang\":\[\r\n\]+File file1.txt:\r\n\tfoo FUNC_lang\\(void\\);(\r\n\r\nNon-debugging symbols:\r\n0x\[0-9a-f\]+ +\\.FUNC_lang)?" \
+ "All functions matching regular expression \"fUnC_lang\":\[\r\n\]+File file1.txt:\r\n\tfoo FUNC_lang\\(\\);(\r\n\r\nNon-debugging symbols:\r\n0x\[0-9a-f\]+ +\\.FUNC_lang)?" \
"regexp case-sensitive off"
OOC, the actual name & type matching respect the symbol's language, right?

Patch is OK.

Thanks,
Pedro Alves
Philippe Waroquiers
2018-11-17 12:24:12 UTC
Permalink
Post by Pedro Alves
Post by Philippe Waroquiers
if (symbol_lookup_debug > 1)
{
@@ -4601,6 +4598,7 @@ print_symbol_info (enum search_domain kind,
struct symbol *sym,
int block, const char *last)
{
+ scoped_switch_auto_to_sym_language l (sym);
Sounds unnecessarily inefficient to use the scoped switch here
instead of at the caller to avoid the back and forth for each
symbol, but probably this isn't in any hot path, so it's fine.
Yes, I do not think this is performance critical,
and also, switching of language is not very expensive :
it implies to construct/destroy scoped_switch_auto_to_sym_language l,
which do calls to functions setting enumeration values for
the language and case settings.
Post by Pedro Alves
Post by Philippe Waroquiers
struct symtab *s = symbol_symtab (sym);
if (last != NULL)
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
index b15dcafa00..2e3397865a 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
@@ -42,8 +42,10 @@ gdb_test "info functions fUnC_lang" \
gdb_test "set case-sensitive off" {warning: the current case sensitivity setting does not match the language\.}
# The dot-leading symbol is for ppc64 function descriptors.
+# Note that info functions gives the FUNC_lang result using the fortran syntax
+# as specific in dw-case-insensitive-debug.S DW_AT_language.
gdb_test "info functions fUnC_lang" \
- "All functions matching regular expression \"fUnC_lang\":\[\r\n\]+File file1.txt:\r\n\tfoo FUNC_lang\\(void\\);(\r\n\r\nNon-debugging symbols:\r\n0x\[0-9a-f\]+ +\\.FUNC_lang)?" \
+ "All functions matching regular expression \"fUnC_lang\":\[\r\n\]+File file1.txt:\r\n\tfoo FUNC_lang\\(\\);(\r\n\r\nNon-debugging symbols:\r\n0x\[0-9a-f\]+ +\\.FUNC_lang)?" \
"regexp case-sensitive off"
OOC, the actual name & type matching respect the symbol's language, right?
Yes, effectively, the previous patch series that introduced
e.g. 'info function -t TYPEREGEXP' was already switching to the entity language
to do the matching of the type.

The only somewhat (strange ? non intuitive ?) behavior remaining is that the
entity names are printed (and matched) not according to the language setting,
but according to the 'set print demangle' setting.

For example, in the below, you see that with set lang c, the var name
is still printed with a . after global_pack, while intuitively, one
would have expected the 'raw' name with __. The __ are shown
when demangling is off.

(gdb) set lang c
Warning: the current language does not match this frame.
(gdb) info var some_struct_in_ada
All variables matching regular expression "some_struct_in_ada":

File /bd/home/philippe/gdb/git/info_t/gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads:
24: struct global_pack__some_type_in_ada global_pack.some_struct_in_ada;
(gdb) set print demangle off
(gdb) info var some_struct_in_ada
All variables matching regular expression "some_struct_in_ada":

File /bd/home/philippe/gdb/git/info_t/gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads:
24: struct global_pack__some_type_in_ada global_pack__some_struct_in_ada;
(gdb) 

I guess that changing this would mean to have demangling be driven by language
setting (not too sure how the demangling logic works now).


Thanks for the review, I think I handled all your comments/suggestions
in RFAv2.

Philippe

Philippe Waroquiers
2018-10-28 14:46:14 UTC
Permalink
gdb/ChangeLog
2018-10-27 Philippe Waroquiers <***@skynet.be>

* NEWS: Document the language choice done by
'info [types|functions|variables]|rbreak'.
---
gdb/NEWS | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/gdb/NEWS b/gdb/NEWS
index 7fe588dabb..5bc9749369 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -95,6 +95,15 @@ info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]
on the entity names or entity types. The flag -q disables
printing headers or informations messages.

+info functions
+info types
+info variables
+rbreak
+ These commands now uses the language choice specified using `set language'
+ to choose the syntax to print the results. In particular,
+ `set language auto' means to automatically choose the language of
+ the shown entities.
+
thread apply [all | COUNT | -COUNT] [FLAG]... COMMAND
The 'thread apply' command accepts new FLAG arguments.
FLAG arguments allow to control what output to produce and how to handle
--
2.19.1
Eli Zaretskii
2018-10-28 15:31:41 UTC
Permalink
Date: Sun, 28 Oct 2018 15:46:14 +0100
diff --git a/gdb/NEWS b/gdb/NEWS
index 7fe588dabb..5bc9749369 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -95,6 +95,15 @@ info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]
on the entity names or entity types. The flag -q disables
printing headers or informations messages.
+info functions
+info types
+info variables
+rbreak
+ These commands now uses the language choice specified using `set language'
+ to choose the syntax to print the results. In particular,
I'd suggest a slight rewording of the first sentence:

These commands now determine the syntax for the shown entities
according to the language chosen by `set language'.

Thanks.
Philippe Waroquiers
2018-10-28 14:46:13 UTC
Permalink
doc/ChangeLog
2018-10-27 Philippe Waroquiers <***@skynet.be>

* gdb.texinfo (Examining the Symbol Table): Document language choice
for 'info types|functions|variables' commands.
(Setting Breakpoints): Document language choice to print
the functions in which a breakpoint is set.
---
gdb/doc/gdb.texinfo | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 8c1e618973..86445b8f45 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -3873,6 +3873,12 @@ breakpoints are set, they are treated just like the breakpoints set with
the @code{break} command. You can delete them, disable them, or make
them conditional the same way as any other breakpoint.

+In programs using different languages, @value{GDBN} chooses the syntax
+to print the list of all breakpoints it sets according to the
+@samp{set language} value: using @samp{set language auto} means
+to use the language of the breakpoint's function, other values mean to use
+the manually specified language.
+
The syntax of the regular expression is the standard one used with tools
like @file{grep}. Note that this is different from the syntax used by
shells, so for instance @code{foo*} matches all functions that include
@@ -17902,6 +17908,12 @@ types in your program whose names include the string @code{value}, but
@samp{i type ^value$} gives information only on types whose complete
name is @code{value}.

+In programs using different languages, @value{GDBN} chooses the syntax
+to print the type description according to the
+@samp{set language} value: using @samp{set language auto} means
+to use the language of the type, other values mean to use
+the manually specified language.
+
This command differs from @code{ptype} in two ways: first, like
@code{whatis}, it does not print a detailed description; second, it
lists all source files and line numbers where a type is defined.
@@ -17986,6 +17998,12 @@ Similarly to @samp{info types}, this command groups its output by source
files and annotates each function definition with its source line
number.

+In programs using different languages, @value{GDBN} chooses the syntax
+to print the function name and type according to the
+@samp{set language} value: using @samp{set language auto} means
+to use the language of the function, other values mean to use
+the manually specified language.
+
The optional flag @samp{-q}, which stands for @samp{quiet}, disables
printing header information and messages explaining why no functions
have been printed.
@@ -18026,6 +18044,12 @@ outside of functions (i.e.@: excluding local variables).
The printed variables are grouped by source files and annotated with
their respective source line numbers.

+In programs using different languages, @value{GDBN} chooses the syntax
+to print the variable name and type according to the
+@samp{set language} value: using @samp{set language auto} means
+to use the language of the variable, other values mean to use
+the manually specified language.
+
The optional flag @samp{-q}, which stands for @samp{quiet}, disables
printing header information and messages explaining why no variables
have been printed.
--
2.19.1
Eli Zaretskii
2018-10-28 15:33:10 UTC
Permalink
Date: Sun, 28 Oct 2018 15:46:13 +0100
+to print the list of all breakpoints it sets according to the
+to use the language of the breakpoint's function, other values mean to use
+the manually specified language.
Please add a cross-reference to where "set language" is described,
here and in the other places where you make these changes.

Thanks.
Philippe Waroquiers
2018-10-28 14:46:12 UTC
Permalink
2018-10-27 Philippe Waroquiers <***@skynet.be>

* gdb.ada/info_auto_lang.exp: New testcase.
* gdb.ada/info_auto_lang/global_pack.ads: New file.
* gdb.ada/info_auto_lang/proc_in_ada.adb: New file.
* gdb.ada/info_auto_lang/some_c.c: New file.
---
gdb/testsuite/gdb.ada/info_auto_lang.exp | 153 ++++++++++++++++++
.../gdb.ada/info_auto_lang/global_pack.ads | 10 ++
.../gdb.ada/info_auto_lang/proc_in_ada.adb | 11 ++
gdb/testsuite/gdb.ada/info_auto_lang/some_c.c | 15 ++
4 files changed, 189 insertions(+)
create mode 100644 gdb/testsuite/gdb.ada/info_auto_lang.exp
create mode 100644 gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads
create mode 100644 gdb/testsuite/gdb.ada/info_auto_lang/proc_in_ada.adb
create mode 100644 gdb/testsuite/gdb.ada/info_auto_lang/some_c.c

diff --git a/gdb/testsuite/gdb.ada/info_auto_lang.exp b/gdb/testsuite/gdb.ada/info_auto_lang.exp
new file mode 100644
index 0000000000..60a8b5a17c
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/info_auto_lang.exp
@@ -0,0 +1,153 @@
+# Copyright 2018 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 "ada.exp"
+
+# This test verifies that the commands
+# info [functions|variables|types]
+# are respecting the 'set language auto|ada|c' setup, whatever the language
+# of the current frame.
+# Similarly, checks that rbreak reports its results respecting
+# the language mode.
+
+standard_ada_testfile proc_in_ada
+set cfile "some_c"
+set csrcfile ${srcdir}/${subdir}/${testdir}/${cfile}.c
+set cobject [standard_output_file ${cfile}.o]
+
+gdb_compile "${csrcfile}" "${cobject}" object [list debug]
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } {
+ return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/some_c.c]
+runto "some_c.c:$bp_location"
+
+set number "\[0-9]\+"
+
+set func_in_c(c_syntax) "${number}: void proc_in_c\\\(void\\\);"
+set func_in_c(ada_syntax) "${number}: procedure proc_in_c;"
+set func_in_ada(c_syntax) "${number}: void proc_in_ada\\\(void\\\);"
+set func_in_ada(ada_syntax) "${number}: procedure proc_in_ada;"
+
+set type_in_c(c_syntax) [multi_line \
+ "${number}: typedef struct {" \
+ " int some_component_in_c;" \
+ "} some_type_in_c;" ]
+set type_in_c(ada_syntax) [multi_line \
+ "${number}: record" \
+ " some_component_in_c: int;" \
+ "end record" ]
+set type_in_ada(c_syntax) "${number}: struct global_pack__some_type_in_ada;"
+set type_in_ada(ada_syntax) "${number}: global_pack.some_type_in_ada;"
+
+set var_in_c(c_syntax) "${number}: some_type_in_c some_struct_in_c;"
+set var_in_c(ada_syntax) "${number}: some_struct_in_c: some_type_in_c;"
+set var_in_ada(c_syntax) "${number}: struct global_pack__some_type_in_ada global_pack.some_struct_in_ada;"
+set var_in_ada(ada_syntax) "${number}: global_pack.some_struct_in_ada: global_pack.some_type_in_ada;"
+
+set rbreak_func_in_c(c_syntax) "void proc_in_c\\\(void\\\);"
+set rbreak_func_in_c(ada_syntax) "procedure proc_in_c;"
+set rbreak_func_in_ada(c_syntax) "void proc_in_ada\\\(void\\\);"
+set rbreak_func_in_ada(ada_syntax) "procedure proc_in_ada;"
+
+
+foreach_with_prefix language_choice { "auto" "ada" "c" } {
+
+ # Switch to the desired language_choice in a frame giving no warning,
+ # and then, set the expected matches for the various commands tested
+ # afterwards.
+ if {$language_choice == "auto"} {
+ gdb_test "frame 0" "#0 .*" "select frame with lang c"
+ set c_match c_syntax
+ set ada_match ada_syntax
+ } elseif {$language_choice == "ada"} {
+ gdb_test "frame 1" "#1 .*" "select frame with lang ada"
+ set c_match ada_syntax
+ set ada_match ada_syntax
+ } elseif {$language_choice == "c"} {
+ gdb_test "frame 0" "#0 .*" "select frame with lang c"
+ set c_match c_syntax
+ set ada_match c_syntax
+ } else {
+ fail "unexpected language choice"
+ }
+ gdb_test_no_output "set language $language_choice" "set language language_choice"
+
+ foreach frame {
+ "0"
+ "1" } {
+ if { $frame == 0 } {
+ set frame_lang "c"
+ } else {
+ set frame_lang "ada"
+ }
+ gdb_test "frame $frame" "#$frame .*" "select frame $frame with lang $frame_lang"
+ set selected_frame_msg [concat " in selected frame " $frame " with lang $frame_lang"]
+
+ set cmd "info functions proc_in_"
+ set check [concat $cmd $selected_frame_msg]
+ gdb_test $cmd \
+ [multi_line \
+ "All functions matching regular expression \"proc_in_\":" \
+ "" \
+ "File .*some_c.c:" \
+ $func_in_c($c_match) \
+ "" \
+ "File .*proc_in_ada.adb:" \
+ $func_in_ada($ada_match)
+ ] $check
+
+ set cmd "info types some_type"
+ set check [concat $cmd $selected_frame_msg]
+ gdb_test $cmd \
+ [multi_line \
+ "All types matching regular expression \"some_type\":" \
+ "" \
+ "File .*some_c.c:" \
+ $type_in_c($c_match) \
+ "" \
+ "File .*global_pack.ads:" \
+ $type_in_ada($ada_match)
+ ] $check
+
+ set cmd "info variables some_struct"
+ set check [concat $cmd $selected_frame_msg]
+ gdb_test $cmd \
+ [multi_line \
+ "All variables matching regular expression \"some_struct\":" \
+ "" \
+ "File .*some_c.c:" \
+ $var_in_c($c_match) \
+ "" \
+ "File .*global_pack.ads:" \
+ $var_in_ada($ada_match)
+ ] $check
+
+ set cmd "rbreak proc_in_"
+ set check [concat $cmd $selected_frame_msg]
+ gdb_test $cmd \
+ [multi_line \
+ "Breakpoint.*file .*some_c.c,.*" \
+ $rbreak_func_in_c($c_match) \
+ "Breakpoint.*file .*proc_in_ada.adb,.*" \
+ $rbreak_func_in_ada($ada_match)
+ ] $check
+ delete_breakpoints
+ }
+}
+
diff --git a/gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads b/gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads
new file mode 100644
index 0000000000..5feeacd1fb
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads
@@ -0,0 +1,10 @@
+package Global_Pack is
+ Some_Number_In_Ada : Integer := 0;
+
+ type Some_Type_In_Ada is
+ record
+ Some_Component_In_Ada : Integer;
+ end record;
+
+ Some_Struct_In_Ada : Some_Type_In_Ada;
+end Global_Pack;
diff --git a/gdb/testsuite/gdb.ada/info_auto_lang/proc_in_ada.adb b/gdb/testsuite/gdb.ada/info_auto_lang/proc_in_ada.adb
new file mode 100644
index 0000000000..d244db43e7
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/info_auto_lang/proc_in_ada.adb
@@ -0,0 +1,11 @@
+with Text_Io; use Text_Io;
+with Global_Pack; use Global_Pack;
+procedure Proc_In_Ada is
+ procedure Something_In_C
+ with Import, Convention => C, External_Name => "proc_in_c";
+ pragma Linker_Options ("some_c.o");
+begin
+ Something_In_C;
+ Some_Number_In_Ada := Some_Number_In_Ada + 1;
+ Put_Line ("hello world from Ada");
+end Proc_In_Ada;
diff --git a/gdb/testsuite/gdb.ada/info_auto_lang/some_c.c b/gdb/testsuite/gdb.ada/info_auto_lang/some_c.c
new file mode 100644
index 0000000000..79ca1627e2
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/info_auto_lang/some_c.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+int some_number_in_c;
+typedef struct {
+ int some_component_in_c;
+} some_type_in_c;
+
+some_type_in_c some_struct_in_c;
+void proc_in_c (void)
+{
+ some_number_in_c++;
+ some_struct_in_c.some_component_in_c++;
+ printf ("Hello world from C %d %d\n", /* STOP */
+ some_number_in_c,
+ some_struct_in_c.some_component_in_c);
+}
--
2.19.1
Pedro Alves
2018-11-16 18:29:58 UTC
Permalink
Post by Philippe Waroquiers
* gdb.ada/info_auto_lang.exp: New testcase.
* gdb.ada/info_auto_lang/global_pack.ads: New file.
* gdb.ada/info_auto_lang/proc_in_ada.adb: New file.
* gdb.ada/info_auto_lang/some_c.c: New file.
---
gdb/testsuite/gdb.ada/info_auto_lang.exp | 153 ++++++++++++++++++
.../gdb.ada/info_auto_lang/global_pack.ads | 10 ++
.../gdb.ada/info_auto_lang/proc_in_ada.adb | 11 ++
gdb/testsuite/gdb.ada/info_auto_lang/some_c.c | 15 ++
4 files changed, 189 insertions(+)
create mode 100644 gdb/testsuite/gdb.ada/info_auto_lang.exp
create mode 100644 gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads
create mode 100644 gdb/testsuite/gdb.ada/info_auto_lang/proc_in_ada.adb
create mode 100644 gdb/testsuite/gdb.ada/info_auto_lang/some_c.c
diff --git a/gdb/testsuite/gdb.ada/info_auto_lang.exp b/gdb/testsuite/gdb.ada/info_auto_lang.exp
new file mode 100644
index 0000000000..60a8b5a17c
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/info_auto_lang.exp
@@ -0,0 +1,153 @@
+# Copyright 2018 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 "ada.exp"
+
+# This test verifies that the commands
+# info [functions|variables|types]
+# are respecting the 'set language auto|ada|c' setup, whatever the language
+# of the current frame.
s/are respecting/respect/

s/setup/setting/ (I guess?)
Post by Philippe Waroquiers
+# Similarly, checks that rbreak reports its results respecting
+# the language mode.
+
+standard_ada_testfile proc_in_ada
+set cfile "some_c"
+set csrcfile ${srcdir}/${subdir}/${testdir}/${cfile}.c
+set cobject [standard_output_file ${cfile}.o]
+
+gdb_compile "${csrcfile}" "${cobject}" object [list debug]
Should check return of gdb_compile, and call untested.
Post by Philippe Waroquiers
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } {
+ return -1
+}
"untested".
Post by Philippe Waroquiers
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/some_c.c]
+runto "some_c.c:$bp_location"
Check result of runto.
Post by Philippe Waroquiers
+
+set number "\[0-9]\+"
You can use $decimal instead.
Post by Philippe Waroquiers
+
+set func_in_c(c_syntax) "${number}: void proc_in_c\\\(void\\\);"
+set func_in_c(ada_syntax) "${number}: procedure proc_in_c;"
+set func_in_ada(c_syntax) "${number}: void proc_in_ada\\\(void\\\);"
+set func_in_ada(ada_syntax) "${number}: procedure proc_in_ada;"
+
+set type_in_c(c_syntax) [multi_line \
+ "${number}: typedef struct {" \
+ " int some_component_in_c;" \
+ "} some_type_in_c;" ]
+set type_in_c(ada_syntax) [multi_line \
+ "${number}: record" \
+ " some_component_in_c: int;" \
+ "end record" ]
+set type_in_ada(c_syntax) "${number}: struct global_pack__some_type_in_ada;"
+set type_in_ada(ada_syntax) "${number}: global_pack.some_type_in_ada;"
+
+set var_in_c(c_syntax) "${number}: some_type_in_c some_struct_in_c;"
+set var_in_c(ada_syntax) "${number}: some_struct_in_c: some_type_in_c;"
+set var_in_ada(c_syntax) "${number}: struct global_pack__some_type_in_ada global_pack.some_struct_in_ada;"
+set var_in_ada(ada_syntax) "${number}: global_pack.some_struct_in_ada: global_pack.some_type_in_ada;"
+
+set rbreak_func_in_c(c_syntax) "void proc_in_c\\\(void\\\);"
+set rbreak_func_in_c(ada_syntax) "procedure proc_in_c;"
+set rbreak_func_in_ada(c_syntax) "void proc_in_ada\\\(void\\\);"
+set rbreak_func_in_ada(ada_syntax) "procedure proc_in_ada;"
+
+
+foreach_with_prefix language_choice { "auto" "ada" "c" } {
+
+ # Switch to the desired language_choice in a frame giving no warning,
I'm having trouble understanding what this means, but I think you meant:

# Check that switching to the desired language_choice when the selected
# frame has the same language (or the desired language is auto) gives no
# warning. Also set the expected matches for the various commands
# tested afterwards.

Is that right?
Post by Philippe Waroquiers
+ # and then, set the expected matches for the various commands tested
+ # afterwards.
+ if {$language_choice == "auto"} {
+ gdb_test "frame 0" "#0 .*" "select frame with lang c"
+ set c_match c_syntax
+ set ada_match ada_syntax
+ } elseif {$language_choice == "ada"} {
+ gdb_test "frame 1" "#1 .*" "select frame with lang ada"
+ set c_match ada_syntax
+ set ada_match ada_syntax
+ } elseif {$language_choice == "c"} {
+ gdb_test "frame 0" "#0 .*" "select frame with lang c"
+ set c_match c_syntax
+ set ada_match c_syntax
+ } else {
+ fail "unexpected language choice"
This would be a testcase bug, so should be an error instead of a fail.
Post by Philippe Waroquiers
+ }
+ gdb_test_no_output "set language $language_choice" "set language language_choice"
+
+ foreach frame {
+ "0"
+ "1" } {
+ if { $frame == 0 } {
+ set frame_lang "c"
+ } else {
+ set frame_lang "ada"
+ }
+ gdb_test "frame $frame" "#$frame .*" "select frame $frame with lang $frame_lang"
+ set selected_frame_msg [concat " in selected frame " $frame " with lang $frame_lang"]
+
+ set cmd "info functions proc_in_"
+ set check [concat $cmd $selected_frame_msg]
+ gdb_test $cmd \
+ [multi_line \
+ "All functions matching regular expression \"proc_in_\":" \
+ "" \
+ "File .*some_c.c:" \
+ $func_in_c($c_match) \
+ "" \
+ "File .*proc_in_ada.adb:" \
+ $func_in_ada($ada_match)
+ ] $check
+
+ set cmd "info types some_type"
+ set check [concat $cmd $selected_frame_msg]
+ gdb_test $cmd \
+ [multi_line \
+ "All types matching regular expression \"some_type\":" \
+ "" \
+ "File .*some_c.c:" \
+ $type_in_c($c_match) \
+ "" \
+ "File .*global_pack.ads:" \
+ $type_in_ada($ada_match)
+ ] $check
+
+ set cmd "info variables some_struct"
+ set check [concat $cmd $selected_frame_msg]
+ gdb_test $cmd \
+ [multi_line \
+ "All variables matching regular expression \"some_struct\":" \
+ "" \
+ "File .*some_c.c:" \
+ $var_in_c($c_match) \
+ "" \
+ "File .*global_pack.ads:" \
+ $var_in_ada($ada_match)
+ ] $check
+
+ set cmd "rbreak proc_in_"
+ set check [concat $cmd $selected_frame_msg]
+ gdb_test $cmd \
+ [multi_line \
+ "Breakpoint.*file .*some_c.c,.*" \
+ $rbreak_func_in_c($c_match) \
+ "Breakpoint.*file .*proc_in_ada.adb,.*" \
+ $rbreak_func_in_ada($ada_match)
+ ] $check
+ delete_breakpoints
+ }
+}
+
diff --git a/gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads b/gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads
new file mode 100644
index 0000000000..5feeacd1fb
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/info_auto_lang/global_pack.ads
Missing copyright header.
Post by Philippe Waroquiers
@@ -0,0 +1,10 @@
+package Global_Pack is
+ Some_Number_In_Ada : Integer := 0;
+
+ type Some_Type_In_Ada is
+ record
+ Some_Component_In_Ada : Integer;
+ end record;
+
+ Some_Struct_In_Ada : Some_Type_In_Ada;
+end Global_Pack;
diff --git a/gdb/testsuite/gdb.ada/info_auto_lang/proc_in_ada.adb b/gdb/testsuite/gdb.ada/info_auto_lang/proc_in_ada.adb
new file mode 100644
index 0000000000..d244db43e7
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/info_auto_lang/proc_in_ada.adb
Missing copyright header.
Post by Philippe Waroquiers
@@ -0,0 +1,11 @@
+with Text_Io; use Text_Io;
+with Global_Pack; use Global_Pack;
+procedure Proc_In_Ada is
+ procedure Something_In_C
+ with Import, Convention => C, External_Name => "proc_in_c";
+ pragma Linker_Options ("some_c.o");
+begin
+ Something_In_C;
+ Some_Number_In_Ada := Some_Number_In_Ada + 1;
+ Put_Line ("hello world from Ada");
+end Proc_In_Ada;
diff --git a/gdb/testsuite/gdb.ada/info_auto_lang/some_c.c b/gdb/testsuite/gdb.ada/info_auto_lang/some_c.c
new file mode 100644
index 0000000000..79ca1627e2
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/info_auto_lang/some_c.c
Missing copyright header.
Post by Philippe Waroquiers
@@ -0,0 +1,15 @@
+#include <stdio.h>
If not important to the testcase, it's better to avoid stdio.h/printf etc.,
so that the testcase works against bare metal targets that don't support
hosted I/O.
Post by Philippe Waroquiers
+int some_number_in_c;
+typedef struct {
+ int some_component_in_c;
+} some_type_in_c;
+
+some_type_in_c some_struct_in_c;
+void proc_in_c (void)
+{
+ some_number_in_c++;
+ some_struct_in_c.some_component_in_c++;
+ printf ("Hello world from C %d %d\n", /* STOP */
+ some_number_in_c,
+ some_struct_in_c.some_component_in_c);
This (and Ada's equivalent) printf isn't used by the .exp file, right?

BTW, I think that with the small change below, the gdb.sum output
is more structured, and thus clearer. You'd need to indent the body
of with_test_prefix, of course. WDYT?

Otherwise OK.

From d28c1a6473db03c4621b3592617afc805e847ad8 Mon Sep 17 00:00:00 2001
From: Pedro Alves <***@redhat.com>
Date: Fri, 16 Nov 2018 16:59:38 +0000
Subject: [PATCH] gdb.sum

---
gdb/testsuite/gdb.ada/info_auto_lang.exp | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/gdb/testsuite/gdb.ada/info_auto_lang.exp b/gdb/testsuite/gdb.ada/info_auto_lang.exp
index 60a8b5a17c..531e981f2a 100644
--- a/gdb/testsuite/gdb.ada/info_auto_lang.exp
+++ b/gdb/testsuite/gdb.ada/info_auto_lang.exp
@@ -96,11 +96,13 @@ foreach_with_prefix language_choice { "auto" "ada" "c" } {
} else {
set frame_lang "ada"
}
- gdb_test "frame $frame" "#$frame .*" "select frame $frame with lang $frame_lang"
- set selected_frame_msg [concat " in selected frame " $frame " with lang $frame_lang"]
+
+ with_test_prefix "frame=$frame, frame_lang=$frame_lang" {
+
+ gdb_test "frame $frame" "#$frame .*" "select frame"
+ set selected_frame_msg [concat " in selected frame " $frame]

set cmd "info functions proc_in_"
- set check [concat $cmd $selected_frame_msg]
gdb_test $cmd \
[multi_line \
"All functions matching regular expression \"proc_in_\":" \
@@ -110,10 +112,9 @@ foreach_with_prefix language_choice { "auto" "ada" "c" } {
"" \
"File .*proc_in_ada.adb:" \
$func_in_ada($ada_match)
- ] $check
+ ]

set cmd "info types some_type"
- set check [concat $cmd $selected_frame_msg]
gdb_test $cmd \
[multi_line \
"All types matching regular expression \"some_type\":" \
@@ -123,10 +124,9 @@ foreach_with_prefix language_choice { "auto" "ada" "c" } {
"" \
"File .*global_pack.ads:" \
$type_in_ada($ada_match)
- ] $check
+ ]

set cmd "info variables some_struct"
- set check [concat $cmd $selected_frame_msg]
gdb_test $cmd \
[multi_line \
"All variables matching regular expression \"some_struct\":" \
@@ -136,18 +136,18 @@ foreach_with_prefix language_choice { "auto" "ada" "c" } {
"" \
"File .*global_pack.ads:" \
$var_in_ada($ada_match)
- ] $check
+ ]

set cmd "rbreak proc_in_"
- set check [concat $cmd $selected_frame_msg]
gdb_test $cmd \
[multi_line \
"Breakpoint.*file .*some_c.c,.*" \
$rbreak_func_in_c($c_match) \
"Breakpoint.*file .*proc_in_ada.adb,.*" \
$rbreak_func_in_ada($ada_match)
- ] $check
+ ]
delete_breakpoints
+ }
}
}
--
2.14.4
Philippe Waroquiers
2018-11-13 19:15:37 UTC
Permalink
thanks
Post by Philippe Waroquiers
The commands 'info [functions|variables|types]|rbreak' work
on the global program, not only in the current frame.
So in in mixed languages program, these commands examine and print
entities defined in different languages.
Now, GDB uses the current language to print all the results of
these commands, which is somewhat surprising.
For example, when the current frame is in Ada,
87: function gethostbyname (a1: access char) return access hostent;
This patch series ensures that these commands respect the 'set language auto'
setup, to print the results in the language used to define the printed
entities.
Loading...