Re: [PATCH 1/7] gdb: Add new -n flag to some info commands

Andrew Burgess
2019-08-26T15:52:10Z

* Eli Zaretskii <eliz@gnu.org> [2019-07-31 17:51:26 +0300]:

> > Date: Tue, 30 Jul 2019 22:02:45 +0100
> > From: Andrew Burgess <andrew.burgess@embecosm.com>
> > Cc: gdb-patches@sourceware.org, Richard.Bunt@arm.com
> >
> > --- a/gdb/NEWS
> > +++ b/gdb/NEWS
> > @@ -215,6 +215,11 @@ maint show test-options-completion-result
> > printing of some header information in a similar fashion to "info
> > variables" and "info functions".
> >
> > + ** The "info variables", "info functions", and "whereis" commands
> > + now take a '-n' flag that excludes non-debug symbols (symbols
> > + from the ELF's symbol table, rather than from the DWARf) from the
> > + results.
>
> This is good, except that I wouldn't mention "ELF", because this
> feature also works for non-ELF binaries, right? So I'd just say
> "symbols from the symbol table, not from the debug info such as
> DWARF".
>
> > +The function information comes from two sources, the debug information
> > +associated with the executable (for example DWARF), but also non-debug
> > +symbols are included in the results, these are symbols taken from the
> > +symbol table of the executable. A non-debug symbol is only included
> > +if it is for a symbol in an executable section. The @samp{-n} flag
> > +excludes non-debugging symbols from the results.
>
> My suggestion is to reverse the order: first say what -n does, then
> explain the terminology:
>
> The @samp{-n} flag excludes @dfn{non-debugging symbols} from the
> results. A non-debugging symbol is a symbol that comes from the
> executable's symbol table, not from the debug information (for
> example, DWARF) associated with the executable.
>
> > @@ -18574,7 +18581,7 @@
> >
> >
> > @kindex info variables
> > -@item info variables [-q]
> > +@item info variables [-q] [-n]
> > Print the names and data types of all variables that are defined
> > outside of functions (i.e.@: excluding local variables).
> > The printed variables are grouped by source files and annotated with
> > @@ -18587,11 +18594,18 @@
> > language of the variable, other values mean to use
> > the manually specified language (see @ref{Manually, ,Set Language Manually}).
> >
> > +The variable information comes from two sources, the debug information
> > +associated with the executable (for example DWARF), but also non-debug
> > +symbols are included in the results, these are symbols taken from the
> > +symbol table of the executable. A non-debug symbol is only included
> > +if it is for a symbol in a data section. The @samp{-n} flag excludes
> > +non-debugging symbols from the results.
>
> Instead of repeating the same text just a few dozen lines after the
> first instance, I'd just use "non-debugging symbols" here, because
> they were already defined above. IOW, keep the last sentence only.

Thanks for the feedback, and sorry for the huge delay in getting
around to look at this series again.

A new version of this patch is below that addresses your comments
above:

- Updated text in gdb/NEWS, and
- Updated text in gdb/doc/gdb.texinfo

Thanks,
Andrew

---

commit 3d90d43bcff73300e5116701397d52ad9f6fb572
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date: Mon Jul 22 16:53:06 2019 +0100

gdb: Add new -n flag to some info commands

The 'info variables', its alias 'whereis', and 'info functions' all
include non-debug symbols in the output by default. The list of
non-debug symbols can sometimes be quite long, resulting in the
debug symbol based results being scrolled off the screen.

This commit adds a '-n' flag to all of the commands listed above that
excludes the non-debug symbols from the results, leaving just the
debug symbol based results.

gdb/ChangeLog:

