[PATCH 0/7] Fortran info types, info modules, info module ...

classic Classic list List threaded Threaded
26 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[PATCH 0/7] Fortran info types, info modules, info module ...

Andrew Burgess
A set of patches working toward the goal of adding some new commands
related to Fortran modules.

  #1 - Not Fortran related at all, just adds a new flag to the "info
       functions" and "info variables" commands.

  #2 - In preparation for patch #3.

  #3 - Ensure Fortran variables from modules show up in "info
       variables" output.

  #4 - Fix "info types" for Fortran.

  #5 - We create a symbol for each Fortran module, don't show this in
       the "info types" output.

  #6 - New command "info modules", list all Fortran modules.

  #7 - Two new commands "info module functions" and "info module
       variables", these are like "info functions" and "info variables",
       but with a module twist.

Thanks,
Andrew

---

Andrew Burgess (7):
  gdb: Add new -n flag to some info commands
  gdb: Add an is_declaration field to each symbol
  gdb/fortran: Include module variables in 'info variables' output
  gdb/fortran: Implement la_print_typedef for Fortran
  gdb/fortran: Don't include module symbols when searching for types
  gdb/fortran: Add new 'info modules' command
  gdb: Add new commands to list module variables and functions

 gdb/ChangeLog                              |  90 ++++++
 gdb/NEWS                                   |  24 ++
 gdb/cli/cli-utils.c                        |  65 +---
 gdb/cli/cli-utils.h                        |  39 +--
 gdb/doc/ChangeLog                          |  14 +
 gdb/doc/gdb.texinfo                        |  66 +++-
 gdb/dwarf2read.c                           |  11 +
 gdb/f-lang.c                               |   2 +-
 gdb/f-lang.h                               |   5 +
 gdb/f-typeprint.c                          |  11 +
 gdb/psymtab.c                              |   2 +
 gdb/python/python.c                        |   4 +-
 gdb/stack.c                                |  77 ++++-
 gdb/symtab.c                               | 471 +++++++++++++++++++++++++++--
 gdb/symtab.h                               |  12 +-
 gdb/testsuite/ChangeLog                    |  39 +++
 gdb/testsuite/gdb.base/info-fun.exp        |  97 +++---
 gdb/testsuite/gdb.base/info-var-f1.c       |  24 ++
 gdb/testsuite/gdb.base/info-var-f2.c       |  26 ++
 gdb/testsuite/gdb.base/info-var.exp        |  60 ++++
 gdb/testsuite/gdb.base/info-var.h          |  18 ++
 gdb/testsuite/gdb.fortran/info-modules.exp | 180 +++++++++++
 gdb/testsuite/gdb.fortran/info-types.exp   |  49 +++
 gdb/testsuite/gdb.fortran/info-types.f90   |  72 +++++
 gdb/testsuite/gdb.fortran/module.exp       |  24 ++
 gdb/testsuite/lib/fortran.exp              |  12 +
 26 files changed, 1323 insertions(+), 171 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/info-var-f1.c
 create mode 100644 gdb/testsuite/gdb.base/info-var-f2.c
 create mode 100644 gdb/testsuite/gdb.base/info-var.exp
 create mode 100644 gdb/testsuite/gdb.base/info-var.h
 create mode 100644 gdb/testsuite/gdb.fortran/info-modules.exp
 create mode 100644 gdb/testsuite/gdb.fortran/info-types.exp
 create mode 100644 gdb/testsuite/gdb.fortran/info-types.f90

--
2.14.5

Reply | Threaded
Open this post in threaded view
|

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

Andrew Burgess
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.
---
 gdb/ChangeLog                        |  43 +++++++++++++
 gdb/NEWS                             |   4 ++
 gdb/cli/cli-utils.c                  |  65 ++-----------------
 gdb/cli/cli-utils.h                  |  39 ++----------
 gdb/doc/ChangeLog                    |   5 ++
 gdb/doc/gdb.texinfo                  |  16 +++--
 gdb/python/python.c                  |   4 +-
 gdb/stack.c                          |  77 ++++++++++++++++++++--
 gdb/symtab.c                         | 120 ++++++++++++++++++++++++++++++-----
 gdb/symtab.h                         |   3 +-
 gdb/testsuite/ChangeLog              |   9 +++
 gdb/testsuite/gdb.base/info-fun.exp  |  97 +++++++++++++++-------------
 gdb/testsuite/gdb.base/info-var-f1.c |  24 +++++++
 gdb/testsuite/gdb.base/info-var-f2.c |  26 ++++++++
 gdb/testsuite/gdb.base/info-var.exp  |  60 ++++++++++++++++++
 gdb/testsuite/gdb.base/info-var.h    |  18 ++++++
 16 files changed, 446 insertions(+), 164 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/info-var-f1.c
 create mode 100644 gdb/testsuite/gdb.base/info-var-f2.c
 create mode 100644 gdb/testsuite/gdb.base/info-var.exp
 create mode 100644 gdb/testsuite/gdb.base/info-var.h

diff --git a/gdb/NEWS b/gdb/NEWS
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.
+
 * 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..c0a13037b37 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..c7f7abd9e87 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,15 @@
 language of the function, 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 executable code.  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 +18578,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 +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.
+
 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);
--
2.14.5

Reply | Threaded
Open this post in threaded view
|

[PATCH 2/7] gdb: Add an is_declaration field to each symbol

Andrew Burgess
In reply to this post by Andrew Burgess
This commit is in preparation for a later commit, there should be no
user visible change after this commit.

Track if a symbol is a declaration or not.  At one point we could
possibly figure this out based on the LOC_UNRESOLVED address class of
the symbol, but, for Fortran we mark some symbols as LOC_UNRESOLVED
even when the DWARF supplies an address, this is because the address
supplied by the DWARF is actually wrong.  For details look in
dwarf2read.c and look for references to gFortran bug #40040.  I have
confirmed that current versions of gFortran still have the issue
mentioned in that bug report.

I considered two possible solutions to this problem, one was to add a
new address class, something like:
    LOC_UNRESOLVED_BUT_IS_STILL_A_DEFINITION
that I could use specifically for marking these "broken" Fortran
symbols.  My concern here is that every place LOC_UNRESOLVED is
mentioned would need to be possibly edited to also handle the new
address class, and any future change that mentions LOC_UNRESOLVED
would be a possible source of Fortran bugs due to not handling the new
address class correctly.

So, the solution I took was to add a new single bit flag to the symbol
to track if the symbol is a declaration or not.  There are already
some 1 bit flags in the symbol object, and on x86-64 GNU/Linux (at
least for me) adding one additional flag didn't increase the size of
the symbol object at all.

gdb/ChangeLog:

        * dwarf2read.c (new_symbol): Mark symbol as declaration when
        appropriate.
        * symtab.h (struct symbol): Add 'is_declaration' flag.
        (SYMBOL_IS_DECLARATION): Define.
---
 gdb/ChangeLog    | 7 +++++++
 gdb/dwarf2read.c | 3 +++
 gdb/symtab.h     | 4 ++++
 3 files changed, 14 insertions(+)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 3d90d632891..01cab752888 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -21503,6 +21503,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
    dwarf2_full_name (name, die, cu),
                            NULL);
 
+      if (die_is_declaration (die, cu))
+ SYMBOL_IS_DECLARATION (sym) = 1;
+
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 4f653bcdc1b..c4fd520e735 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1110,6 +1110,9 @@ struct symbol
   /* Whether this is an inlined function (class LOC_BLOCK only).  */
   unsigned is_inlined : 1;
 
+  /* Is this symbol a declaration?  */
+  unsigned is_declaration : 1;
+
   /* The concrete type of this symbol.  */
 
   ENUM_BITFIELD (symbol_subclass_kind) subclass : 2;
@@ -1171,6 +1174,7 @@ extern const struct symbol_impl *symbol_impls;
 #define SYMBOL_INLINED(symbol) (symbol)->is_inlined
 #define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \
   (((symbol)->subclass) == SYMBOL_TEMPLATE)
+#define SYMBOL_IS_DECLARATION(symbol) (symbol)->is_declaration
 #define SYMBOL_TYPE(symbol) (symbol)->type
 #define SYMBOL_LINE(symbol) (symbol)->line
 #define SYMBOL_COMPUTED_OPS(symbol) (SYMBOL_IMPL (symbol).ops_computed)
--
2.14.5

Reply | Threaded
Open this post in threaded view
|

[PATCH 3/7] gdb/fortran: Include module variables in 'info variables' output

Andrew Burgess
In reply to this post by Andrew Burgess
Due to a work around in dwarf2read.c for gFortran issue #40040,
non-constant module variables don't show up in 'info variables'
output.

