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

Andrew Burgess
2019-07-30T21:02:54Z

* Eli Zaretskii <eliz@gnu.org> [2019-07-27 19:40:58 +0300]:

> > From: Andrew Burgess <andrew.burgess@embecosm.com>
> > Cc: Richard Bunt <Richard.Bunt@arm.com>, Andrew Burgess <andrew.burgess@embecosm.com>
> > Date: Sat, 27 Jul 2019 17:22:29 +0100
> >
> > index cc1d58520d4..40b56727227 100644
> > --- a/gdb/NEWS
> > +++ b/gdb/NEWS
> > @@ -215,6 +215,10 @@ 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 from the
> > + results.
>
> I'm afraid "non-debug symbols" will not be self-explanatory enough.
> Can we say something more concrete here, or at least give a couple of
> examples?
>
> > +By default, the command will include non-debug symbols in the output\n\
> > +these can be excluded using the -n flag." : ""));
>
> I believe we need a semi-colon after "output".
>
> > +Non-debug symbols are also included in the results if the symbols are
> > +of a type that indicates they might be for executable code. The
> > +@samp{-n} flag excludes non-debugging symbols from the results.
>
> Please add here text that explains what are "non-debug symbols". I
> also had difficulty understanding what does "a type that indicates
> they might be for executable code" means, so maybe clarify that as
> well.
>
> > @@ -18587,11 +18591,15 @@
> > language of the variable, other values mean to use
> > the manually specified language (see @ref{Manually, ,Set Language Manually}).
> >
> > +Non-debug symbols are also included in the results if the symbols are
> > +of a type that indicates they might be for data objects. The
> > +@samp{-n} flag excludes non-debugging symbols from the results.
>
> Same here.

Eli,

Thanks for the feedback. I've tried to rewrite things to hopefully
make them clearer. Do feel free to push back if it's still not good
enough.

Tom's comment is also addressed.

Thanks,
Andrew

--

commit ccec24e58bcc7c98ed8d465bed016b049bb02b5b
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 cc1d58520d4..eb97f59a5a0 100644
--- 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.
+
* 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 be65d528d28..2c189a01155 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18527,7 +18527,7 @@
have already been read, and files whose symbols will be read when needed.

@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
@@ -18540,11 +18540,18 @@
language of the function, other values mean to use
the manually specified language (see @ref{Manually, ,Set Language Manually}).

+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.
+
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).

@@ -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.
+
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 96bee7c3b04..bc45d2eb28f 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 959ae652ec2..1f47d032dd8 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -2359,13 +2359,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,
@@ -2472,7 +2535,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);
@@ -3428,14 +3495,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 87a0c8e4da6..1925edeeaa3 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4332,12 +4332,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;
@@ -4553,6 +4557,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 ())
@@ -4699,7 +4704,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)
{
@@ -4715,7 +4720,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)
{
@@ -4768,15 +4774,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);
}

@@ -4786,10 +4864,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. */
@@ -4830,7 +4912,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. */
@@ -4891,7 +4973,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)
@@ -6080,27 +6163,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 9880ecc4c53..4f653bcdc1b 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2037,7 +2037,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);