* cli/cli-utils.c (info_print_options_defs): Delete.
(make_info_print_options_def_group): Delete.
(extract_info_print_options): Delete.
(info_print_command_completer): Delete.
(info_print_args_help): Add extra parameter, and optionally
include text about -n flag.
* cli/cli-utils.h (struct info_print_options): Delete.
(extract_info_print_options): Delete declaration.
(info_print_command_completer): Delete declaration.
(info_print_args_help): Add extra parameter, extend header
comment.
* python/python.c (gdbpy_rbreak): Pass additional parameter to
search_symbols.
* stack.c (struct info_print_options): New type.
(info_print_options_defs): New file scoped variable.
(make_info_print_options_def_group): New static function.
(info_print_command_completer): New static function.
(info_locals_command): Update to use new local functions.
(info_args_command): Likewise.
(_initialize_stack): Add extra parameter to calls to
info_print_args_help.
* symtab.c (search_symbols): Add extra parameter, use this to
possibly excluse non-debug symbols.
(symtab_symbol_info): Add extra parameter, which is passed on to
search_symbols.
(struct info_print_options): New type.
(info_print_options_defs): New file scoped variable.
(make_info_print_options_def_group): New static function.
(info_print_command_completer): New static function.
(info_variables_command): Update to use local functions, and pass
extra parameter through to symtab_symbol_info.
(info_functions_command): Likewise.
(info_types_command): Pass additional argument through to
symtab_symbol_info.
(rbreak_command): Pass extra argument to search_symbols.
(_initialize_symtab): Add extra arguments for calls to
info_print_args_help, and update help text for 'info variables',
'whereis', and 'info functions' commands.
* symtab.h (search_symbols): Add extra argument to declaration.
* NEWS: Mention new flags.

gdb/doc/ChangeLog:

* gdb.texinfo (Symbols): Add information about the -n flag to
"info variables" and "info functions".

gdb/testsuite/ChangeLog:

* gdb.base/info-fun.exp: Extend to test the -n flag for 'info
functions'. Reindent as needed.
* gdb.base/info-var-f1.c: New file.
* gdb.base/info-var-f2.c: New file.
* gdb.base/info-var.exp: New file.
* gdb.base/info-var.h: New file.

diff --git a/gdb/NEWS b/gdb/NEWS
index 894a2546ac0..a6df12f879b 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -257,6 +257,11 @@ maint show test-options-completion-result
printing of some header information in a similar fashion to "info
variables" and "info functions".

+ ** The "info variables", "info functions", and "whereis" commands
+ now take a '-n' flag that excludes non-debug symbols (symbols
+ from the symbol table, not from the debug info such as DWARf)
+ from the results.
+
* Completion improvements

** GDB can now complete the options of the "thread apply all" and
diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
index c6405505d99..b6b21c95b03 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -194,7 +194,8 @@ report_unrecognized_option_error (const char *command, const char *args)

const char *
info_print_args_help (const char *prefix,
- const char *entity_kind)
+ const char *entity_kind,
+ bool document_n_flag)
{
return xstrprintf (_("\
%sIf NAMEREGEXP is provided, only prints the %s whose name\n\
@@ -204,8 +205,11 @@ matches TYPEREGEXP. Note that the matching is done with the type\n\
printed by the 'whatis' command.\n\
By default, the command might produce headers and/or messages indicating\n\
why no %s can be printed.\n\
-The flag -q disables the production of these headers and messages."),
- prefix, entity_kind, entity_kind, entity_kind);
+The flag -q disables the production of these headers and messages.%s"),
+ prefix, entity_kind, entity_kind, entity_kind,
+ (document_n_flag ? _("\n\
+By default, the command will include non-debug symbols in the output;\n\
+these can be excluded using the -n flag.") : ""));
}

/* See documentation in cli-utils.h. */
@@ -435,58 +439,3 @@ validate_flags_qcs (const char *which_command, qcs_flags *flags)
error (_("%s: -c and -s are mutually exclusive"), which_command);
}