The reason is that issue #40040 means that the debug symbol definition
for these module variables can sometimes have the incorrect location
information attached to it.  The work around in GDB is to ignore the
location information from the debug information, and mark these
symbols as LOC_UNRESOLVED, GDB will then fall back to using the
non-debug symbols in order to figure out the location of these
symbols.

The problem with this is that GDB uses LOC_UNRESOLVED to indicate a
variable declaration, and doesn't include such symbols in its output.

In an earlier commit I extended each symbol to now explicitly track if
it is marked as a declaration in the DWARF, so GDB can now use this
information rather than LOC_UNRESOLVED to exclude declarations from
the 'info variables' output.

You might think that we could just switch from checking:

  SYMBOL_CLASS (sym) != LOC_UNRESOLVED

to checking:

  !SYMBOL_IS_DECLARATION (sym)

However, this is not good enough, often in C or C++ the declaration is
_also_ the definition, in which case the symbol will be marked as a
declaration, but will _not_ be of address class LOC_UNRESOLVED.  The
correct condition then is that we shouldn't show declarations that are
of class LOC_UNRESOLVED.  The preserves the existing C/C++ behaviour
in every case I've tried so far, and also fixes the gFortran issues
that I was seeing.

gdb/ChangeLog:

        * dwarf2read.c (new_symbol): Mark symbol as declaration when
        appropriate.
        * symtab.h (struct symbol): Add 'is_declaration' flag.
        (SYMBOL_IS_DECLARATION): Define.

gdb/testsuite/ChangeLog:

        * gdb.fortran/module.exp: Extend with 'info variables' test.
---
 gdb/symtab.c                         |  3 ++-
 gdb/testsuite/ChangeLog              |  4 ++++
 gdb/testsuite/gdb.fortran/module.exp | 24 ++++++++++++++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/gdb/symtab.c b/gdb/symtab.c
index 1925edeeaa3..84038d15dff 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4520,8 +4520,9 @@ search_symbols (const char *regexp, enum search_domain kind,
    || preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
   NULL, 0) == 0)
   && ((kind == VARIABLES_DOMAIN
+       && !(SYMBOL_CLASS (sym) == LOC_UNRESOLVED
+    && SYMBOL_IS_DECLARATION (sym))
        && SYMBOL_CLASS (sym) != LOC_TYPEDEF
-       && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
        && SYMBOL_CLASS (sym) != LOC_BLOCK
        /* LOC_CONST can be used for more than
   just enums, e.g., c++ static const
diff --git a/gdb/testsuite/gdb.fortran/module.exp b/gdb/testsuite/gdb.fortran/module.exp
index 4d71e7efac5..276f7dc3c24 100644
--- a/gdb/testsuite/gdb.fortran/module.exp
+++ b/gdb/testsuite/gdb.fortran/module.exp
@@ -13,6 +13,8 @@
 # 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 "fortran.exp"
+
 standard_testfile .f90
 
 if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}] } {
@@ -32,6 +34,28 @@ if ![runto MAIN__] then {
     continue
 }
 
+set int_type [fortran_int4]
+
+# Test 'info variables' can find module variables.
+gdb_test "info variables -n" \
+    [multi_line \
+ "All defined variables:" \
+ "" \
+ "File .*$srcfile:" \
+ "18:\[ \t\]+${int_type} mod1::var_const;" \
+ "17:\[ \t\]+${int_type} mod1::var_i;" \
+ "23:\[ \t\]+${int_type} mod2::var_i;" \
+ "28:\[ \t\]+${int_type} mod3::mod1;" \
+ "27:\[ \t\]+${int_type} mod3::mod2;" \
+ "29:\[ \t\]+${int_type} mod3::var_i;" \
+ "33:\[ \t\]+${int_type} modmany::var_a;" \
+ "33:\[ \t\]+${int_type} modmany::var_b;" \
+ "33:\[ \t\]+${int_type} modmany::var_c;" \
+ "33:\[ \t\]+${int_type} modmany::var_i;" \
+ "37:\[ \t\]+${int_type} moduse::var_x;" \
+ "37:\[ \t\]+${int_type} moduse::var_y;" ]
+
+
 # Do not use simple single-letter names as GDB would pick up for expectedly
 # nonexisting symbols some static variables from system libraries debuginfos.
 
--
2.14.5

Reply | Threaded
Open this post in threaded view
|

[PATCH 4/7] gdb/fortran: Implement la_print_typedef for Fortran

Andrew Burgess
In reply to this post by Andrew Burgess
Implement an la_print_typedef method for Fortran, this allows 'info
types' to work for Fortran.  The implementation is just copied from
ada_print_typedef (with the appropriate changes).

To support the testing of this patch I added a new proc,
fortran_character1, to lib/fortran.exp which returns a regexp to match
a 1-byte character type.  The regexp returned is correct for current
versions of gFortran.  All of the other regexp are guesses based on
all of the other support procs in lib/fortran.exp, I haven't tested
them myself.

gdb/ChangeLog:

        * f-lang.c (f_language_defn): Use f_print_typedef.
        * f-lang.h (f_print_typedef): Declare.
        * f-typeprint.c (f_print_typedef): Define.

gdb/testsuite/ChangeLog:

        * gdb.fortran/info-types.exp: New file.
        * gdb.fortran/info-types.f90: New file.
        * lib/fortran.exp (fortran_character1): New proc.
---
 gdb/ChangeLog                            |  6 +++++
 gdb/f-lang.c                             |  2 +-
 gdb/f-lang.h                             |  5 ++++
 gdb/f-typeprint.c                        | 11 ++++++++
 gdb/testsuite/ChangeLog                  |  6 +++++
 gdb/testsuite/gdb.fortran/info-types.exp | 45 ++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/info-types.f90 | 25 ++++++++++++++++++
 gdb/testsuite/lib/fortran.exp            | 12 +++++++++
 8 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 gdb/testsuite/gdb.fortran/info-types.exp
 create mode 100644 gdb/testsuite/gdb.fortran/info-types.f90

diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index e93a5f34276..ce7f1471c52 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -644,7 +644,7 @@ extern const struct language_defn f_language_defn =
   f_printstr, /* function to print string constant */
   f_emit_char, /* Function to print a single character */
   f_print_type, /* Print a type using appropriate syntax */
-  default_print_typedef, /* Print a typedef using appropriate syntax */
+  f_print_typedef, /* Print a typedef using appropriate syntax */
   f_val_print, /* Print a value using appropriate syntax */
   c_value_print, /* FIXME */
   default_read_var_value, /* la_read_var_value */
diff --git a/gdb/f-lang.h b/gdb/f-lang.h
index 1ba529d76c5..cf6024c4454 100644
--- a/gdb/f-lang.h
+++ b/gdb/f-lang.h
@@ -28,6 +28,11 @@ struct parser_state;
 
 extern int f_parse (struct parser_state *);
 
+/* Implement the la_print_typedef language method for Fortran.  */
+
+extern void f_print_typedef (struct type *type, struct symbol *new_symbol,
+     struct ui_file *stream);
+
 extern void f_print_type (struct type *, const char *, struct ui_file *, int,
   int, const struct type_print_options *);
 
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 17ac02f4ccf..92b50938740 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -45,6 +45,17 @@ void f_type_print_varspec_prefix (struct type *, struct ui_file *,
 void f_type_print_base (struct type *, struct ui_file *, int, int);
 
 
+/* See documentation in f-lang.h.  */
+
+void
+f_print_typedef (struct type *type, struct symbol *new_symbol,
+ struct ui_file *stream)
+{
+  type = check_typedef (type);
+  f_print_type (type, "", stream, 0, 0, &type_print_raw_options);
+  fprintf_filtered (stream, "\n");
+}
+
 /* LEVEL is the depth to indent lines by.  */
 
 void
diff --git a/gdb/testsuite/gdb.fortran/info-types.exp b/gdb/testsuite/gdb.fortran/info-types.exp
new file mode 100644
index 00000000000..9571dc45593
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/info-types.exp
@@ -0,0 +1,45 @@
+# 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/>.
+
+# This file tests 'info types' for some Fortran types.
+
+load_lib "fortran.exp"
+
+if { [skip_fortran_tests] } { continue }
+
+standard_testfile .f90
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}] } {
+    return -1
+}
+
+if { ![runto MAIN__] } {
+    perror "Could not run to breakpoint `MAIN__'."
+    continue
+}
+
+set integer4 [fortran_int4]
+set logical4 [fortran_logical4]
+set character1 [fortran_character1]
+
+gdb_test "info types" \
+    [multi_line \
+ "All defined types:" \
+ "" \
+ "File .*:" \
+ "\[\t \]+${character1}" \
+ "\[\t \]+${integer4}" \
+ "\[\t \]+${logical4}" \
+ "16:\[\t \]+Type s1;" ]
diff --git a/gdb/testsuite/gdb.fortran/info-types.f90 b/gdb/testsuite/gdb.fortran/info-types.f90
new file mode 100644
index 00000000000..21c9d9df63c
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/info-types.f90
@@ -0,0 +1,25 @@
+! 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 2 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/>.
+
+program info_types_test
+  type :: s1
+     integer :: a
+  end type s1
+
+  logical :: l
+  type (s1) :: var_a
+  var_a%a = 1
+  l = .FALSE.
+end program info_types_test
diff --git a/gdb/testsuite/lib/fortran.exp b/gdb/testsuite/lib/fortran.exp
index d3a35cd291e..81811dbc3c9 100644
--- a/gdb/testsuite/lib/fortran.exp
+++ b/gdb/testsuite/lib/fortran.exp
@@ -88,3 +88,15 @@ proc fortran_logical4 {} {
  return "unknown"
     }
 }
