* [PUSHED 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] @ 2018-10-27 12:44 Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 5/5] Add a test case for info args|functions|locals|variables " Philippe Waroquiers ` (4 more replies) 0 siblings, 5 replies; 8+ messages in thread From: Philippe Waroquiers @ 2018-10-27 12:44 UTC (permalink / raw) To: gdb-patches Many thanks to Eli, Pedro and Tom for the several reviews. Philippe ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PUSHED 5/5] Add a test case for info args|functions|locals|variables [-q] [-t TYPEREGEXP] [NAMEREGEXP] 2018-10-27 12:44 [PUSHED 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers @ 2018-10-27 12:44 ` Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 3/5] Document changes to info [args|functions|locals|variables] Philippe Waroquiers ` (3 subsequent siblings) 4 siblings, 0 replies; 8+ messages in thread From: Philippe Waroquiers @ 2018-10-27 12:44 UTC (permalink / raw) To: gdb-patches; +Cc: Philippe Waroquiers Add a test case for info args|functions|locals|variables [-q] [-t TYPEREGEXP] [NAMEREGEXP] gdb/testsuite/ChangeLog 2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> * gdb.base/info_qt.c: New file. * gdb.base/info_qt.exp: New file. --- gdb/testsuite/ChangeLog | 5 + gdb/testsuite/gdb.base/info_qt.c | 78 +++++++++ gdb/testsuite/gdb.base/info_qt.exp | 243 +++++++++++++++++++++++++++++ 3 files changed, 326 insertions(+) create mode 100644 gdb/testsuite/gdb.base/info_qt.c create mode 100644 gdb/testsuite/gdb.base/info_qt.exp diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index a8c83d792c..cf0da029e4 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> + + * gdb.base/info_qt.c: New file. + * gdb.base/info_qt.exp: New file. + 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-htm-regs.c: New file. diff --git a/gdb/testsuite/gdb.base/info_qt.c b/gdb/testsuite/gdb.base/info_qt.c new file mode 100644 index 0000000000..479557124f --- /dev/null +++ b/gdb/testsuite/gdb.base/info_qt.c @@ -0,0 +1,78 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2018 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +typedef int entier; + +int info_qt_inc = 0; +entier info_qt_ent = 0; + +static void +setup_done (void) +{ +} + +static void +setup (char arg_c, int arg_i, int arg_j) +{ + char loc_arg_c = arg_c; + int loc_arg_i = arg_i; + int loc_arg_j = arg_j; + + info_qt_inc += loc_arg_c + loc_arg_i + loc_arg_j; + setup_done (); +} + +void info_fun1 (void) +{ + info_qt_inc++; + info_qt_ent++; +} + +int info_fun2 (char c) +{ + info_qt_inc += c; + return info_qt_inc; +} + +int info_fun2bis (char c) +{ + info_qt_inc += c; + return info_qt_inc; +} + +entier info_fun2xxx (char arg_c, int arg_i, int arg_j) +{ + info_qt_inc += arg_c + arg_i + arg_j; + return info_qt_inc; +} + +entier info_fun2yyy (char arg_c, int arg_i, int arg_j) +{ + setup (arg_c, arg_i, arg_j); + info_qt_inc += arg_c + arg_i + arg_j; + return info_qt_inc; +} + +int +main (int argc, char **argv, char **envp) +{ + info_fun1 (); + (void) info_fun2 ('a'); + (void) info_fun2bis ('b'); + (void) info_fun2xxx ('c', 1, 2); + (void) info_fun2yyy ('d', 3, 4); +} diff --git a/gdb/testsuite/gdb.base/info_qt.exp b/gdb/testsuite/gdb.base/info_qt.exp new file mode 100644 index 0000000000..ab0872973a --- /dev/null +++ b/gdb/testsuite/gdb.base/info_qt.exp @@ -0,0 +1,243 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2018 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +# This test verifies the TYPEREGEXP and NAMEREGEXP matching logic +# in the commands +# info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP]. + + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile}] } { + return -1 +} + +clean_restart ${binfile} + +if ![runto setup_done] then { + fail "can't run to setup_done" + return 0 +} + +set any "\[^\r\n\]*" +set ws "\[ \t\]\+" +set number "\[0-9]\+" + + +############# Test 'info functions'. + +with_test_prefix "info functions nameregexp" { + foreach cmd { + "info functions info_fun" + "info functions -- info_fun" + "info functions ^info_fun" } { + gdb_test $cmd \ + [multi_line \ + "All functions matching regular expression \".*info_fun.*\":" \ + "" \ + "File .*info_qt.c:" \ + "${number}: void info_fun1\\\(void\\\);" \ + "${number}: int info_fun2\\\(char\\\);" \ + "${number}: int info_fun2bis\\\(char\\\);" \ + "${number}: entier info_fun2xxx\\\(char, int, int\\\);" \ + "${number}: entier info_fun2yyy\\\(char, int, int\\\);" \ + ] + } +} + +with_test_prefix "info functions nameregexp quiet" { + foreach cmd { + "info functions -q info_fun" + "info functions -q -- info_fun" } { + gdb_test $cmd \ + [multi_line \ + "" \ + "File .*info_qt.c:" \ + "${number}: void info_fun1\\\(void\\\);" \ + "${number}: int info_fun2\\\(char\\\);" \ + "${number}: int info_fun2bis\\\(char\\\);" \ + "${number}: entier info_fun2xxx\\\(char, int, int\\\);" \ + "${number}: entier info_fun2yyy\\\(char, int, int\\\);" \ + ] + } +} + +with_test_prefix "info functions nameregexp quiet no match" { + foreach cmd { + "info functions -q nowaythiscanmatch" + "info functions -q -- -q" } { + gdb_test_no_output $cmd + } +} + +with_test_prefix "info functions typeregexp nameregexp" { + foreach cmd { + "info functions -t entier -q info_fun" + "info functions -q -t 'entier (' -- info_fun" + "info functions -q -t '(char, int, int)' -- info_fun" + "info functions -q -t 'entier (char, int, int)' -- info_fun" } { + gdb_test $cmd \ + [multi_line \ + "" \ + "File .*info_qt.c:" \ + "${number}: entier info_fun2xxx\\\(char, int, int\\\);" \ + "${number}: entier info_fun2yyy\\\(char, int, int\\\);" \ + ] + } +} + +with_test_prefix "info functions typeregexp nameregexp no match" { + gdb_test_no_output "info functions -t ganze_Zahl -q info_fun" \ + "quiet output info functions no matching type" +} + +############# Test 'info variables'. + +with_test_prefix "info variables nameregexp" { + foreach cmd { + "info variables info_qt" + "info variables -- info_qt" + "info variables ^info_qt" } { + gdb_test $cmd \ + [multi_line \ + "All variables matching regular expression \".*info_qt.*\":" \ + "" \ + "File .*info_qt.c:" \ + "${number}: entier info_qt_ent;" \ + "${number}: int info_qt_inc;" \ + ] + } +} + +with_test_prefix "info variables nameregexp quiet no match" { + foreach cmd { + "info variables -q nowaythiscanmatch" + "info variables -q -- -q" } { + gdb_test_no_output $cmd + } +} + +with_test_prefix "info variables typeregexp nameregexp quiet" { + foreach cmd { + "info variables -t entier -q info_qt" + "info variables -q -t entier -- info_qt" } { + gdb_test $cmd \ + [multi_line \ + "" \ + "File .*info_qt.c:" \ + "${number}: entier info_qt_ent;" \ + ] + } +} + +with_test_prefix "info variables typeregexp nameregexp quiet no match" { + gdb_test_no_output "info variables -t ganze_Zahl -q info_at" \ + "quiet output info variables no matching type" +} + + + +############# Test 'info args' in function setup. + +gdb_test "frame 1" ".* in setup .*" "set frame 1 for info args" + +with_test_prefix "info args matching all args" { + foreach cmd { + "info args" + "info args arg_" + "info args g" + "info args -- .*" } { + gdb_test $cmd \ + [multi_line \ + "arg_c = 100 'd'" \ + "arg_i = 3" \ + "arg_j = 4" \ + ] + } +} + +with_test_prefix "info args matching some args" { + foreach cmd { + "info args -t int" + "info args arg_[ij]"} { + gdb_test $cmd \ + [multi_line \ + "arg_i = 3" \ + "arg_j = 4" \ + ] + } +} + +with_test_prefix "info args no match" { + gdb_test "info args nowaythiscanmatch" "No matching arguments." "no matching args" + gdb_test_no_output "info args -q nowaythiscanmatch" "quiet no matching args" + gdb_test_no_output "info args -q -t entier" "quiet no matching args with type" +} + +############# Test 'info locals' in function setup. + +gdb_test "frame 1" ".* in setup .*" "set frame 1 for info locals" + +with_test_prefix "info locals matching all locals" { + foreach cmd { + "info locals" + "info locals loc_arg_" + "info locals g" + "info locals -- .*" } { + gdb_test $cmd \ + [multi_line \ + "loc_arg_c = 100 'd'" \ + "loc_arg_i = 3" \ + "loc_arg_j = 4" \ + ] + } +} + +with_test_prefix "info locals matching some locals" { + foreach cmd { + "info locals -t int" + "info locals arg_[ij]" + "info locals loc_arg_[ij]"} { + gdb_test $cmd \ + [multi_line \ + "loc_arg_i = 3" \ + "loc_arg_j = 4" \ + ] + } +} + +with_test_prefix "info locals no match" { + gdb_test "info locals nowaythiscanmatch" "No matching locals." "no matching locals" + gdb_test_no_output "info locals -q nowaythiscanmatch" "quiet no matching locals" + gdb_test_no_output "info locals -q -t ganze_Zahl loc" "quiet no matching locals with type" +} + +# Verify that the rest of the args is taken as a single regexp. +with_test_prefix "rest of args as single regexp" { + gdb_test "info functions abc def" \ + "All functions matching regular expression \\\"abc def\\\":" \ + "single regexp" + + gdb_test "info functions -t uvw abc def" \ + "All functions matching regular expression \\\"abc def\\\" with type matching regulation expression \\\"uvw\\\":" \ + "-t noquote single regexp" + + gdb_test "info functions -t 'uvw xyz' abc def" \ + "All functions matching regular expression \\\"abc def\\\" with type matching regulation expression \\\"uvw xyz\\\":" \ + "-t quote single regexp" +} -- 2.19.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PUSHED 3/5] Document changes to info [args|functions|locals|variables] 2018-10-27 12:44 [PUSHED 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 5/5] Add a test case for info args|functions|locals|variables " Philippe Waroquiers @ 2018-10-27 12:44 ` Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 1/5] New cli-utils.h/.c function extract_info_print_args Philippe Waroquiers ` (2 subsequent siblings) 4 siblings, 0 replies; 8+ messages in thread From: Philippe Waroquiers @ 2018-10-27 12:44 UTC (permalink / raw) To: gdb-patches; +Cc: Philippe Waroquiers Document changes to info [args|functions|locals|variables] gdb/doc/ChangeLog 2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> * gdb.texinfo (Information About a Frame): Document changes to 'info args' and 'info locals'. (Examining the Symbol Table): Document changes to 'info functions' and 'info variables'. --- gdb/doc/ChangeLog | 7 +++ gdb/doc/gdb.texinfo | 125 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 120 insertions(+), 12 deletions(-) diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index abcdbda5d4..8804e81ffa 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,10 @@ +2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> + + * gdb.texinfo (Information About a Frame): Document changes + to 'info args' and 'info locals'. + (Examining the Symbol Table): Document changes to 'info functions' + and 'info variables'. + 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index c49a7745f8..8c1e618973 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -7830,15 +7830,75 @@ same as for the @command{frame} command (@pxref{Selection, ,Selecting a Frame}). The selected frame remains unchanged by this command. @kindex info args -@item info args +@item info args [-q] Print the arguments of the selected frame, each on a separate line. -@item info locals +The optional flag @samp{-q}, which stands for @samp{quiet}, disables +printing header information and messages explaining why no argument +have been printed. + +@item info args [-q] [-t @var{type_regexp}] [@var{regexp}] +Like @kbd{info args}, but only print the arguments selected +with the provided regexp(s). + +If @var{regexp} is provided, print only the arguments whose names +match the regular expression @var{regexp}. + +If @var{type_regexp} is provided, print only the arguments whose +types, as printed by the @code{whatis} command, match +the regular expression @var{type_regexp}. +If @var{type_regexp} contains space(s), it should be enclosed in +quote characters. If needed, use backslash to escape the meaning +of special characters or quotes. + +If both @var{regexp} and @var{type_regexp} are provided, an argument +is printed only if its name matches @var{regexp} and its type matches +@var{type_regexp}. + +@item info locals [-q] @kindex info locals Print the local variables of the selected frame, each on a separate line. These are all variables (declared either static or automatic) accessible at the point of execution of the selected frame. +The optional flag @samp{-q}, which stands for @samp{quiet}, disables +printing header information and messages explaining why no local variables +have been printed. + +@item info locals [-q] [-t @var{type_regexp}] [@var{regexp}] +Like @kbd{info locals}, but only print the local variables selected +with the provided regexp(s). + +If @var{regexp} is provided, print only the local variables whose names +match the regular expression @var{regexp}. + +If @var{type_regexp} is provided, print only the local variables whose +types, as printed by the @code{whatis} command, match +the regular expression @var{type_regexp}. +If @var{type_regexp} contains space(s), it should be enclosed in +quote characters. If needed, use backslash to escape the meaning +of special characters or quotes. + +If both @var{regexp} and @var{type_regexp} are provided, a local variable +is printed only if its name matches @var{regexp} and its type matches +@var{type_regexp}. + +The command @kbd{info locals -q -t @var{type_regexp}} can usefully be +combined with the commands @kbd{frame apply} and @kbd{thread apply}. +For example, your program might use Resource Acquisition Is +Initialization types (RAII) such as @code{lock_something_t}: each +local variable of type @code{lock_something_t} automatically places a +lock that is destroyed when the variable goes out of scope. You can +then list all acquired locks in your program by doing +@smallexample +thread apply all -s frame apply all -s info locals -q -t lock_something_t +@end smallexample +@noindent +or the equivalent shorter form +@smallexample +tfaas i lo -q -t lock_something_t +@end smallexample + @end table @node Frame Apply @@ -17920,32 +17980,73 @@ debugging information, organized into two lists: files whose symbols have already been read, and files whose symbols will be read when needed. @kindex info functions -@item info functions +@item info functions [-q] 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 number. -@item info functions @var{regexp} -Like @samp{info functions}, but only print the names and data types of -functions whose names contain a match for regular expression -@var{regexp}. Thus, @samp{info fun step} finds all functions whose +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}] +Like @samp{info functions}, but only print the names and data types +of the functions selected with the provided regexp(s). + +If @var{regexp} is provided, print only the functions whose names +match the regular expression @var{regexp}. +Thus, @samp{info fun step} finds all functions whose names include @code{step}; @samp{info fun ^step} finds those whose names start with @code{step}. If a function name contains characters that conflict with the regular expression language (e.g.@: @samp{operator*()}), they may be quoted with a backslash. +If @var{type_regexp} is provided, print only the functions whose +types, as printed by the @code{whatis} command, match +the regular expression @var{type_regexp}. +If @var{type_regexp} contains space(s), it should be enclosed in +quote characters. If needed, use backslash to escape the meaning +of special characters or quotes. +Thus, @samp{info fun -t '^int ('} finds the functions that return +an integer; @samp{info fun -t '(.*int.*'} finds the functions that +have an argument type containing int; @samp{info fun -t '^int (' ^step} +finds the functions whose names start with @code{step} and that return +int. + +If both @var{regexp} and @var{type_regexp} are provided, a function +is printed only if its name matches @var{regexp} and its type matches +@var{type_regexp}. + + @kindex info variables -@item info variables +@item info variables [-q] 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 their respective source line numbers. -@item info variables @var{regexp} -Like @kbd{info variables}, but only print the names and data types of -non-local variables whose names contain a match for regular expression -@var{regexp}. +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}] +Like @kbd{info variables}, but only print the variables selected +with the provided regexp(s). + +If @var{regexp} is provided, print only the variables whose names +match the regular expression @var{regexp}. + +If @var{type_regexp} is provided, print only the variables whose +types, as printed by the @code{whatis} command, match +the regular expression @var{type_regexp}. +If @var{type_regexp} contains space(s), it should be enclosed in +quote characters. If needed, use backslash to escape the meaning +of special characters or quotes. + +If both @var{regexp} and @var{type_regexp} are provided, an argument +is printed only if its name matches @var{regexp} and its type matches +@var{type_regexp}. @kindex info classes @cindex Objective-C, classes and selectors -- 2.19.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PUSHED 1/5] New cli-utils.h/.c function extract_info_print_args 2018-10-27 12:44 [PUSHED 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 5/5] Add a test case for info args|functions|locals|variables " Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 3/5] Document changes to info [args|functions|locals|variables] Philippe Waroquiers @ 2018-10-27 12:44 ` Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 2/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 4/5] Announce changes in NEWS " Philippe Waroquiers 4 siblings, 0 replies; 8+ messages in thread From: Philippe Waroquiers @ 2018-10-27 12:44 UTC (permalink / raw) To: gdb-patches; +Cc: Philippe Waroquiers New cli-utils.h/.c function extract_info_print_args factorizes the extraction of the args '[-q] [-t TYPEREGEXP] [NAMEREGEXP]'. New cli-utils.h/.c function report_unrecognized_option_error factorizes reporting an unknown option for a command. These functions will be used by the commands info [args|functions|locals|variables] As extract_info_print_args will be used for 'info functions|variables' which already have the NAMEREGEXP arg, it provides a backward compatible behaviour. cli-utils.c has a new static function extract_arg_maybe_quoted that extracts an argument, possibly quoted. The behaviour of this function is similar to the parsing done by gdb_argv. gdb/ChangeLog 2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> * cli-utils.c (extract_arg_maybe_quoted): New function. (extract_info_print_args): New function. (info_print_args_help): New function. (report_unrecognized_option_error): New function. * cli-utils.h (extract_arg_maybe_quoted): New function. (extract_info_print_args): New function. (info_print_args_help): New function. (report_unrecognized_option_error): New function. --- gdb/ChangeLog | 11 ++++ gdb/cli/cli-utils.c | 129 ++++++++++++++++++++++++++++++++++++++++++++ gdb/cli/cli-utils.h | 30 +++++++++++ 3 files changed, 170 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1f8e958c9a..ea033a798f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> + + * cli-utils.c (extract_arg_maybe_quoted): New function. + (extract_info_print_args): New function. + (info_print_args_help): New function. + (report_unrecognized_option_error): New function. + * cli-utils.h (extract_arg_maybe_quoted): New function. + (extract_info_print_args): New function. + (info_print_args_help): New function. + (report_unrecognized_option_error): New function. + 2018-10-26 Tom Tromey <tom@tromey.com> * dwarf2read.c (recursively_compute_inclusions): Use std::vector. diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c index 30ee4450f9..73315996ad 100644 --- a/gdb/cli/cli-utils.c +++ b/gdb/cli/cli-utils.c @@ -23,6 +23,8 @@ #include <ctype.h> +static std::string extract_arg_maybe_quoted (const char **arg); + /* See documentation in cli-utils.h. */ int @@ -128,6 +130,70 @@ get_number (char **pp) /* See documentation in cli-utils.h. */ +bool +extract_info_print_args (const char **args, + bool *quiet, + std::string *regexp, + std::string *t_regexp) +{ + /* Check for NAMEREGEXP or -- NAMEREGEXP. */ + if (**args != '-' || check_for_argument (args, "--", 2)) + { + *args = skip_spaces (*args); + *regexp = *args; + *args = NULL; + return true; + } + + if (check_for_argument (args, "-t", 2)) + { + *t_regexp = extract_arg_maybe_quoted (args); + *args = skip_spaces (*args); + return true; + } + + if (check_for_argument (args, "-q", 2)) + { + *quiet = true; + *args = skip_spaces (*args); + return true; + } + + return false; +} + +/* See documentation in cli-utils.h. */ + +void +report_unrecognized_option_error (const char *command, const char *args) +{ + std::string option = extract_arg (&args); + + error (_("Unrecognized option '%s' to %s command. " + "Try \"help %s\"."), option.c_str (), + command, command); +} + +/* See documentation in cli-utils.h. */ + +const char * +info_print_args_help (const char *prefix, + const char *entity_kind) +{ + return xstrprintf (_("\ +%sIf NAMEREGEXP is provided, only prints the %s whose name\n\ +matches NAMEREGEXP.\n\ +If -t TYPEREGEXP is provided, only prints the %s whose type\n\ +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); +} + +/* See documentation in cli-utils.h. */ + number_or_range_parser::number_or_range_parser (const char *string) { init (string); @@ -283,6 +349,69 @@ remove_trailing_whitespace (const char *start, const char *s) return s; } +/* A helper function to extract an argument from *ARG. An argument is + delimited by whitespace, but it can also be optionally quoted. + The quoting and special characters are handled similarly to + the parsing done by gdb_argv. + The return value is empty if no argument was found. */ + +static std::string +extract_arg_maybe_quoted (const char **arg) +{ + bool squote = false; + bool dquote = false; + bool bsquote = false; + std::string result; + const char *p = *arg; + + /* Find the start of the argument. */ + p = skip_spaces (p); + + /* Parse p similarly to gdb_argv buildargv function. */ + while (*p != '\0') + { + if (isspace (*p) && !squote && !dquote && !bsquote) + break; + else + { + if (bsquote) + { + bsquote = false; + result += *p; + } + else if (*p == '\\') + bsquote = true; + else if (squote) + { + if (*p == '\'') + squote = false; + else + result += *p; + } + else if (dquote) + { + if (*p == '"') + dquote = false; + else + result += *p; + } + else + { + if (*p == '\'') + squote = true; + else if (*p == '"') + dquote = true; + else + result += *p; + } + p++; + } + } + + *arg = p; + return result; +} + /* See documentation in cli-utils.h. */ std::string diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h index fa7d02d719..f591ba14d6 100644 --- a/gdb/cli/cli-utils.h +++ b/gdb/cli/cli-utils.h @@ -39,6 +39,36 @@ extern int get_number (const char **); extern int get_number (char **); +/* Extract from ARGS the arguments [-q] [-t TYPEREGEXP] [--] NAMEREGEXP. + + The caller is responsible to initialize *QUIET to false, *REGEXP + and *T_REGEXP to "". + extract_info_print_args can then be called iteratively to search + for valid arguments, as part of a 'main parsing loop' searching for + -q/-t/-- arguments together with other flags and options. + + Returns true and updates *ARGS + one of *QUIET, *REGEXP, *T_REGEXP if + it finds a valid argument. + Returns false if no valid argument is found at the beginning of ARGS. */ + +extern bool extract_info_print_args (const char **args, + bool *quiet, + std::string *regexp, + std::string *t_regexp); + +/* Throws an error telling the user that ARGS starts with an option + unrecognized by COMMAND. */ + +extern void report_unrecognized_option_error (const char *command, + const char *args); + + +/* Builds the help string for a command documented by PREFIX, + followed by the extract_info_print_args help for ENTITY_KIND. */ + +const char *info_print_args_help (const char *prefix, + const char *entity_kind); + /* Parse a number or a range. A number will be of the form handled by get_number. A range will be of the form <number1> - <number2>, and -- 2.19.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PUSHED 2/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] 2018-10-27 12:44 [PUSHED 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers ` (2 preceding siblings ...) 2018-10-27 12:44 ` [PUSHED 1/5] New cli-utils.h/.c function extract_info_print_args Philippe Waroquiers @ 2018-10-27 12:44 ` Philippe Waroquiers 2018-10-30 14:59 ` Tom de Vries 2018-10-27 12:44 ` [PUSHED 4/5] Announce changes in NEWS " Philippe Waroquiers 4 siblings, 1 reply; 8+ messages in thread From: Philippe Waroquiers @ 2018-10-27 12:44 UTC (permalink / raw) To: gdb-patches; +Cc: Philippe Waroquiers Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Main changes are: * stack.c: Add two regexp preg and treg to print_variable_and_value_data and used them inside do_print_variable_and_value to filter the variables to print. * symtab.h: Add a new function bool treg_matches_sym_type_name, that factorises type matching logic. * symtab.c: Add type/name matching logic to 'info functions|variables'. * stack.c : Add type/name matching logic to 'info args|locals'. gdb/ChangeLog 2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> * stack.c (print_variable_and_value_data): Add preg and treg. (print_frame_local_vars): Add quiet, regexp and t_regexp arguments, and update callers. (print_frame_arg_vars): Likewise. (prepare_reg): New function. (info_locals_command): Extract info print args and use them. (info_args_command): Likewise. (_initialize_stack): Modify on-line help. * symtab.c (treg_matches_sym_type_name): New function. (search_symbols): New arg t_regexp. (symtab_symbol_info): New args quiet, regexp, t_regexp. (info_variables_command): Extract info print args and use them. (info_functions_command): Likewise. (info_types_command): Update call to symtab_symbol_info. (_initialize_symtab): Modify on-line help. * symtab.h (treg_matches_sym_type_name): New function. (search_symbols): New t_regexp arg. --- gdb/ChangeLog | 20 +++++ gdb/python/python.c | 4 +- gdb/stack.c | 139 +++++++++++++++++++++++++++----- gdb/symtab.c | 191 +++++++++++++++++++++++++++++++++++++------- gdb/symtab.h | 7 +- 5 files changed, 312 insertions(+), 49 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ea033a798f..d105e74dc5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,23 @@ +2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> + + * stack.c (print_variable_and_value_data): Add preg and treg. + (print_frame_local_vars): Add quiet, regexp and t_regexp arguments, + and update callers. + (print_frame_arg_vars): Likewise. + (prepare_reg): New function. + (info_locals_command): Extract info print args and use them. + (info_args_command): Likewise. + (_initialize_stack): Modify on-line help. + * symtab.c (treg_matches_sym_type_name): New function. + (search_symbols): New arg t_regexp. + (symtab_symbol_info): New args quiet, regexp, t_regexp. + (info_variables_command): Extract info print args and use them. + (info_functions_command): Likewise. + (info_types_command): Update call to symtab_symbol_info. + (_initialize_symtab): Modify on-line help. + * symtab.h (treg_matches_sym_type_name): New function. + (search_symbols): New t_regexp arg. + 2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> * cli-utils.c (extract_arg_maybe_quoted): New function. diff --git a/gdb/python/python.c b/gdb/python/python.c index 8fbce78469..348405e205 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -743,11 +743,11 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw) { const char **files = symtab_paths.vec.data (); - symbols = search_symbols (regex, FUNCTIONS_DOMAIN, + symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, symtab_paths.vec.size (), files); } else - symbols = search_symbols (regex, FUNCTIONS_DOMAIN, 0, NULL); + symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 0, NULL); /* 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 87b493f790..abbaf5d4a7 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -88,8 +88,10 @@ const char *print_entry_values = print_entry_values_default; /* Prototypes for local functions. */ -static void print_frame_local_vars (struct frame_info *, int, - struct ui_file *); +static void print_frame_local_vars (struct frame_info *frame, + bool quiet, + const char *regexp, const char *t_regexp, + int num_tabs, struct ui_file *stream); static void print_frame (struct frame_info *frame, int print_level, enum print_what print_what, int print_args, @@ -1878,7 +1880,7 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags, { struct frame_id frame_id = get_frame_id (fi); - print_frame_local_vars (fi, 1, gdb_stdout); + print_frame_local_vars (fi, false, NULL, NULL, 1, gdb_stdout); /* print_frame_local_vars invalidates FI. */ fi = frame_find_by_id (frame_id); @@ -2060,6 +2062,8 @@ iterate_over_block_local_vars (const struct block *block, struct print_variable_and_value_data { + gdb::optional<compiled_regex> preg; + gdb::optional<compiled_regex> treg; struct frame_id frame_id; int num_tabs; struct ui_file *stream; @@ -2077,6 +2081,14 @@ do_print_variable_and_value (const char *print_name, = (struct print_variable_and_value_data *) cb_data; struct frame_info *frame; + if (p->preg.has_value () + && p->preg->exec (SYMBOL_NATURAL_NAME (sym), 0, + NULL, 0) != 0) + return; + if (p->treg.has_value () + && !treg_matches_sym_type_name (*p->treg, sym)) + return; + frame = frame_find_by_id (p->frame_id); if (frame == NULL) { @@ -2092,14 +2104,38 @@ do_print_variable_and_value (const char *print_name, p->values_printed = 1; } +/* Prepares the regular expression REG from REGEXP. + If REGEXP is NULL, it results in an empty regular expression. */ + +static void +prepare_reg (const char *regexp, gdb::optional<compiled_regex> *reg) +{ + if (regexp != NULL) + { + int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off + ? REG_ICASE : 0); + reg->emplace (regexp, cflags, _("Invalid regexp")); + } + else + reg->reset (); +} + /* Print all variables from the innermost up to the function block of FRAME. Print them with values to STREAM indented by NUM_TABS. + If REGEXP is not NULL, only print local variables whose name + matches REGEXP. + If T_REGEXP is not NULL, only print local variables whose type + matches T_REGEXP. + If no local variables have been printed and !QUIET, prints a message + explaining why no local variables could be printed. This function will invalidate FRAME. */ static void -print_frame_local_vars (struct frame_info *frame, int num_tabs, - struct ui_file *stream) +print_frame_local_vars (struct frame_info *frame, + bool quiet, + const char *regexp, const char *t_regexp, + int num_tabs, struct ui_file *stream) { struct print_variable_and_value_data cb_data; const struct block *block; @@ -2107,18 +2143,22 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs, if (!get_frame_pc_if_available (frame, &pc)) { - fprintf_filtered (stream, - _("PC unavailable, cannot determine locals.\n")); + if (!quiet) + fprintf_filtered (stream, + _("PC unavailable, cannot determine locals.\n")); return; } block = get_frame_block (frame, 0); if (block == 0) { - fprintf_filtered (stream, "No symbol table info available.\n"); + if (!quiet) + fprintf_filtered (stream, "No symbol table info available.\n"); return; } + prepare_reg (regexp, &cb_data.preg); + prepare_reg (t_regexp, &cb_data.treg); cb_data.frame_id = get_frame_id (frame); cb_data.num_tabs = 4 * num_tabs; cb_data.stream = stream; @@ -2134,14 +2174,33 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs, do_print_variable_and_value, &cb_data); - if (!cb_data.values_printed) - fprintf_filtered (stream, _("No locals.\n")); + if (!cb_data.values_printed && !quiet) + { + if (regexp == NULL && t_regexp == NULL) + fprintf_filtered (stream, _("No locals.\n")); + else + fprintf_filtered (stream, _("No matching locals.\n")); + } } void info_locals_command (const char *args, int from_tty) { + std::string regexp; + std::string t_regexp; + bool quiet = false; + + while (args != NULL + && extract_info_print_args (&args, &quiet, ®exp, &t_regexp)) + ; + + if (args != NULL) + report_unrecognized_option_error ("info locals", args); + print_frame_local_vars (get_selected_frame (_("No frame selected.")), + quiet, + regexp.empty () ? NULL : regexp.c_str (), + t_regexp.empty () ? NULL : t_regexp.c_str (), 0, gdb_stdout); } @@ -2180,29 +2239,45 @@ iterate_over_block_arg_vars (const struct block *b, /* Print all argument variables of the function of FRAME. Print them with values to STREAM. + If REGEXP is not NULL, only print argument variables whose name + matches REGEXP. + If T_REGEXP is not NULL, only print argument variables whose type + matches T_REGEXP. + If no argument variables have been printed and !QUIET, prints a message + explaining why no argument variables could be printed. This function will invalidate FRAME. */ static void -print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream) +print_frame_arg_vars (struct frame_info *frame, + bool quiet, + const char *regexp, const char *t_regexp, + struct ui_file *stream) { struct print_variable_and_value_data cb_data; struct symbol *func; CORE_ADDR pc; + gdb::optional<compiled_regex> preg; + gdb::optional<compiled_regex> treg; if (!get_frame_pc_if_available (frame, &pc)) { - fprintf_filtered (stream, _("PC unavailable, cannot determine args.\n")); + if (!quiet) + fprintf_filtered (stream, + _("PC unavailable, cannot determine args.\n")); return; } func = get_frame_function (frame); if (func == NULL) { - fprintf_filtered (stream, _("No symbol table info available.\n")); + if (!quiet) + fprintf_filtered (stream, _("No symbol table info available.\n")); return; } + prepare_reg (regexp, &cb_data.preg); + prepare_reg (t_regexp, &cb_data.treg); cb_data.frame_id = get_frame_id (frame); cb_data.num_tabs = 0; cb_data.stream = stream; @@ -2214,14 +2289,34 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream) /* do_print_variable_and_value invalidates FRAME. */ frame = NULL; - if (!cb_data.values_printed) - fprintf_filtered (stream, _("No arguments.\n")); + if (!cb_data.values_printed && !quiet) + { + if (regexp == NULL && t_regexp == NULL) + fprintf_filtered (stream, _("No arguments.\n")); + else + fprintf_filtered (stream, _("No matching arguments.\n")); + } } void -info_args_command (const char *ignore, int from_tty) +info_args_command (const char *args, int from_tty) { + std::string regexp; + std::string t_regexp; + bool quiet; + + while (args != NULL + && extract_info_print_args (&args, &quiet, ®exp, &t_regexp)) + ; + + if (args != NULL) + report_unrecognized_option_error ("info args", args); + + print_frame_arg_vars (get_selected_frame (_("No frame selected.")), + quiet, + regexp.empty () ? NULL : regexp.c_str (), + t_regexp.empty () ? NULL : t_regexp.c_str (), gdb_stdout); } \f @@ -2994,9 +3089,17 @@ Usage: info frame level LEVEL"), &info_frame_cmd_list); add_info ("locals", info_locals_command, - _("Local variables of current stack frame.")); + info_print_args_help (_("\ +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"))); add_info ("args", info_args_command, - _("Argument variables of current stack frame.")); + 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"))); if (dbx_commands) add_com ("func", class_stack, func_command, _("\ diff --git a/gdb/symtab.c b/gdb/symtab.c index 2e48d6527e..cd27a75e8c 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -43,6 +43,7 @@ #include "cli/cli-utils.h" #include "fnmatch.h" #include "hashtab.h" +#include "typeprint.h" #include "gdb_obstack.h" #include "block.h" @@ -4266,6 +4267,52 @@ symbol_search::compare_search_syms (const symbol_search &sym_a, SYMBOL_PRINT_NAME (sym_b.symbol)); } +/* Returns true if the type_name of symbol_type of SYM matches TREG. + If SYM has no symbol_type or symbol_name, returns false. */ + +bool +treg_matches_sym_type_name (const compiled_regex &treg, + const struct symbol *sym) +{ + struct type *sym_type; + std::string printed_sym_type_name; + + if (symbol_lookup_debug > 1) + { + fprintf_unfiltered (gdb_stdlog, + "treg_matches_sym_type_name\n sym %s\n", + SYMBOL_NATURAL_NAME (sym)); + } + + sym_type = SYMBOL_TYPE (sym); + if (sym_type == NULL) + return false; + + if (language_mode == language_mode_auto) + { + scoped_restore_current_language l; + + set_language (SYMBOL_LANGUAGE (sym)); + printed_sym_type_name = type_to_string (sym_type); + } + else + printed_sym_type_name = type_to_string (sym_type); + + if (symbol_lookup_debug > 1) + { + fprintf_unfiltered (gdb_stdlog, + " sym_type_name %s\n", + printed_sym_type_name.c_str ()); + } + + + if (printed_sym_type_name.empty ()) + return false; + + return treg.exec (printed_sym_type_name.c_str (), 0, NULL, 0) == 0; +} + + /* Sort the symbols in RESULT and remove duplicates. */ static void @@ -4281,7 +4328,9 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result) Only symbols of KIND are searched: VARIABLES_DOMAIN - search all symbols, excluding functions, type names, - and constants (enums) + and constants (enums). + if T_REGEXP is not NULL, only returns var that have + a type matching regular expression T_REGEXP. FUNCTIONS_DOMAIN - search all functions TYPES_DOMAIN - search all type names ALL_DOMAIN - an internal error for this function @@ -4292,6 +4341,7 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result) std::vector<symbol_search> search_symbols (const char *regexp, enum search_domain kind, + const char *t_regexp, int nfiles, const char *files[]) { struct compunit_symtab *cust; @@ -4317,6 +4367,7 @@ search_symbols (const char *regexp, enum search_domain kind, enum minimal_symbol_type ourtype4; std::vector<symbol_search> result; gdb::optional<compiled_regex> preg; + gdb::optional<compiled_regex> treg; gdb_assert (kind <= TYPES_DOMAIN); @@ -4366,6 +4417,13 @@ search_symbols (const char *regexp, enum search_domain kind, preg.emplace (regexp, cflags, _("Invalid regexp")); } + if (t_regexp != NULL) + { + int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off + ? REG_ICASE : 0); + treg.emplace (t_regexp, cflags, _("Invalid regexp")); + } + /* Search through the partial symtabs *first* for all symbols matching the regexp. That way we don't have to reproduce all of the machinery below. */ @@ -4377,8 +4435,9 @@ search_symbols (const char *regexp, enum search_domain kind, lookup_name_info::match_any (), [&] (const char *symname) { - return (!preg || preg->exec (symname, - 0, NULL, 0) == 0); + return (!preg.has_value () + || preg->exec (symname, + 0, NULL, 0) == 0); }, NULL, kind); @@ -4413,7 +4472,7 @@ search_symbols (const char *regexp, enum search_domain kind, || MSYMBOL_TYPE (msymbol) == ourtype3 || MSYMBOL_TYPE (msymbol) == ourtype4) { - if (!preg + if (!preg.has_value () || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0, NULL, 0) == 0) { @@ -4452,7 +4511,7 @@ search_symbols (const char *regexp, enum search_domain kind, files, nfiles, 1)) && file_matches (symtab_to_fullname (real_symtab), files, nfiles, 0))) - && ((!preg + && ((!preg.has_value () || preg->exec (SYMBOL_NATURAL_NAME (sym), 0, NULL, 0) == 0) && ((kind == VARIABLES_DOMAIN @@ -4464,9 +4523,13 @@ search_symbols (const char *regexp, enum search_domain kind, We only want to skip enums here. */ && !(SYMBOL_CLASS (sym) == LOC_CONST && (TYPE_CODE (SYMBOL_TYPE (sym)) - == TYPE_CODE_ENUM))) - || (kind == FUNCTIONS_DOMAIN - && SYMBOL_CLASS (sym) == LOC_BLOCK) + == TYPE_CODE_ENUM)) + && (!treg.has_value () + || treg_matches_sym_type_name (*treg, sym))) + || (kind == FUNCTIONS_DOMAIN + && SYMBOL_CLASS (sym) == LOC_BLOCK + && (!treg.has_value () + || treg_matches_sym_type_name (*treg, sym))) || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF)))) { @@ -4497,8 +4560,13 @@ search_symbols (const char *regexp, enum search_domain kind, || MSYMBOL_TYPE (msymbol) == ourtype3 || MSYMBOL_TYPE (msymbol) == ourtype4) { - if (!preg || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0, - NULL, 0) == 0) + /* If the user wants to see var matching a type regexp, + then never give a minimal symbol. */ + if (kind != VARIABLES_DOMAIN + && !treg.has_value () /* minimal symbol has never a type ???? */ + && (!preg.has_value () + || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0, + NULL, 0) == 0)) { /* For functions we can do a quick check of whether the symbol might be found via find_pc_symtab. */ @@ -4599,7 +4667,9 @@ print_msymbol_info (struct bound_minimal_symbol msymbol) matches. */ static void -symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty) +symtab_symbol_info (bool quiet, + const char *regexp, enum search_domain kind, + const char *t_regexp, int from_tty) { static const char * const classnames[] = {"variable", "function", "type"}; @@ -4609,13 +4679,33 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty) gdb_assert (kind <= TYPES_DOMAIN); /* Must make sure that if we're interrupted, symbols gets freed. */ - std::vector<symbol_search> symbols = search_symbols (regexp, kind, 0, NULL); + std::vector<symbol_search> symbols = search_symbols (regexp, kind, + t_regexp, 0, NULL); - if (regexp != NULL) - printf_filtered (_("All %ss matching regular expression \"%s\":\n"), - classnames[kind], regexp); - else - printf_filtered (_("All defined %ss:\n"), classnames[kind]); + if (!quiet) + { + if (regexp != NULL) + { + if (t_regexp != NULL) + printf_filtered + (_("All %ss matching regular expression \"%s\"" + " with type matching regulation expression \"%s\":\n"), + classnames[kind], regexp, t_regexp); + else + printf_filtered (_("All %ss matching regular expression \"%s\":\n"), + classnames[kind], regexp); + } + else + { + if (t_regexp != NULL) + printf_filtered + (_("All defined %ss" + " with type matching regulation expression \"%s\" :\n"), + classnames[kind], t_regexp); + else + printf_filtered (_("All defined %ss:\n"), classnames[kind]); + } + } for (const symbol_search &p : symbols) { @@ -4625,7 +4715,8 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty) { if (first) { - printf_filtered (_("\nNon-debugging symbols:\n")); + if (!quiet) + printf_filtered (_("\nNon-debugging symbols:\n")); first = 0; } print_msymbol_info (p.msymbol); @@ -4643,22 +4734,53 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty) } static void -info_variables_command (const char *regexp, int from_tty) +info_variables_command (const char *args, int from_tty) { - symtab_symbol_info (regexp, VARIABLES_DOMAIN, from_tty); + std::string regexp; + std::string t_regexp; + bool quiet = false; + + while (args != NULL + && extract_info_print_args (&args, &quiet, ®exp, &t_regexp)) + ; + + if (args != NULL) + report_unrecognized_option_error ("info variables", args); + + symtab_symbol_info (quiet, + regexp.empty () ? NULL : regexp.c_str (), + VARIABLES_DOMAIN, + t_regexp.empty () ? NULL : t_regexp.c_str (), + from_tty); } + static void -info_functions_command (const char *regexp, int from_tty) +info_functions_command (const char *args, int from_tty) { - symtab_symbol_info (regexp, FUNCTIONS_DOMAIN, from_tty); + std::string regexp; + std::string t_regexp; + bool quiet; + + while (args != NULL + && extract_info_print_args (&args, &quiet, ®exp, &t_regexp)) + ; + + if (args != NULL) + report_unrecognized_option_error ("info functions", args); + + symtab_symbol_info (quiet, + regexp.empty () ? NULL : regexp.c_str (), + FUNCTIONS_DOMAIN, + t_regexp.empty () ? NULL : t_regexp.c_str (), + from_tty); } static void info_types_command (const char *regexp, int from_tty) { - symtab_symbol_info (regexp, TYPES_DOMAIN, from_tty); + symtab_symbol_info (false, regexp, TYPES_DOMAIN, NULL, from_tty); } /* Breakpoint all functions matching regular expression. */ @@ -4701,6 +4823,7 @@ rbreak_command (const char *regexp, int from_tty) std::vector<symbol_search> symbols = search_symbols (regexp, FUNCTIONS_DOMAIN, + NULL, nfiles, files); scoped_rbreak_breakpoints finalize; @@ -5902,14 +6025,26 @@ _initialize_symtab (void) symbol_cache_key = register_program_space_data_with_cleanup (NULL, symbol_cache_cleanup); - add_info ("variables", info_variables_command, _("\ -All global and static variable names, or those matching REGEXP.")); + 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\ +Prints the global and static variables.\n"), + _("global and static variables"))); if (dbx_commands) - add_com ("whereis", class_info, info_variables_command, _("\ -All global and static variable names, or those matching REGEXP.")); + 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\ +Prints the global and static variables.\n"), + _("global and static variables"))); add_info ("functions", info_functions_command, - _("All function names, or those matching REGEXP.")); + info_print_args_help (_("\ +All function names or those matching REGEXPs.\n\ +Usage: info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\ +Prints the functions.\n"), + _("functions"))); /* FIXME: This command has at least the following problems: 1. It prints builtin types (in a very strange and confusing fashion). diff --git a/gdb/symtab.h b/gdb/symtab.h index b91ec12b29..e0b870135b 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -25,6 +25,7 @@ #include <string> #include "gdb_vecs.h" #include "gdbtypes.h" +#include "gdb_regex.h" #include "common/enum-flags.h" #include "common/function-view.h" #include "common/gdb_optional.h" @@ -2057,8 +2058,12 @@ private: }; extern std::vector<symbol_search> search_symbols (const char *, - enum search_domain, int, + enum search_domain, + const char *, + int, const char **); +extern bool treg_matches_sym_type_name (const compiled_regex &treg, + const struct symbol *sym); /* The name of the ``main'' function. FIXME: cagney/2001-03-20: Can't make main_name() const since some -- 2.19.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PUSHED 2/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] 2018-10-27 12:44 ` [PUSHED 2/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers @ 2018-10-30 14:59 ` Tom de Vries 2018-10-30 21:27 ` Philippe Waroquiers 0 siblings, 1 reply; 8+ messages in thread From: Tom de Vries @ 2018-10-30 14:59 UTC (permalink / raw) To: Philippe Waroquiers, gdb-patches; +Cc: Pedro Alves On 10/27/18 2:44 PM, Philippe Waroquiers wrote: > @@ -4497,8 +4560,13 @@ search_symbols (const char *regexp, enum search_domain kind, > || MSYMBOL_TYPE (msymbol) == ourtype3 > || MSYMBOL_TYPE (msymbol) == ourtype4) > { > - if (!preg || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0, > - NULL, 0) == 0) > + /* If the user wants to see var matching a type regexp, > + then never give a minimal symbol. */ > + if (kind != VARIABLES_DOMAIN > + && !treg.has_value () /* minimal symbol has never a type ???? */ > + && (!preg.has_value () > + || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0, > + NULL, 0) == 0)) > { > /* For functions we can do a quick check of whether the > symbol might be found via find_pc_symtab. */ Hi, Consider this testcase with minimal symbols: ... $ cat test.c static int var; int main (void) { return 0; } $ gcc test.c $ ... After this commit, I don't see "var": ... $ gdb -batch a.out -ex "info var" All defined variables: File init.c: 24: const int _IO_stdin_used; ... while before this commit, I do see "var": ... $ gdb -batch a.out -ex "info variables" All defined variables: File init.c: 24: const int _IO_stdin_used; Non-debugging symbols: 0x0000000000400534 __GNU_EH_FRAME_HDR 0x0000000000400624 __FRAME_END__ 0x0000000000600e40 __frame_dummy_init_array_entry 0x0000000000600e40 __init_array_start 0x0000000000600e48 __do_global_dtors_aux_fini_array_entry 0x0000000000600e48 __init_array_end 0x0000000000600e50 _DYNAMIC 0x0000000000601000 _GLOBAL_OFFSET_TABLE_ 0x0000000000601018 __data_start 0x0000000000601018 data_start 0x0000000000601020 __dso_handle 0x0000000000601028 __TMC_END__ 0x0000000000601028 __bss_start 0x0000000000601028 _edata 0x0000000000601028 completed 0x000000000060102c var 0x0000000000601030 _end ... I think this is a regression. Thanks, - Tom ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PUSHED 2/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] 2018-10-30 14:59 ` Tom de Vries @ 2018-10-30 21:27 ` Philippe Waroquiers 0 siblings, 0 replies; 8+ messages in thread From: Philippe Waroquiers @ 2018-10-30 21:27 UTC (permalink / raw) To: Tom de Vries, gdb-patches; +Cc: Pedro Alves On Tue, 2018-10-30 at 15:59 +0100, Tom de Vries wrote: > > After this commit, I don't see "var": ... > I think this is a regression. > Yes, thanks for the clear description of the regression. I have just sent an RFA with a fix and a test case. Philippe ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PUSHED 4/5] Announce changes in NEWS to info [args|functions|locals|variables] 2018-10-27 12:44 [PUSHED 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers ` (3 preceding siblings ...) 2018-10-27 12:44 ` [PUSHED 2/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers @ 2018-10-27 12:44 ` Philippe Waroquiers 4 siblings, 0 replies; 8+ messages in thread From: Philippe Waroquiers @ 2018-10-27 12:44 UTC (permalink / raw) To: gdb-patches; +Cc: Philippe Waroquiers Announce changes in NEWS to info [args|functions|locals|variables] gdb/ChangeLog 2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> * NEWS: Mention changes to 'info [args|functions|locals|variables]' --- gdb/ChangeLog | 4 ++++ gdb/NEWS | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d105e74dc5..e9491358fa 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> + + * NEWS: Mention changes to 'info [args|functions|locals|variables]' + 2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> * stack.c (print_variable_and_value_data): Add preg and treg. diff --git a/gdb/NEWS b/gdb/NEWS index 6b00cd8f9f..7fe588dabb 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -86,6 +86,15 @@ target extended-remote FILENAME If FILENAME is a Unix domain socket, GDB will attempt to connect to this socket instead of opening FILENAME as a character device. +info args [-q] [-t TYPEREGEXP] [NAMEREGEXP] +info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP] +info locals [-q] [-t TYPEREGEXP] [NAMEREGEXP] +info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP] + These commands can now print only the searched entities + matching the provided regexp(s), giving a condition + on the entity names or entity types. The flag -q disables + printing headers or informations messages. + thread apply [all | COUNT | -COUNT] [FLAG]... COMMAND The 'thread apply' command accepts new FLAG arguments. FLAG arguments allow to control what output to produce and how to handle -- 2.19.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-10-30 21:27 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-10-27 12:44 [PUSHED 0/5] info [args|functions|locals|variables] [-q] [-t TYPEREGEXP] [NAMEREGEXP] Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 5/5] Add a test case for info args|functions|locals|variables " Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 3/5] Document changes to info [args|functions|locals|variables] Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 1/5] New cli-utils.h/.c function extract_info_print_args Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 2/5] Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables] Philippe Waroquiers 2018-10-30 14:59 ` Tom de Vries 2018-10-30 21:27 ` Philippe Waroquiers 2018-10-27 12:44 ` [PUSHED 4/5] Announce changes in NEWS " Philippe Waroquiers
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).