-/* The options used by the 'info variables' commands and similar. */
-
-static const gdb::option::option_def info_print_options_defs[] = {
- gdb::option::boolean_option_def<info_print_options> {
- "q",
- [] (info_print_options *opt) { return &opt->quiet; },
- nullptr, /* show_cmd_cb */
- nullptr /* set_doc */
- },
-
- gdb::option::string_option_def<info_print_options> {
- "t",
- [] (info_print_options *opt) { return &opt->type_regexp; },
- nullptr, /* show_cmd_cb */
- nullptr /* set_doc */
- }
-};
-
-/* Returns the option group used by 'info variables' and similar. */
-
-static gdb::option::option_def_group
-make_info_print_options_def_group (info_print_options *opts)
-{
- return {{info_print_options_defs}, opts};
-}
-
-/* See documentation in cli-utils.h. */
-
-void
-extract_info_print_options (info_print_options *opts,
- const char **args)
-{
- auto grp = make_info_print_options_def_group (opts);
- gdb::option::process_options
- (args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
- if (*args != nullptr && **args == '\0')
- *args = nullptr;
-}
-
-/* See documentation in cli-utils.h. */
-
-void
-info_print_command_completer (struct cmd_list_element *ignore,
- completion_tracker &tracker,
- const char *text, const char * /* word */)
-{
- const auto group
- = make_info_print_options_def_group (nullptr);
- if (gdb::option::complete_options
- (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
- return;
-
- const char *word = advance_to_expression_complete_word_point (tracker, text);
- symbol_completer (ignore, tracker, text, word);
-}
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
index 17cdd842b2f..cbe8ff66e15 100644
--- a/gdb/cli/cli-utils.h
+++ b/gdb/cli/cli-utils.h
@@ -47,38 +47,6 @@ extern int get_number (char **);
error instead of returning 0. */
extern ULONGEST get_ulongest (const char **pp, int trailer = '\0');

-/* Structure to hold the values of the options used by the 'info
- variables' command and other similar commands. These correspond to the
- -q and -t options. */
-
-struct info_print_options
-{
- int quiet = false;
- char *type_regexp = nullptr;
-
- ~info_print_options ()
- {
- xfree (type_regexp);
- }
-};
-
-/* Extract options from ARGS for commands like 'info variables', placing
- the options into OPTS. ARGS is updated to point to the first character
- after the options, or, if there is nothing after the options, then ARGS
- is set to nullptr. */
-
-extern void extract_info_print_options (info_print_options *opts,
- const char **args);
-
-/* Function that can be used as a command completer for 'info variable'
- and friends. This offers command option completion as well as symbol
- completion. At the moment all symbols are offered for all commands. */
-
-extern void info_print_command_completer (struct cmd_list_element *ignore,
- completion_tracker &tracker,
- const char *text,
- const char * /* word */);
-
/* Throws an error telling the user that ARGS starts with an option
unrecognized by COMMAND. */

@@ -87,10 +55,13 @@ extern void report_unrecognized_option_error (const char *command,

/* Builds the help string for a command documented by PREFIX,
- followed by the extract_info_print_args help for ENTITY_KIND. */
+ followed by the extract_info_print_args help for ENTITY_KIND. If
+ DOCUMENT_N_FLAG is true then help text descibing the -n flag is also
+ included. */

const char *info_print_args_help (const char *prefix,
- const char *entity_kind);
+ const char *entity_kind,
+ bool document_n_flag);

/* Parse a number or a range.
A number will be of the form handled by get_number.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 1e7af64e55e..d8cea1a085d 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18609,7 +18609,7 @@
have case-insensitive filesystem (e.g., MS-Windows).

@kindex info functions
-@item info functions [-q]
+@item info functions [-q] [-n]
Print the names and data types of all defined functions.
Similarly to @samp{info types}, this command groups its output by source
files and annotates each function definition with its source line
@@ -18622,11 +18622,16 @@
language of the function, other values mean to use
the manually specified language (see @ref{Manually, ,Set Language Manually}).

+The @samp{-n} flag excludes @dfn{non-debugging symbols} from the
+results. A non-debugging symbol is a symbol that comes from the
+executable's symbol table, not from the debug information (for
+example, DWARF) associated with the executable.
+
The optional flag @samp{-q}, which stands for @samp{quiet}, disables
printing header information and messages explaining why no functions
have been printed.

-@item info functions [-q] [-t @var{type_regexp}] [@var{regexp}]
+@item info functions [-q] [-n] [-t @var{type_regexp}] [@var{regexp}]
Like @samp{info functions}, but only print the names and data types
of the functions selected with the provided regexp(s).

@@ -18656,7 +18661,7 @@

@kindex info variables
-@item info variables [-q]
+@item info variables [-q] [-n]
Print the names and data types of all variables that are defined
outside of functions (i.e.@: excluding local variables).
The printed variables are grouped by source files and annotated with
@@ -18669,11 +18674,13 @@
language of the variable, other values mean to use
the manually specified language (see @ref{Manually, ,Set Language Manually}).

+The @samp{-n} flag excludes non-debugging symbols from the results.
+
The optional flag @samp{-q}, which stands for @samp{quiet}, disables
printing header information and messages explaining why no variables
have been printed.

-@item info variables [-q] [-t @var{type_regexp}] [@var{regexp}]
+@item info variables [-q] [-n] [-t @var{type_regexp}] [@var{regexp}]
Like @kbd{info variables}, but only print the variables selected
with the provided regexp(s).

diff --git a/gdb/python/python.c b/gdb/python/python.c
index 162470dcc02..8f4cbb5d701 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -734,10 +734,10 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw)
const char **files = symtab_paths.vec.data ();

symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL,
- symtab_paths.vec.size (), files);
+ symtab_paths.vec.size (), files, false);
}
else
- symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 0, NULL);
+ symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 0, NULL, false);

/* Count the number of symbols (both symbols and optionally minimal
symbols) so we can correctly check the throttle limit. */
diff --git a/gdb/stack.c b/gdb/stack.c
index 06431ea3543..10a88e99aba 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -2417,13 +2417,76 @@ print_frame_local_vars (struct frame_info *frame,
}
}

+/* Structure to hold the values of the options used by the 'info
+ variables' command and other similar commands. These correspond to the
+ -q and -t options. */
+
+struct info_print_options
+{
+ int quiet = false;
+ char *type_regexp = nullptr;
+
+ ~info_print_options ()
+ {
+ xfree (type_regexp);
+ }
+};
+
+/* The options used by the 'info locals' and 'info args' commands. */
+
+static const gdb::option::option_def info_print_options_defs[] = {
+ gdb::option::boolean_option_def<info_print_options> {
+ "q",
+ [] (info_print_options *opt) { return &opt->quiet; },
+ nullptr, /* show_cmd_cb */
+ nullptr /* set_doc */
+ },
+
+ gdb::option::string_option_def<info_print_options> {
+ "t",
+ [] (info_print_options *opt) { return &opt->type_regexp; },
+ nullptr, /* show_cmd_cb */
+ nullptr /* set_doc */
+ }
+};
+
+/* Returns the option group used by 'info locals' and 'info args'
+ commands. */
+
+static gdb::option::option_def_group
+make_info_print_options_def_group (info_print_options *opts)
+{
+ return {{info_print_options_defs}, opts};
+}
+
+/* Command completer for 'info locals' and 'info args'. */
+
+static void
+info_print_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char * /* word */)
+{
+ const auto group
+ = make_info_print_options_def_group (nullptr);
+ if (gdb::option::complete_options
+ (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
+ return;
+
+ const char *word = advance_to_expression_complete_word_point (tracker, text);
+ symbol_completer (ignore, tracker, text, word);
+}
+
/* Implement the 'info locals' command. */

void
info_locals_command (const char *args, int from_tty)
{
info_print_options opts;
- extract_info_print_options (&opts, &args);
+ auto grp = make_info_print_options_def_group (&opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+ if (args != nullptr && *args == '\0')
+ args = nullptr;

print_frame_local_vars (get_selected_frame (_("No frame selected.")),
opts.quiet, args, opts.type_regexp,
@@ -2530,7 +2593,11 @@ void
info_args_command (const char *args, int from_tty)
{
info_print_options opts;
- extract_info_print_options (&opts, &args);
+ auto grp = make_info_print_options_def_group (&opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+ if (args != nullptr && *args == '\0')
+ args = nullptr;

print_frame_arg_vars (get_selected_frame (_("No frame selected.")),
opts.quiet, args, opts.type_regexp, gdb_stdout);
@@ -3487,14 +3554,16 @@ Usage: info frame level LEVEL"),
All local variables of current stack frame or those matching REGEXPs.\n\
Usage: info locals [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the local variables of the current stack frame.\n"),
- _("local variables")));
+ _("local variables"),
+ false));
set_cmd_completer_handle_brkchars (cmd, info_print_command_completer);
cmd = add_info ("args", info_args_command,
info_print_args_help (_("\
All argument variables of current stack frame or those matching REGEXPs.\n\
Usage: info args [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the argument variables of the current stack frame.\n"),
- _("argument variables")));
+ _("argument variables"),
+ false));
set_cmd_completer_handle_brkchars (cmd, info_print_command_completer);

if (dbx_commands)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index bd6fa35db6a..62c9078797e 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4454,12 +4454,16 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)

Within each file the results are sorted locally; each symtab's global and
static blocks are separately alphabetized.
- Duplicate entries are removed. */
+ Duplicate entries are removed.
+
+ When EXCLUDE_MINSYMS is false then matching minsyms are also returned,
+ otherwise they are excluded. */

std::vector<symbol_search>
search_symbols (const char *regexp, enum search_domain kind,
const char *t_regexp,
- int nfiles, const char *files[])
+ int nfiles, const char *files[],
+ bool exclude_minsyms)
{
const struct blockvector *bv;
const struct block *b;
@@ -4675,6 +4679,7 @@ search_symbols (const char *regexp, enum search_domain kind,
as we assume that a minimal symbol does not have a type. */

if ((found_misc || (nfiles == 0 && kind != FUNCTIONS_DOMAIN))
+ && !exclude_minsyms
&& !treg.has_value ())
{
for (objfile *objfile : current_program_space->objfiles ())
@@ -4821,7 +4826,7 @@ print_msymbol_info (struct bound_minimal_symbol msymbol)
matches. */

static void
-symtab_symbol_info (bool quiet,
+symtab_symbol_info (bool quiet, bool exclude_minsyms,
const char *regexp, enum search_domain kind,
const char *t_regexp, int from_tty)
{
@@ -4837,7 +4842,8 @@ symtab_symbol_info (bool quiet,

/* Must make sure that if we're interrupted, symbols gets freed. */
std::vector<symbol_search> symbols = search_symbols (regexp, kind,
- t_regexp, 0, NULL);
+ t_regexp, 0, NULL,
+ exclude_minsyms);

if (!quiet)
{
@@ -4890,15 +4896,87 @@ symtab_symbol_info (bool quiet,
}
}

+/* Structure to hold the values of the options used by the 'info variables'
+ and 'info functions' commands. These correspond to the -q, -t, and -n
+ options. */
+
+struct info_print_options
+{
+ int quiet = false;
+ int exclude_minsyms = false;
+ char *type_regexp = nullptr;
+
+ ~info_print_options ()
+ {
+ xfree (type_regexp);
+ }
+};
+
+/* The options used by the 'info variables' and 'info functions'
+ commands. */
+
+static const gdb::option::option_def info_print_options_defs[] = {
+ gdb::option::boolean_option_def<info_print_options> {
+ "q",
+ [] (info_print_options *opt) { return &opt->quiet; },
+ nullptr, /* show_cmd_cb */
+ nullptr /* set_doc */
+ },
+
+ gdb::option::boolean_option_def<info_print_options> {
+ "n",
+ [] (info_print_options *opt) { return &opt->exclude_minsyms; },
+ nullptr, /* show_cmd_cb */
+ nullptr /* set_doc */
+ },
+
+ gdb::option::string_option_def<info_print_options> {
+ "t",
+ [] (info_print_options *opt) { return &opt->type_regexp; },
+ nullptr, /* show_cmd_cb */
+ nullptr /* set_doc */
+ }
+};
+
+/* Returns the option group used by 'info variables' and 'info
+ functions'. */
+
+static gdb::option::option_def_group
+make_info_print_options_def_group (info_print_options *opts)
+{
+ return {{info_print_options_defs}, opts};
+}
+
+/* Command completer for 'info variables' and 'info functions'. */
+
+static void
+info_print_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char * /* word */)
+{
+ const auto group
+ = make_info_print_options_def_group (nullptr);
+ if (gdb::option::complete_options
+ (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
+ return;
+
+ const char *word = advance_to_expression_complete_word_point (tracker, text);
+ symbol_completer (ignore, tracker, text, word);
+}
+
/* Implement the 'info variables' command. */

static void
info_variables_command (const char *args, int from_tty)
{
info_print_options opts;
- extract_info_print_options (&opts, &args);
+ auto grp = make_info_print_options_def_group (&opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+ if (args != nullptr && *args == '\0')
+ args = nullptr;

- symtab_symbol_info (opts.quiet, args, VARIABLES_DOMAIN,
+ symtab_symbol_info (opts.quiet, opts.exclude_minsyms, args, VARIABLES_DOMAIN,
opts.type_regexp, from_tty);
}

@@ -4908,10 +4986,14 @@ static void
info_functions_command (const char *args, int from_tty)
{
info_print_options opts;
- extract_info_print_options (&opts, &args);
+ auto grp = make_info_print_options_def_group (&opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+ if (args != nullptr && *args == '\0')
+ args = nullptr;

- symtab_symbol_info (opts.quiet, args, FUNCTIONS_DOMAIN,
- opts.type_regexp, from_tty);
+ symtab_symbol_info (opts.quiet, opts.exclude_minsyms, args,
+ FUNCTIONS_DOMAIN, opts.type_regexp, from_tty);
}

/* Holds the -q option for the 'info types' command. */
@@ -4952,7 +5034,7 @@ info_types_command (const char *args, int from_tty)
(&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
if (args != nullptr && *args == '\0')
args = nullptr;
- symtab_symbol_info (opts.quiet, args, TYPES_DOMAIN, NULL, from_tty);
+ symtab_symbol_info (opts.quiet, false, args, TYPES_DOMAIN, NULL, from_tty);
}

/* Command completer for 'info types' command. */
@@ -5013,7 +5095,8 @@ rbreak_command (const char *regexp, int from_tty)
std::vector<symbol_search> symbols = search_symbols (regexp,
FUNCTIONS_DOMAIN,
NULL,
- nfiles, files);
+ nfiles, files,
+ false);

scoped_rbreak_breakpoints finalize;
for (const symbol_search &p : symbols)
@@ -6246,27 +6329,30 @@ _initialize_symtab (void)
c = add_info ("variables", info_variables_command,
info_print_args_help (_("\
All global and static variable names or those matching REGEXPs.\n\
-Usage: info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Usage: info variables [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the global and static variables.\n"),
- _("global and static variables")));
+ _("global and static variables"),
+ true));
set_cmd_completer_handle_brkchars (c, info_print_command_completer);
if (dbx_commands)
{
c = add_com ("whereis", class_info, info_variables_command,
info_print_args_help (_("\
All global and static variable names, or those matching REGEXPs.\n\
-Usage: whereis [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Usage: whereis [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the global and static variables.\n"),
- _("global and static variables")));
+ _("global and static variables"),
+ true));
set_cmd_completer_handle_brkchars (c, info_print_command_completer);
}

c = add_info ("functions", info_functions_command,
info_print_args_help (_("\
All function names or those matching REGEXPs.\n\
-Usage: info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Usage: info functions [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the functions.\n"),
- _("functions")));
+ _("functions"),
+ true));
set_cmd_completer_handle_brkchars (c, info_print_command_completer);

c = add_info ("types", info_types_command, _("\
diff --git a/gdb/symtab.h b/gdb/symtab.h
index caf396db9f1..f009cb499be 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2065,7 +2065,8 @@ extern std::vector<symbol_search> search_symbols (const char *,
enum search_domain,
const char *,
int,
- const char **);
+ const char **,
+ bool);
extern bool treg_matches_sym_type_name (const compiled_regex &treg,
const struct symbol *sym);

diff --git a/gdb/testsuite/gdb.base/info-fun.exp b/gdb/testsuite/gdb.base/info-fun.exp
index 208525eda65..cee3a09ac14 100644
--- a/gdb/testsuite/gdb.base/info-fun.exp
+++ b/gdb/testsuite/gdb.base/info-fun.exp
@@ -30,54 +30,63 @@ if [get_compiler_info] {
return -1
}

-# SEP must be last for the possible `unsupported' error path.
-foreach libsepdebug {NO IN SEP} { with_test_prefix "$libsepdebug" {
+foreach_with_prefix n_flag { 0 1 } {

- set sep_lib_flags $lib_flags
- if {$libsepdebug != "NO"} {
- lappend sep_lib_flags {debug}
- }
- if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $sep_lib_flags] != ""
- || [gdb_compile $srcdir/$subdir/${srcfile} ${binfile} \
- executable $bin_flags] != "" } {
- untested "failed to compile"
- return -1
- }
+ # SEP must be last for the possible `unsupported' error path.
+ foreach libsepdebug {NO IN SEP} { with_test_prefix "$libsepdebug" {

- if {$libsepdebug == "SEP"} {
- if {[gdb_gnu_strip_debug $binfile_lib] != 0} {
- unsupported "could not split debug of $binfile_lib."
- return
- } else {
- pass "split solib"
+ set sep_lib_flags $lib_flags
+ if {$libsepdebug != "NO"} {
+ lappend sep_lib_flags {debug}
+ }
+ if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $sep_lib_flags] != ""
+ || [gdb_compile $srcdir/$subdir/${srcfile} ${binfile} \
+ executable $bin_flags] != "" } {
+ untested "failed to compile"
+ return -1
}
- }

- clean_restart $executable
+ if {$libsepdebug == "SEP"} {
+ if {[gdb_gnu_strip_debug $binfile_lib] != 0} {
+ unsupported "could not split debug of $binfile_lib."
+ return
+ } else {
+ pass "split solib"
+ }
+ }
+
+ clean_restart $executable
+
+ if ![runto_main] then {
+ fail "can't run to main"
+ return 0
+ }

- if ![runto_main] then {
- fail "can't run to main"
- return 0
- }
+ set match_str {All functions matching regular expression "foo":[\r\n]*}
+ if { "$libsepdebug" != "NO" } {
+ append match_str {File .*/info-fun-solib[.]c:[\r\n]*}
+ append match_str {\d+:\tint foo\(void\);[\r\n]*}
+ }

- set match_str {All functions matching regular expression "foo":[\r\n]*}
- if { "$libsepdebug" != "NO" } {
- append match_str {File .*/info-fun-solib[.]c:[\r\n]*}
- append match_str {\d+:\tint foo\(void\);[\r\n]*}
- }
- append match_str {Non-debugging symbols:[\r\n]*}
- # Note: Targets like {m68k,ppc64,s390x}-linux also have, e.g.,
- # 00000011.plt_call.foo+0 (m68k).
- set plt_foo_match "($hex \[^\r\n\]*plt\[^\r\n\]*foo\[^\r\n\]*\[\r\n\]*)?"
- append match_str $plt_foo_match
- # This text we want to match precisely.
- append match_str "$hex *foo(@plt)?\[\r\n\]*"
- # Watch for again to not have to worry about the order of appearance.
- append match_str $plt_foo_match
- if { "$libsepdebug" == "NO" } {
- # Note: The ".?" is for targets like m68k-linux that have ".foo" here.
- append match_str "$hex *.?foo\[\r\n\]*"
- }
+ set opt ""
+ if { !$n_flag } {
+ append match_str {Non-debugging symbols:[\r\n]*}
+ # Note: Targets like {m68k,ppc64,s390x}-linux also have, e.g.,
+ # 00000011.plt_call.foo+0 (m68k).
+ set plt_foo_match "($hex \[^\r\n\]*plt\[^\r\n\]*foo\[^\r\n\]*\[\r\n\]*)?"
+ append match_str $plt_foo_match
+ # This text we want to match precisely.
+ append match_str "$hex *foo(@plt)?\[\r\n\]*"
+ # Watch for again to not have to worry about the order of appearance.
+ append match_str $plt_foo_match
+ if { "$libsepdebug" == "NO" } {
+ # Note: The ".?" is for targets like m68k-linux that have ".foo" here.
+ append match_str "$hex *.?foo\[\r\n\]*"
+ }
+ } else {
+ set opt "-n"
+ }

- gdb_test "info fun foo" "$match_str"
-}}
+ gdb_test "info fun $opt foo" "$match_str"
+ }}
+}
diff --git a/gdb/testsuite/gdb.base/info-var-f1.c b/gdb/testsuite/gdb.base/info-var-f1.c
new file mode 100644
index 00000000000..b0587f12da1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/info-var-f1.c
@@ -0,0 +1,24 @@
+/* Copyright 2019 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/>. */
+
+#include "info-var.h"
+
+static int f1_var = -3;
+
+int
+main ()
+{
+ return global_var + get_offset() + f1_var;
+}
diff --git a/gdb/testsuite/gdb.base/info-var-f2.c b/gdb/testsuite/gdb.base/info-var-f2.c
new file mode 100644
index 00000000000..fdff696ebeb
--- /dev/null
+++ b/gdb/testsuite/gdb.base/info-var-f2.c
@@ -0,0 +1,26 @@
+/* Copyright 2019 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/>. */
+
+#include "info-var.h"
+
+int global_var = 1;
+
+static int f2_var = 2;
+
+int
+get_offset (void)
+{
+ return f2_var;
+}
diff --git a/gdb/testsuite/gdb.base/info-var.exp b/gdb/testsuite/gdb.base/info-var.exp
new file mode 100644
index 00000000000..5a07d6214da
--- /dev/null
+++ b/gdb/testsuite/gdb.base/info-var.exp
@@ -0,0 +1,60 @@
+# Copyright 2019 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/>.
+
+# Some basic testing of 'info variables'.
+
+standard_testfile info-var-f1.c info-var-f2.c
+
+if {[prepare_for_testing "failed to prepare" \
+ "${testfile}" "$srcfile $srcfile2" "debug"]} {
+ return -1
+}
+
+if ![runto_main] then {
+ fail "can't run to main"
+ return 0
+}
+
+gdb_test "info variables" \
+ [multi_line \
+ "All defined variables:" \
+ "" \
+ "File .*${srcfile}:" \
+ "18:\[ \t\]+static int f1_var;" \
+ "" \
+ "File .*${srcfile2}:" \
+ "18:\[ \t\]+int global_var;" \
+ "20:\[ \t\]+static int f2_var;" \
+ "" \
+ "Non-debugging symbols:" \
+ ".*"]
+
+gdb_test "info variables -n" \
+ [multi_line \
+ "All defined variables:" \
+ "" \
+ "File .*${srcfile}:" \
+ "18:\[ \t\]+static int f1_var;" \
+ "" \
+ "File .*${srcfile2}:" \
+ "18:\[ \t\]+int global_var;" \
+ "20:\[ \t\]+static int f2_var;" ]
+
+gdb_test "info variables -n global" \
+ [multi_line \
+ "All variables matching regular expression \"global\":" \
+ "" \
+ "File .*${srcfile2}:" \
+ "18:\[ \t\]+int global_var;" ]
diff --git a/gdb/testsuite/gdb.base/info-var.h b/gdb/testsuite/gdb.base/info-var.h
new file mode 100644
index 00000000000..d65db82474c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/info-var.h
@@ -0,0 +1,18 @@
+/* Copyright 2019 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/>. */
+
+extern int global_var;
+
+extern int get_offset (void);