+
+proc fortran_character1 {} {
+    if {[test_compiler_info {gcc-4-[012]-*}]} {
+ return "character1"
+    } elseif {[test_compiler_info {gcc-*}]} {
+ return "character\\(kind=1\\)"
+    } elseif {[test_compiler_info {icc-*}]} {
+ return "CHARACTER\\(1\\)"
+    } else {
+ return "unknown"
+    }
+}
--
2.14.5

Reply | Threaded
Open this post in threaded view
|

[PATCH 5/7] gdb/fortran: Don't include module symbols when searching for types

Andrew Burgess
In reply to this post by Andrew Burgess
Currently the 'info types' command will return symbols that correspond
to Fortran modules.  This because the symbols are created with domain
MODULE_DOMAIN, but address_class LOC_TYPEDEF, which is the same
address_class as type symbols.

This commit explicitly prevents MODULE_DOMAIN symbols from appearing
when we search for symbols in the TYPES_DOMAIN, this prevents the
module symbols from appearing in the output of 'info types'.

gdb/ChangeLog:

        * symtab.c (search_symbols): Don't include MODULE_DOMAIN symbols
        when searching for types.

gdb/testsuite/ChangeLog:

        * gdb.fortran/info-types.exp: Add module.
        * gdb.fortran/info-types.f90: Update expected results.
---
 gdb/ChangeLog                            |  5 +++++
 gdb/symtab.c                             |  3 ++-
 gdb/testsuite/ChangeLog                  |  5 +++++
 gdb/testsuite/gdb.fortran/info-types.exp |  4 +++-
 gdb/testsuite/gdb.fortran/info-types.f90 | 11 +++++++++++
 5 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/gdb/symtab.c b/gdb/symtab.c
index 84038d15dff..d3a209608b7 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4539,7 +4539,8 @@ search_symbols (const char *regexp, enum search_domain kind,
       || treg_matches_sym_type_name (*treg,
      sym)))
       || (kind == TYPES_DOMAIN
-  && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
+  && SYMBOL_CLASS (sym) == LOC_TYPEDEF
+  && SYMBOL_DOMAIN (sym) != MODULE_DOMAIN))))
     {
       /* match */
       result.emplace_back (i, sym);
diff --git a/gdb/testsuite/gdb.fortran/info-types.exp b/gdb/testsuite/gdb.fortran/info-types.exp
index 9571dc45593..81e67395e8a 100644
--- a/gdb/testsuite/gdb.fortran/info-types.exp
+++ b/gdb/testsuite/gdb.fortran/info-types.exp
@@ -42,4 +42,6 @@ gdb_test "info types" \
  "\[\t \]+${character1}" \
  "\[\t \]+${integer4}" \
  "\[\t \]+${logical4}" \
- "16:\[\t \]+Type s1;" ]
+ "20:\[\t \]+Type __vtype_mod1_M1t1;" \
+ "17:\[\t \]+Type m1t1;" \
+ "22:\[\t \]+Type s1;" ]
diff --git a/gdb/testsuite/gdb.fortran/info-types.f90 b/gdb/testsuite/gdb.fortran/info-types.f90
index 21c9d9df63c..0e27e1ddf08 100644
--- a/gdb/testsuite/gdb.fortran/info-types.f90
+++ b/gdb/testsuite/gdb.fortran/info-types.f90
@@ -13,13 +13,24 @@
 ! You should have received a copy of the GNU General Public License
 ! along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+module mod1
+  type :: m1t1
+     integer :: b
+  end type m1t1
+end module mod1
+
 program info_types_test
+  use mod1
+
   type :: s1
      integer :: a
   end type s1
 
   logical :: l
   type (s1) :: var_a
+  type (m1t1) :: var_b
+
   var_a%a = 1
+  var_b%b = 2
   l = .FALSE.
 end program info_types_test
--
2.14.5

Reply | Threaded
Open this post in threaded view
|

[PATCH 6/7] gdb/fortran: Add new 'info modules' command

Andrew Burgess
In reply to this post by Andrew Burgess
Add a new command 'info modules' that lists all of the modules GDB
knows about from the debug information.

A module is a debugging entity in the DWARF defined with
DW_TAG_module, currently Fortran is known to use this tag for its
modules.  I'm not aware of any other language that currently makes use
of DW_TAG_module.

The output style is similar to the 'info type' output:

    (gdb) info modules
    All defined modules:

    File info-types.f90:
    16:     mod1
    24:     mod2
    (gdb)

Where the user is told the file the module is defined in and, on the
left hand side, the line number at which the module is defined along
with the name of the module.

This patch is a new implementation of an idea originally worked on by
Mark O'Connor, Chris January, David Lecomber, and Xavier Oro from ARM.

gdb/ChangeLog:

        * dwarf2read.c (dw2_debug_names_iterator::next): Handle
        MODULES_DOMAIN.
        * psymtab.c (recursively_search_psymtabs): Likewise.
        * symtab.c (search_domain_name): Likewise.
        (search_symbols): Likewise.
        (print_symbol_info): Likewise.
        (symtab_symbol_info): Likewise.
        (info_modules_command): New function.
        (_initialize_symtab): Register 'info modules' command.
        * symtab.h (enum search_domain): Add MODULES_DOMAIN.
        * NEWS: Mention new 'info modules' command.

gdb/doc/ChangeLog:

        * gdb.texinfo (Symbols): Document new 'info modules' command.

gdb/testsuite/ChangeLog:

        * gdb.fortran/info-modules.exp: New file.
        * gdb.fortran/info-types.exp: Update expected results.
        * gdb.fortran/info-types.f90: Extend with extra module.
---
 gdb/ChangeLog                              | 14 +++++++
 gdb/NEWS                                   |  6 +++
 gdb/doc/ChangeLog                          |  4 ++
 gdb/doc/gdb.texinfo                        | 16 ++++++++
 gdb/dwarf2read.c                           |  8 ++++
 gdb/psymtab.c                              |  2 +
 gdb/symtab.c                               | 36 ++++++++++++++++--
 gdb/symtab.h                               |  5 ++-
 gdb/testsuite/ChangeLog                    |  6 +++
 gdb/testsuite/gdb.fortran/info-modules.exp | 61 ++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/info-types.exp   |  2 +-
 gdb/testsuite/gdb.fortran/info-types.f90   |  5 +++
 12 files changed, 159 insertions(+), 6 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/info-modules.exp

diff --git a/gdb/NEWS b/gdb/NEWS
index 40b56727227..14c931602f4 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -104,6 +104,12 @@ maint show test-settings KIND
   A set of commands used by the testsuite for exercising the settings
   infrastructure.
 
+info modules [-q] [REGEXP]
+  Return a list of modules matching REGEXP, or all modules if no
+  REGEXP is given.  Only languages that generate DW_TAG_module in
+  their DWARF (for example Fortran) will give any results for this
+  command.
+
 * Changed commands
 
 help
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index c7f7abd9e87..71ee20f29d5 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18617,6 +18617,22 @@
 is printed only if its name matches @var{regexp} and its type matches
 @var{type_regexp}.
 
+@kindex info modules
+@cindex modules
+@item info modules [-q] [@var{regexp}]
+List all modules for which there is debugging information available.
+Modules are identified by @code{DW_TAG_module} in DWARF debugging
+information, only languages that use this tag will list modules with
+this command.  Currently Fortran is known to generate module
+information in its debug.
+
+If the optional @var{regexp} is provided then only modules whose name
+matches @var{regexp} will be listed.
+
+The optional flag @samp{-q}, which stands for @samp{quiet}, disables
+printing header information and messages explaining why no functions
+have been printed.
+
 @kindex info classes
 @cindex Objective-C, classes and selectors
 @item info classes
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 01cab752888..00012877da1 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -6004,6 +6004,14 @@ dw2_debug_names_iterator::next ()
   goto again;
  }
       break;
+    case MODULES_DOMAIN:
+      switch (indexval.dwarf_tag)
+ {
+ case DW_TAG_module:
+  break;
+ default:
+  goto again;
+ }
     default:
       break;
     }
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 6cc7566580a..95615e30f68 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1301,6 +1301,8 @@ recursively_search_psymtabs
   QUIT;
 
   if ((domain == ALL_DOMAIN
+       || (domain == MODULES_DOMAIN
+   && (*psym)->domain == MODULE_DOMAIN)
        || (domain == VARIABLES_DOMAIN
    && (*psym)->aclass != LOC_TYPEDEF
    && (*psym)->aclass != LOC_BLOCK)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index d3a209608b7..793be13ab9d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -297,6 +297,7 @@ search_domain_name (enum search_domain e)
     case VARIABLES_DOMAIN: return "VARIABLES_DOMAIN";
     case FUNCTIONS_DOMAIN: return "FUNCTIONS_DOMAIN";
     case TYPES_DOMAIN: return "TYPES_DOMAIN";
+    case MODULES_DOMAIN: return "MODULES_DOMAIN";
     case ALL_DOMAIN: return "ALL_DOMAIN";
     default: gdb_assert_not_reached ("bad search_domain");
     }
@@ -4365,7 +4366,7 @@ search_symbols (const char *regexp, enum search_domain kind,
   gdb::optional<compiled_regex> preg;
   gdb::optional<compiled_regex> treg;
 
-  gdb_assert (kind <= TYPES_DOMAIN);
+  gdb_assert (kind <= MODULES_DOMAIN);
 
   ourtype = types[kind];
   ourtype2 = types2[kind];
@@ -4540,7 +4541,9 @@ search_symbols (const char *regexp, enum search_domain kind,
      sym)))
       || (kind == TYPES_DOMAIN
   && SYMBOL_CLASS (sym) == LOC_TYPEDEF
-  && SYMBOL_DOMAIN (sym) != MODULE_DOMAIN))))
+  && SYMBOL_DOMAIN (sym) != MODULE_DOMAIN)
+      || (kind == MODULES_DOMAIN
+  && SYMBOL_DOMAIN (sym) == MODULE_DOMAIN))))
     {
       /* match */
       result.emplace_back (i, sym);
@@ -4671,6 +4674,11 @@ print_symbol_info (enum search_domain kind,
 
       printf_filtered (";\n");
     }
+  /* Printing of modules is currently done here, maybe at some future
+     point we might want a language specific method to print the module
+     symbol so that we can customise the output more.  */
+  else if (kind == MODULES_DOMAIN)
+    printf_filtered ("%s\n", SYMBOL_PRINT_NAME (sym));
 }
 
 /* This help function for symtab_symbol_info() prints information
@@ -4711,11 +4719,11 @@ symtab_symbol_info (bool quiet, bool exclude_minsyms,
     const char *t_regexp, int from_tty)
 {
   static const char * const classnames[] =
-    {"variable", "function", "type"};
+    {"variable", "function", "type", "module"};
   const char *last_filename = "";
   int first = 1;
 
-  gdb_assert (kind <= TYPES_DOMAIN);
+  gdb_assert (kind <= MODULES_DOMAIN);
 
   if (regexp != nullptr && *regexp == '\0')
     regexp = nullptr;
@@ -4934,6 +4942,22 @@ info_types_command_completer (struct cmd_list_element *ignore,
   symbol_completer (ignore, tracker, text, word);
 }
 
+/* Implement the 'info modules' command.  */
+
+static void
+info_modules_command (const char *args, int from_tty)
+{
+  info_types_options opts;
+
+  auto grp = make_info_types_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, true, args, MODULES_DOMAIN, NULL,
+      from_tty);
+}
+
 /* Breakpoint all functions matching regular expression.  */
 
 void
@@ -6198,6 +6222,10 @@ Print information about all types matching REGEXP, or all types if no\n\
 REGEXP is given.  The optional flag -q disables printing of headers."));
   set_cmd_completer_handle_brkchars (c, info_types_command_completer);
 
+  c = add_info ("modules", info_modules_command,
+ _("All module names, or those matching REGEXP."));
+  set_cmd_completer_handle_brkchars (c, info_types_command_completer);
+
   add_info ("sources", info_sources_command,
     _("Source files in the program."));
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index c4fd520e735..6e8bca0a86a 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -799,8 +799,11 @@ enum search_domain
   /* All defined types */
   TYPES_DOMAIN = 2,
 
+  /* All modules.  */
+  MODULES_DOMAIN = 3,
+
   /* Any type.  */
-  ALL_DOMAIN = 3
+  ALL_DOMAIN = 4
 };
 
 extern const char *search_domain_name (enum search_domain);
diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp
new file mode 100644
index 00000000000..33110236271
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/info-modules.exp
@@ -0,0 +1,61 @@
+# 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/>.
+
+# This file tests 'info modules'.
+
+load_lib "fortran.exp"
+
+if { [skip_fortran_tests] } { continue }
+
+standard_testfile info-types.f90
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}] } {
+    return -1
+}
+
+if { ![runto MAIN__] } {
+    perror "Could not run to breakpoint `MAIN__'."
+    continue
+}
+
+gdb_test "info modules" \
+    [multi_line \
+ "All defined modules:" \
+ "" \
+ "File .*:" \
+ "16:\[\t \]+mod1" \
+ "22:\[\t \]+mod2" ]
+
+gdb_test "info modules 1" \
+    [multi_line \
+ "All modules matching regular expression \"1\":" \
+ "" \
+ "File .*:" \
+ "16:\[\t \]+mod1" ]
+
+gdb_test "info modules 2" \
+    [multi_line \
+ "All modules matching regular expression \"2\":" \
+ "" \
+ "File .*:" \
+ "22:\[\t \]+mod2" ]
+
+gdb_test "info modules mod" \
+    [multi_line \
+ "All modules matching regular expression \"mod\":" \
+ "" \
+ "File .*:" \
+ "16:\[\t \]+mod1" \
+ "22:\[\t \]+mod2" ]
diff --git a/gdb/testsuite/gdb.fortran/info-types.exp b/gdb/testsuite/gdb.fortran/info-types.exp
index 81e67395e8a..b0656bce2b7 100644
--- a/gdb/testsuite/gdb.fortran/info-types.exp
+++ b/gdb/testsuite/gdb.fortran/info-types.exp
@@ -44,4 +44,4 @@ gdb_test "info types" \
  "\[\t \]+${logical4}" \
  "20:\[\t \]+Type __vtype_mod1_M1t1;" \
  "17:\[\t \]+Type m1t1;" \
- "22:\[\t \]+Type s1;" ]
+ "26:\[\t \]+Type s1;" ]
diff --git a/gdb/testsuite/gdb.fortran/info-types.f90 b/gdb/testsuite/gdb.fortran/info-types.f90
index 0e27e1ddf08..859a9485c8f 100644
--- a/gdb/testsuite/gdb.fortran/info-types.f90
+++ b/gdb/testsuite/gdb.fortran/info-types.f90
@@ -19,8 +19,13 @@ module mod1
   end type m1t1
 end module mod1
 
+module mod2
+  integer :: mod2_var_1 = 123
+end module mod2
+
 program info_types_test
   use mod1
+  use mod2
 
   type :: s1
      integer :: a
--
2.14.5

Reply | Threaded
Open this post in threaded view
|

[PATCH 7/7] gdb: Add new commands to list module variables and functions

Andrew Burgess
In reply to this post by Andrew Burgess
This patch adds two new commands "info module functions" and "info
module variables".  These commands list all of the functions and
variables grouped by module and then by file.

For example:

  (gdb) info module functions
  All functions in all modules:

  Module "mod1":

  File /some/path/gdb/testsuite/gdb.fortran/info-types.f90:
  35: void mod1::__copy_mod1_M1t1(Type m1t1, Type m1t1);
  25: void mod1::sub_m1_a(integer(kind=4));
  31: integer(kind=4) mod1::sub_m1_b(void);

  Module "mod2":

  File /some/path/gdb/testsuite/gdb.fortran/info-types.f90:
  41: void mod2::sub_m2_a(integer(kind=4), logical(kind=4));
  49: logical(kind=4) mod2::sub_m2_b(real(kind=4));

The new commands take set of flags that allow the output to be
filtered, the user can filter by variable/function name, type, or
containing module.

As GDB doesn't currently track the relationship between a module and
the variables or functions within it in the symbol table, so I filter
based on the module prefix in order to find the functions or variables
in each module.  What this makes clear is that a user could get this
same information using "info variables" and simply provide the prefix
themselves, for example:

  (gdb) info module functions -m mod1 _a
  All functions matching regular expression "_a",
  in all modules matching regular expression "mod1":

  Module "mod1":

  File /some/path/gdb/testsuite/gdb.fortran/info-types.f90:
  25: void mod1::sub_m1_a(integer(kind=4));

Is similar to:

  (gdb) info functions mod1::.*_a.*
  All functions matching regular expression "mod1::.*_a":

  File /some/path/gdb/testsuite/gdb.fortran/info-types.f90:
  25: void mod1::sub_m1_a(integer(kind=4));

The benefits I see for a separate command are that the user doesn't
have to think (or know) about the module prefix format, nor worry
about building a proper regexp.  The user can also easily can across
modules without having to build complex regexps.

This patch is a new implementation of an idea originally worked on by
Mark O'Connor, Chris January, David Lecomber, and Xavier Oro from ARM.

gdb/ChangeLog:

        * symtab.c (info_module_cmdlist): New variable.
        (info_module_command): New function.
        (info_module_subcommand_helper): New function.
        (struct info_modules_var_func_options): New struct.
        (info_modules_var_func_options_defs): New variable.
        (make_info_modules_var_func_options_def_group): New function.
        (info_module_functions_command): New function.
        (info_module_variables_command): New function.
        (info_module_var_func_command_completer): New function.
        (_initialize_symtab): Register new 'info module functions' and
        'info module variables' commands.
        * NEWS: Mention new commands.

gdb/doc/ChangeLog:

        * gdb.texinfo (Symbols): Document new 'info module variables' and
        'info module functions' commands.

gdb/testsuite/ChangeLog:

        * gdb.fortran/info-modules.exp: Update expected results, and add
        additional tests for 'info module functinos', and 'info module
        variables'.
        * gdb.fortran/info-types.exp: Update expected results.
        * gdb.fortran/info-types.f90: Extend testcase with additional
        module variables and functions.
---
 gdb/ChangeLog                              |  15 ++
 gdb/NEWS                                   |  14 ++
 gdb/doc/ChangeLog                          |   5 +
 gdb/doc/gdb.texinfo                        |  34 ++++
 gdb/symtab.c                               | 311 +++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog                    |   9 +
 gdb/testsuite/gdb.fortran/info-modules.exp | 127 +++++++++++-
 gdb/testsuite/gdb.fortran/info-types.exp   |   6 +-
 gdb/testsuite/gdb.fortran/info-types.f90   |  31 +++
 9 files changed, 546 insertions(+), 6 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index 14c931602f4..9b7e6cc1c71 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -110,6 +110,20 @@ info modules [-q] [REGEXP]
   their DWARF (for example Fortran) will give any results for this
   command.
 
+info module functions [-q] [-m MODULE_REGEXP] [-t TYPE_REGEXP] [REGEXP]
+  Return a list of functions within all modules, grouped by module.
+  The list of functions can be restricted with the optional regular
+  expressions.  MODULE_REGEXP matches against the module name,
+  TYPE_REGEXP matches against the function type signature, and REGEXP
+  matches against the function name.
+
+info module variables [-q] [-m MODULE_REGEXP] [-t TYPE_REGEXP] [REGEXP]
+  Return a list of variables within all modules, grouped by module.
+  The list of variables can be restricted with the optional regular
+  expressions.  MODULE_REGEXP matches against the module name,
+  TYPE_REGEXP matches against the variable type, and REGEXP matches
+  against the variable name.
+
 * Changed commands
 
 help
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 71ee20f29d5..5ba07253d6c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18633,6 +18633,40 @@
 printing header information and messages explaining why no functions
 have been printed.
 
+@kindex info module functions
+@cindex modules
+@cindex functions
+@cindex module functions
+@item info module functions [-q] [-m @var{module-regexp}] [-t @var{type-regexp}] [@var{regexp}]
+List all functions within all modules.  The set of functions listed
+can be limited by providing some or all of the optional regular
+expressions.  If @var{module-regexp} is provided, then only modules
+matching @var{module-regexp} will be searched.  Only functions whose
+type matches the optional regular expression @var{type-regexp} will be
+listed.  And only functions whose name matches the optional regular
+expression @var{regexp} will be listed.
+
+The optional flag @samp{-q}, which stands for @samp{quiet}, disables
+printing header information and messages explaining why no functions
+have been printed.
+
+@kindex info module variables
+@cindex modules
+@cindex variables
+@cindex module variables
+@item info module variables [-q] [-m @var{module-regexp}] [-t @var{type-regexp}] [@var{regexp}]
+List all variables within all modules.  The set of variables listed
+can be limited by providing some or all of the optional regular
+expressions.  If @var{module-regexp} is provided, then only modules
+matching @var{module-regexp} will be searched.  Only variables whose
+type matches the optional regular expression @var{type-regexp} will be
+listed.  And only variables whose name matches the optional regular
+expression @var{regexp} will be listed.
+
+The optional flag @samp{-q}, which stands for @samp{quiet}, disables
+printing header information and messages explaining why no variables
+have been printed.
+
 @kindex info classes
 @cindex Objective-C, classes and selectors
 @item info classes
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 793be13ab9d..d8c6518bb39 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -6179,6 +6179,278 @@ symbol_set_symtab (struct symbol *symbol, struct symtab *symtab)
 
 
 
+/* Hold the sub-commands of 'info module'.  */
+
+static struct cmd_list_element *info_module_cmdlist = NULL;
+
+/* Implement the 'info module' command, just displays some help text for
+   the available sub-commands.  */
+
+static void
+info_module_command (const char *args, int from_tty)
+{
+  help_list (info_module_cmdlist, "info module ", class_info, gdb_stdout);
+}
+
+/* Implement the core of both 'info module functions' and 'info module
+   variables'.  */
+
+static void
+info_module_subcommand_helper (bool quiet,
+       const char *module_regexp,
+       const char *regexp,
+       const char *type_regexp,
+       search_domain kind)
+{
+  /* Must make sure that if we're interrupted, MODULES gets freed.  */
+  std::vector<symbol_search> modules = search_symbols (module_regexp,
+       MODULES_DOMAIN,
+       NULL, 0, NULL,
+       true);
+
+  /* Print a header line.  Don't build the header line bit by bit as this
+     prevents internationalisation.  */
+  if (!quiet)
+    {
+      if (module_regexp == nullptr)
+ {
+  if(type_regexp == nullptr)
+    {
+      if (regexp == nullptr)
+ printf_filtered ((kind == VARIABLES_DOMAIN
+  ? _("All variables in all modules:")
+  : _("All functions in all modules:")));
+      else
+ printf_filtered
+  ((kind == VARIABLES_DOMAIN
+    ? _("All variables matching regular expression"
+ " \"%s\" in all modules:")
+    : _("All functions matching regular expression"
+ " \"%s\" in all modules:")),
+   regexp);
+    }
+  else
+    {
+      if (regexp == nullptr)
+ printf_filtered
+  ((kind == VARIABLES_DOMAIN
+    ? _("All variables with type matching regular "
+ "expression \"%s\" in all modules:")
+    : _("All functions with type matching regular "
+ "expression \"%s\" in all modules:")),
+   type_regexp);
+      else
+ printf_filtered
+  ((kind == VARIABLES_DOMAIN
+    ? _("All variables matching regular expression "
+ "\"%s\",\n\twith type matching regular "
+ "expression \"%s\" in all modules:")
+    : _("All functions matching regular expression "
+ "\"%s\",\n\twith type matching regular "
+ "expression \"%s\" in all modules:")),
+   regexp, type_regexp);
+    }
+ }
+      else
+ {
+  if(type_regexp == nullptr)
+    {
+      if (regexp == nullptr)
+ printf_filtered
+  ((kind == VARIABLES_DOMAIN
+    ? _("All variables in all modules matching regular "
+ "expression \"%s\":")
+    : _("All functions in all modules matching regular "
+ "expression \"%s\":")),
+   module_regexp);
+      else
+ printf_filtered
+  ((kind == VARIABLES_DOMAIN
+    ? _("All variables matching regular expression "
+ "\"%s\",\n\tin all modules matching regular "
+ "expression \"%s\":")
+    : _("All functions matching regular expression "
+ "\"%s\",\n\tin all modules matching regular "
+ "expression \"%s\":")),
+   regexp, module_regexp);
+    }
+  else
+    {
+      if (regexp == nullptr)
+ printf_filtered
+  ((kind == VARIABLES_DOMAIN
+    ? _("All variables with type matching regular "
+ "expression \"%s\"\n\tin all modules matching "
+ "regular expression \"%s\":")
+    : _("All functions with type matching regular "
+ "expression \"%s\"\n\tin all modules matching "
+ "regular expression \"%s\":")),
+   type_regexp, module_regexp);
+      else
+ printf_filtered
+  ((kind == VARIABLES_DOMAIN
+    ? _("All variables matching regular expression "
+ "\"%s\",\n\twith type matching regular expression "
+ "\"%s\",\n\tin all modules matching regular "
+ "expression \"%s\":")
+    : _("All functions matching regular expression "
+ "\"%s\",\n\twith type matching regular expression "
+ "\"%s\",\n\tin all modules matching regular "
+ "expression \"%s\":")),
+   regexp, type_regexp, module_regexp);
+    }
+ }
+      printf_filtered ("\n");
+    }
+
+  /* Now search for all symbols of the required KIND matching the required
+     regular expressions.  We figure out which ones are in which modules
+     below.  */
+  std::vector<symbol_search> symbols = search_symbols (regexp, kind,
+       type_regexp, 0,
+       NULL, true);
+
+  /* Now iterate over all MODULES, checking to see which items from
+     SYMBOLS are in each module.  */
+  for (const symbol_search &p : modules)
+    {
+      QUIT;
+
+      /* This is a module.  */
+      gdb_assert (p.symbol != nullptr);
+
+      std::string prefix = SYMBOL_PRINT_NAME (p.symbol);
+      prefix += "::";
+
+      bool module_header_printed = false;
+      const char *last_filename = "";
+      for (const symbol_search &q : symbols)
+ {
+  if (q.symbol == nullptr)
+    continue;
+
+  if (strncmp (SYMBOL_PRINT_NAME (q.symbol), prefix.c_str (),
+       prefix.size ()) != 0)
+    continue;
+
+  if (!module_header_printed)
+    {
+      printf_filtered ("\n");
+      printf_filtered (_("Module \"%s\":\n"),
+       SYMBOL_PRINT_NAME (p.symbol));
+      module_header_printed = true;
+    }
+
+  print_symbol_info (FUNCTIONS_DOMAIN, q.symbol, q.block,
+     last_filename);
+  last_filename
+    = symtab_to_filename_for_display (symbol_symtab (q.symbol));
+ }
+    }
+}
+
+/* Hold the option values for the 'info module .....' sub-commands.  */
+
+struct info_modules_var_func_options
+{
+  int quiet = 0;
+  char *type_regexp = nullptr;
+  char *module_regexp = nullptr;
+
+  ~info_modules_var_func_options ()
+  {
+    xfree (type_regexp);
+    xfree (module_regexp);
+  }
+};
+
+/* The options used by 'info module variables' and 'info module functions'
+   commands.  */
+
+static const gdb::option::option_def info_modules_var_func_options_defs [] = {
+  gdb::option::boolean_option_def<info_modules_var_func_options> {
+    "q",
+    [] (info_modules_var_func_options *opt) { return &opt->quiet; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  },
+
+  gdb::option::string_option_def<info_modules_var_func_options> {
+    "t",
+    [] (info_modules_var_func_options *opt) { return &opt->type_regexp; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  },
+
+  gdb::option::string_option_def<info_modules_var_func_options> {
+    "m",
+    [] (info_modules_var_func_options *opt) { return &opt->module_regexp; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  }
+};
+
+/* Return the option group used by the 'info module ...' sub-commands.  */
+
+static inline gdb::option::option_def_group
+make_info_modules_var_func_options_def_group
+ (info_modules_var_func_options *opts)
+{
+  return {{info_modules_var_func_options_defs}, opts};
+}
+
+/* Implements the 'info module functions' command.  */
+
+static void
+info_module_functions_command (const char *args, int from_tty)
+{
+  info_modules_var_func_options opts;
+  auto grp = make_info_modules_var_func_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
+
+  info_module_subcommand_helper (opts.quiet, opts.module_regexp, args,
+ opts.type_regexp, FUNCTIONS_DOMAIN);
+}
+
+/* Implements the 'info module variables' command.  */
+
+static void
+info_module_variables_command (const char *args, int from_tty)
+{
+  info_modules_var_func_options opts;
+  auto grp = make_info_modules_var_func_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
+
+  info_module_subcommand_helper (opts.quiet, opts.module_regexp, args,
+ opts.type_regexp, VARIABLES_DOMAIN);
+}
+
+/* Command completer for 'info module ...' sub-commands.  */
+
+static void
+info_module_var_func_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text,
+ const char * /* word */)
+{
+
+  const auto group = make_info_modules_var_func_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);
+}
+
+
+
 void
 _initialize_symtab (void)
 {
@@ -6226,6 +6498,45 @@ REGEXP is given.  The optional flag -q disables printing of headers."));
  _("All module names, or those matching REGEXP."));
   set_cmd_completer_handle_brkchars (c, info_types_command_completer);
 
+  add_prefix_cmd ("module", class_info, info_module_command, _("\
+Print information about modules."),
+  &info_module_cmdlist, "info module ",
+  0, &infolist);
+
+  c = add_cmd ("functions", class_info, info_module_functions_command, _("\
+Display functions within each module.\n\
+Usage: info module functions [-q] [-m MODREGEXP] [-t TYPEREGEXP] [REGEXP]\n\
+Print a summary of all functions within each module, grouped by module\n\
+and file.  For each function the line on which the function is defined\n\
+is given along with the type signature and name of the function.\n\
+\n\
+If REGEXP is provided then only functions whose name matches REGEXP are\n\
+listed.  If MODREGEXP is provided then only functions in modules matching\n\
+MODREGEXP are listed.  If TYPEREGEXP is given then only functions whose\n\
+type signature matches TYPEREGEXP are listed.\n\
+\n\
+The -q flag suppresses printing some header information."),
+       &info_module_cmdlist);
+  set_cmd_completer_handle_brkchars
+    (c, info_module_var_func_command_completer);
+
+  c = add_cmd ("variables", class_info, info_module_variables_command, _("\
+Display variables within each module.\n\
+Usage: info module variables [-q] [-m MODREGEXP] [-t TYPEREGEXP] [REGEXP]\n\
+Print a summary of all variables within each module, grouped by module\n\
+and file.  For each variable the line on which the variable is defined\n\
+is given along with the type and name of the variable.\n\
+\n\
+If REGEXP is provided then only variables whose name matches REGEXP are\n\
+listed.  If MODREGEXP is provided then only variables in modules matching\n\
+MODREGEXP are listed.  If TYPEREGEXP is given then only variables whose\n\
+type matches TYPEREGEXP are listed.\n\
+\n\
+The -q flag suppresses printing some header information."),
+       &info_module_cmdlist);
+  set_cmd_completer_handle_brkchars
+    (c, info_module_var_func_command_completer);
+
   add_info ("sources", info_sources_command,
     _("Source files in the program."));
 
diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp
index 33110236271..3a39461ffbc 100644
--- a/gdb/testsuite/gdb.fortran/info-modules.exp
+++ b/gdb/testsuite/gdb.fortran/info-modules.exp
@@ -13,7 +13,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-# This file tests 'info modules'.
+# This file tests 'info modules', 'info module functions', and 'info
+# module variables'.
 
 load_lib "fortran.exp"
 
@@ -30,13 +31,18 @@ if { ![runto MAIN__] } {
     continue
 }
 
+set integer4 [fortran_int4]
+set real4 [fortran_real4]
+
+# Test 'info modules' command.
+
 gdb_test "info modules" \
     [multi_line \
  "All defined modules:" \
  "" \
  "File .*:" \
  "16:\[\t \]+mod1" \
- "22:\[\t \]+mod2" ]
+ "37:\[\t \]+mod2" ]
 
 gdb_test "info modules 1" \
     [multi_line \
@@ -50,7 +56,7 @@ gdb_test "info modules 2" \
  "All modules matching regular expression \"2\":" \
  "" \
  "File .*:" \
- "22:\[\t \]+mod2" ]
+ "37:\[\t \]+mod2" ]
 
 gdb_test "info modules mod" \
     [multi_line \
@@ -58,4 +64,117 @@ gdb_test "info modules mod" \
  "" \
  "File .*:" \
  "16:\[\t \]+mod1" \
- "22:\[\t \]+mod2" ]
+ "37:\[\t \]+mod2" ]
+
+# Test 'info module functions'.
+
+gdb_test "info module functions" \
+    [multi_line \
+ "All functions in all modules:" \
+ "" \
+ "Module \"mod1\":" \
+ "" \
+ "File .*:" \
+ "35:\[\t \]+void mod1::__copy_mod1_M1t1\\(Type m1t1, Type m1t1\\);" \
+ "25:\[\t \]+void mod1::sub_m1_a\\(${integer4}\\);" \
+ "31:\[\t \]+${integer4} mod1::sub_m1_b\\(void\\);" \
+ "" \
+ "Module \"mod2\":" \
+ "" \
+ "File .*:" \
+ "41:\[\t \]+void mod2::sub_m2_a\\(${integer4}, ${logical4}\\);" \
+ "49:\[\t \]+${logical4} mod2::sub_m2_b\\(${real4}\\);" ]
+
+gdb_test "info module functions -m mod1" \
+    [multi_line \
+ "All functions in all modules matching regular expression \"mod1\":" \
+ "" \
+ "Module \"mod1\":" \
+ "" \
+ "File .*:" \
+ "35:\[\t \]+void mod1::__copy_mod1_M1t1\\(Type m1t1, Type m1t1\\);" \
+ "25:\[\t \]+void mod1::sub_m1_a\\(${integer4}\\);" \
+ "31:\[\t \]+${integer4} mod1::sub_m1_b\\(void\\);" ]
+
+gdb_test "info module functions -t integer" \
+    [multi_line \
+ "All functions with type matching regular expression \"integer\" in all modules:" \
+ "" \
+ "Module \"mod1\":" \
+ "" \
+ "File .*:" \
+ "25:\[\t \]+void mod1::sub_m1_a\\(${integer4}\\);" \
+ "31:\[\t \]+${integer4} mod1::sub_m1_b\\(void\\);" \
+ "" \
+ "Module \"mod2\":" \
+ "" \
+ "File .*:" \
+ "41:\[\t \]+void mod2::sub_m2_a\\(${integer4}, ${logical4}\\);" ]
+
+# Test 'info module variables'.
+
+gdb_test "info module variables" \
+    [multi_line \
+ "All variables in all modules:" \
+ "" \
+ "Module \"mod1\":" \
+ "" \
+ "File .*:" \
+ "35:\[\t \]+Type m1t1 mod1::__def_init_mod1_M1t1;" \
+ "35:\[\t \]+Type __vtype_mod1_M1t1 mod1::__vtab_mod1_M1t1;" \
+ "21:\[\t \]+${real4} mod1::mod1_var_1;" \
+ "22:\[\t \]+${integer4} mod1::mod1_var_2;" \
+ "" \
+ "Module \"mod2\":" \
+ "" \
+ "File .*:" \
+ "38:\[\t \]+${integer4} mod2::mod2_var_1;" \
+ "39:\[\t \]+${real4} mod2::mod2_var_2;" ]
+
+gdb_test "info module variables -t real" \
+    [multi_line \
+ "All variables with type matching regular expression \"real\" in all modules:" \
+ "" \
+ "Module \"mod1\":" \
+ "" \
+ "File .*:" \
+ "21:\[\t \]+${real4} mod1::mod1_var_1;" \
+ "" \
+ "Module \"mod2\":" \
+ "" \
+ "File .*:" \
+ "39:\[\t \]+${real4} mod2::mod2_var_2;" ]
+
+gdb_test "info module variables -m mod2" \
+    [multi_line \
+ "All variables in all modules matching regular expression \"mod2\":" \
+ "" \
+ "Module \"mod2\":" \
+ "" \
+ "File .*:" \
+ "38:\[\t \]+${integer4} mod2::mod2_var_1;" \
+ "39:\[\t \]+${real4} mod2::mod2_var_2;" ]
+
+gdb_test "info module variables -m mod2 -t real" \
+    [multi_line \
+ "All variables with type matching regular expression \"real\"" \
+ " in all modules matching regular expression \"mod2\":" \
+ "" \
+ "Module \"mod2\":" \
+ "" \
+ "File .*:" \
+ "39:\[\t \]+${real4} mod2::mod2_var_2;" ]
+
+gdb_test "info module variables _1" \
+    [multi_line \
+ "All variables matching regular expression \"_1\" in all modules:" \
+ "" \
+ "Module \"mod1\":" \
+ "" \
+ "File .*:" \
+ "21:\[\t \]+${real4} mod1::mod1_var_1;" \
+ "" \
+ "Module \"mod2\":" \
+ "" \
+ "File .*:" \
+ "38:\[\t \]+${integer4} mod2::mod2_var_1;" ]
diff --git a/gdb/testsuite/gdb.fortran/info-types.exp b/gdb/testsuite/gdb.fortran/info-types.exp
index b0656bce2b7..71220736cd2 100644
--- a/gdb/testsuite/gdb.fortran/info-types.exp
+++ b/gdb/testsuite/gdb.fortran/info-types.exp
@@ -33,6 +33,7 @@ if { ![runto MAIN__] } {
 set integer4 [fortran_int4]
 set logical4 [fortran_logical4]
 set character1 [fortran_character1]
+set real4 [fortran_real4]
 
 gdb_test "info types" \
     [multi_line \
@@ -42,6 +43,7 @@ gdb_test "info types" \
  "\[\t \]+${character1}" \
  "\[\t \]+${integer4}" \
  "\[\t \]+${logical4}" \
- "20:\[\t \]+Type __vtype_mod1_M1t1;" \
+ "35:\[\t \]+Type __vtype_mod1_M1t1;" \
  "17:\[\t \]+Type m1t1;" \
- "26:\[\t \]+Type s1;" ]
+ "\[\t \]+${real4}" \
+ "57:\[\t \]+Type s1;" ]
diff --git a/gdb/testsuite/gdb.fortran/info-types.f90 b/gdb/testsuite/gdb.fortran/info-types.f90
index 859a9485c8f..d2b61372226 100644
--- a/gdb/testsuite/gdb.fortran/info-types.f90
+++ b/gdb/testsuite/gdb.fortran/info-types.f90
@@ -17,10 +17,41 @@ module mod1
   type :: m1t1
      integer :: b
   end type m1t1
+
+  real :: mod1_var_1 = 1.0
+  integer, parameter :: mod1_var_2 = 456
+
+contains
+  subroutine sub_m1_a(arg)
+    integer :: arg
+    print*, "sub_m1_a"
+    print*, "arg = ", arg
+  end subroutine sub_m1_a
+
+  integer function sub_m1_b()
+    print*, "sub_m1_b"
+    sub_m1_b = 3
+  end function sub_m1_b
 end module mod1
 
 module mod2
   integer :: mod2_var_1 = 123
+  real, parameter :: mod2_var_2 = 0.5
+contains
+  subroutine sub_m2_a(a, b)
+    integer :: a
+    logical :: b
+    print*, "sub_m2_a = ", abc
+    print*, "a = ", a
+    print*, "b = ", b
+  end subroutine sub_m2_a
+
+  logical function sub_m2_b(x)
+    real :: x
+    print*, "sub_m2_b = ", cde
+    print*, "x = ", x
+    sub_m2_b = .true.
+  end function sub_m2_b
 end module mod2
 
 program info_types_test
--
2.14.5

Reply | Threaded
Open this post in threaded view
|

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

Eli Zaretskii
In reply to this post by Andrew Burgess
> From: Andrew Burgess <[hidden email]>
> Cc: Richard Bunt <[hidden email]>, Andrew Burgess <[hidden email]>
> 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.

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 6/7] gdb/fortran: Add new 'info modules' command

Eli Zaretskii
In reply to this post by Andrew Burgess
> From: Andrew Burgess <[hidden email]>
> Cc: Richard Bunt <[hidden email]>, Andrew Burgess <[hidden email]>
> Date: Sat, 27 Jul 2019 17:22:34 +0100
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 40b56727227..14c931602f4 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -104,6 +104,12 @@ maint show test-settings KIND
>    A set of commands used by the testsuite for exercising the settings
>    infrastructure.
>  
> +info modules [-q] [REGEXP]
> +  Return a list of modules matching REGEXP, or all modules if no
> +  REGEXP is given.  Only languages that generate DW_TAG_module in
> +  their DWARF (for example Fortran) will give any results for this
> +  command.

Without saying what is a "module", or at least naming a couple of
languages which support them, this is not a very useful entry, I'm
afraid.  I don't think it's reasonable to assume the reader knows the
DWARF spec enough to understand that from the tag name.

> +@kindex info modules
> +@cindex modules
> +@item info modules [-q] [@var{regexp}]
> +List all modules for which there is debugging information available.
> +Modules are identified by @code{DW_TAG_module} in DWARF debugging
> +information, only languages that use this tag will list modules with
> +this command.  Currently Fortran is known to generate module
> +information in its debug.

I would drop the DW_TAG_module reference, and instead try to explain
in less technical terms what is a module.

What other languages are known to have modules in this meaning?  Can
we name them?

> +The optional flag @samp{-q}, which stands for @samp{quiet}, disables
> +printing header information and messages explaining why no functions
> +have been printed.

Not sure I understand from this text how is -q useful for "info
modules".

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/7] gdb: Add new commands to list module variables and functions

Eli Zaretskii
In reply to this post by Andrew Burgess
> From: Andrew Burgess <[hidden email]>
> Cc: Richard Bunt <[hidden email]>, Andrew Burgess <[hidden email]>
> Date: Sat, 27 Jul 2019 17:22:35 +0100
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 14c931602f4..9b7e6cc1c71 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -110,6 +110,20 @@ info modules [-q] [REGEXP]
>    their DWARF (for example Fortran) will give any results for this
>    command.
>  
> +info module functions [-q] [-m MODULE_REGEXP] [-t TYPE_REGEXP] [REGEXP]
> +  Return a list of functions within all modules, grouped by module.
> +  The list of functions can be restricted with the optional regular
> +  expressions.  MODULE_REGEXP matches against the module name,
> +  TYPE_REGEXP matches against the function type signature, and REGEXP
> +  matches against the function name.
> +
> +info module variables [-q] [-m MODULE_REGEXP] [-t TYPE_REGEXP] [REGEXP]
> +  Return a list of variables within all modules, grouped by module.
> +  The list of variables can be restricted with the optional regular
> +  expressions.  MODULE_REGEXP matches against the module name,
> +  TYPE_REGEXP matches against the variable type, and REGEXP matches
> +  against the variable name.

Modulo the explanation of what is a module, this part is OK.

> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -18633,6 +18633,40 @@
>  printing header information and messages explaining why no functions
>  have been printed.
>  
> +@kindex info module functions
> +@cindex modules
> +@cindex functions
> +@cindex module functions
> +@item info module functions [-q] [-m @var{module-regexp}] [-t @var{type-regexp}] [@var{regexp}]
> +List all functions within all modules.  The set of functions listed
> +can be limited by providing some or all of the optional regular
> +expressions.  If @var{module-regexp} is provided, then only modules
> +matching @var{module-regexp} will be searched.  Only functions whose
> +type matches the optional regular expression @var{type-regexp} will be
> +listed.  And only functions whose name matches the optional regular
> +expression @var{regexp} will be listed.
> +
> +The optional flag @samp{-q}, which stands for @samp{quiet}, disables
> +printing header information and messages explaining why no functions
> +have been printed.
> +
> +@kindex info module variables
> +@cindex modules
> +@cindex variables
> +@cindex module variables
> +@item info module variables [-q] [-m @var{module-regexp}] [-t @var{type-regexp}] [@var{regexp}]
> +List all variables within all modules.  The set of variables listed
> +can be limited by providing some or all of the optional regular
> +expressions.  If @var{module-regexp} is provided, then only modules
> +matching @var{module-regexp} will be searched.  Only variables whose
> +type matches the optional regular expression @var{type-regexp} will be
> +listed.  And only variables whose name matches the optional regular
> +expression @var{regexp} will be listed.
> +
> +The optional flag @samp{-q}, which stands for @samp{quiet}, disables
> +printing header information and messages explaining why no variables
> +have been printed.

These two commands are very similar, so I would suggest to describe
both of them in the same text, instead of repeating almost the same
description twice.

> +  c = add_cmd ("functions", class_info, info_module_functions_command, _("\
> +Display functions within each module.\n\

I'd say instead "Display functions arranged by modules."

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/7] gdb: Add an is_declaration field to each symbol

Tom Tromey-2
In reply to this post by Andrew Burgess
>>>>> "Andrew" == Andrew Burgess <[hidden email]> writes:

Andrew> Track if a symbol is a declaration or not.  At one point we could
Andrew> possibly figure this out based on the LOC_UNRESOLVED address class of
Andrew> the symbol, but, for Fortran we mark some symbols as LOC_UNRESOLVED
Andrew> even when the DWARF supplies an address, this is because the address
Andrew> supplied by the DWARF is actually wrong.  For details look in
Andrew> dwarf2read.c and look for references to gFortran bug #40040.  I have
Andrew> confirmed that current versions of gFortran still have the issue
Andrew> mentioned in that bug report.

That bug looks like another instance of the copy relocation problem.
So, I wonder if these workarounds could be removed if/when this series
lands:

    https://sourceware.org/ml/gdb-patches/2019-06/msg00612.html

(I still haven't looked at Pedro's review in detail, but I will get to
it sooner or later.)

Tom
Reply | Threaded
Open this post in threaded view
|

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

Tom Tromey-2
In reply to this post by Andrew Burgess
>>>>> "Andrew" == Andrew Burgess <[hidden email]> writes:

Andrew> +The flag -q disables the production of these headers and messages.%s"),
Andrew> +     prefix, entity_kind, entity_kind, entity_kind,
Andrew> +     (document_n_flag ? "\n\
Andrew> +By default, the command will include non-debug symbols in the output\n\
Andrew> +these can be excluded using the -n flag." : ""));

I suspect this string should be wrapped in _(...).

Tom
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 6/7] gdb/fortran: Add new 'info modules' command

Tom Tromey-2
In reply to this post by Andrew Burgess
>>>>> "Andrew" == Andrew Burgess <[hidden email]> writes:

Andrew> * dwarf2read.c (dw2_debug_names_iterator::next): Handle
Andrew> MODULES_DOMAIN.

Are modules written to the .debug_names index?

Should Fortran be excluded from gdb_index?

Andrew> * psymtab.c (recursively_search_psymtabs): Likewise.

... since AFAIK module info isn't written to .gdb_index, but if psymtab
searching needs to be changed here, then so would the various indices.

Tom
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/7] gdb: Add an is_declaration field to each symbol

Andrew Burgess
In reply to this post by Tom Tromey-2
* Tom Tromey <[hidden email]> [2019-07-29 14:21:45 -0600]:

> >>>>> "Andrew" == Andrew Burgess <[hidden email]> writes:
>
> Andrew> Track if a symbol is a declaration or not.  At one point we could
> Andrew> possibly figure this out based on the LOC_UNRESOLVED address class of
> Andrew> the symbol, but, for Fortran we mark some symbols as LOC_UNRESOLVED
> Andrew> even when the DWARF supplies an address, this is because the address
> Andrew> supplied by the DWARF is actually wrong.  For details look in
> Andrew> dwarf2read.c and look for references to gFortran bug #40040.  I have
> Andrew> confirmed that current versions of gFortran still have the issue
> Andrew> mentioned in that bug report.
>
> That bug looks like another instance of the copy relocation problem.
> So, I wonder if these workarounds could be removed if/when this series
> lands:
>
>     https://sourceware.org/ml/gdb-patches/2019-06/msg00612.html
>
> (I still haven't looked at Pedro's review in detail, but I will get to
> it sooner or later.)

I checked your copy relocation series does indeed make parts #2 and #3
of my series redundant.

I'll address the other feedback with this series and rebase once your
series lands.

Thanks,
Andrew
Reply | Threaded
Open this post in threaded view
|

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

Andrew Burgess
In reply to this post by Eli Zaretskii
* Eli Zaretskii <[hidden email]> [2019-07-27 19:40:58 +0300]:

> > From: Andrew Burgess <[hidden email]>
> > Cc: Richard Bunt <[hidden email]>, Andrew Burgess <[hidden email]>
> > 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 <[hidden email]>
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);
Reply | Threaded
Open this post in threaded view
|

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

Eli Zaretskii
> Date: Tue, 30 Jul 2019 22:02:45 +0100
> From: Andrew Burgess <[hidden email]>
> Cc: [hidden email], [hidden email]
>
> --- 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.
Reply | Threaded
Open this post in threaded view
|

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

Andrew Burgess
* Eli Zaretskii <[hidden email]> [2019-07-31 17:51:26 +0300]:

> > Date: Tue, 30 Jul 2019 22:02:45 +0100
> > From: Andrew Burgess <[hidden email]>
> > Cc: [hidden email], [hidden email]
> >
> > --- 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 <[hidden email]>
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);
Reply | Threaded
Open this post in threaded view
|

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

Eli Zaretskii
> Date: Mon, 26 Aug 2019 16:52:00 +0100
> From: Andrew Burgess <[hidden email]>
> Cc: [hidden email], [hidden email]
>
> +  ** 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)
                                                                   ^
A typo.

Other than that, the documentation parts are OK.

Thanks.
Reply | Threaded
Open this post in threaded view
|

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

Andrew Burgess
* Eli Zaretskii <[hidden email]> [2019-08-26 19:18:53 +0300]:

> > Date: Mon, 26 Aug 2019 16:52:00 +0100
> > From: Andrew Burgess <[hidden email]>
> > Cc: [hidden email], [hidden email]
> >
> > +  ** 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)
>                                                                    ^
> A typo.
>
> Other than that, the documentation parts are OK.
>
> Thanks.

Thanks,

This patch is now pushed.

Andrew
12