From patchwork Thu Sep 26 23:09:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 34687 Received: (qmail 52133 invoked by alias); 26 Sep 2019 23:09:53 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 52055 invoked by uid 89); 26 Sep 2019 23:09:53 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=1516, na, fullname, disconnect X-HELO: mail-wm1-f47.google.com Received: from mail-wm1-f47.google.com (HELO mail-wm1-f47.google.com) (209.85.128.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 26 Sep 2019 23:09:48 +0000 Received: by mail-wm1-f47.google.com with SMTP id 3so4209913wmi.3 for ; Thu, 26 Sep 2019 16:09:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=ZirNe5YpHTGfAQTuN7LgIWELmZ3CmEQyoPJoh4h4og0=; b=OZlPb/kPE9iGe/cKV8xR9qo9cu9QihyxJ+sOJxDO3rEoonLiIiJY3Ml3cVLkNvtgA6 f0j0QjiY4BxPpdYfVClcJChK1BjwqmxOApQ3FccWB7PZM1mSNeKLEd14DjCejlD5pN59 wh5waeRB4CquDKJVKkVLI/wwlC7UajBlyPywL+w2AuDrSRFWI/DCleN+jFxq6fjEJLUP Q8tqt3dpGhaXVjODKSAucvrA18gMlhVVab+EYBHriQyPR2lgQJgGI0jNLiDjjzia2SKd GM+zH+5FcqpcmvBojmPTDBAPfDcJiid0D5StQpEWIdEI+GduUhy/lFLW7Nn+9xEI5a+t IRmA== Return-Path: Received: from localhost (host86-128-12-122.range86-128.btcentralplus.com. [86.128.12.122]) by smtp.gmail.com with ESMTPSA id c6sm474885wrm.71.2019.09.26.16.09.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 26 Sep 2019 16:09:44 -0700 (PDT) From: Andrew Burgess To: gdb-patches Cc: Andrew Burgess Subject: [PATCH 3/3] gdb/mi: Add new commands -symbol-info-{functions, variables, types} Date: Fri, 27 Sep 2019 00:09:37 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes Add new MI commands -symbol-info-functions, -symbol-info-variables, and -symbol-info-types which correspond to the CLI commands 'info functions', 'info variables', and 'info types' respectively. gdb/ChangeLog: * mi/mi-cmds.c: Add '-symbol-info-functions', '-symbol-info-variables', and '-symbol-info-types'. * mi/mi-cmds.h (mi_cmd_symbol_info_functions): Declare. (mi_cmd_symbol_info_variables): Declare. (mi_cmd_symbol_info_types): Declare. * mi/mi-symbol-cmds.c: Add 'source.h' and 'mi-getopt.h' includes. (mi_symbol_info): New function. (mi_info_functions_or_variables): New function. (mi_cmd_symbol_info_functions): New function. (mi_cmd_symbol_info_variables): New function. (mi_cmd_symbol_info_types): New function. * NEWS: Mention new commands. gdb/testsuite/ChangeLog: * gdb.mi/mi-sym-info-1.c: New file. * gdb.mi/mi-sym-info-2.c: New file. * gdb.mi/mi-sym-info.exp: New file. gdb/doc/ChangeLog: * doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command -symbol-info-functions, -symbol-info-types, and -symbol-info-variables. --- gdb/ChangeLog | 15 +++ gdb/NEWS | 4 + gdb/doc/ChangeLog | 6 + gdb/doc/gdb.texinfo | 212 ++++++++++++++++++++++++++++++++++- gdb/mi/mi-cmds.c | 3 + gdb/mi/mi-cmds.h | 3 + gdb/mi/mi-symbol-cmds.c | 195 ++++++++++++++++++++++++++++++++ gdb/testsuite/ChangeLog | 6 + gdb/testsuite/gdb.mi/mi-sym-info-1.c | 48 ++++++++ gdb/testsuite/gdb.mi/mi-sym-info-2.c | 43 +++++++ gdb/testsuite/gdb.mi/mi-sym-info.exp | 179 +++++++++++++++++++++++++++++ 11 files changed, 708 insertions(+), 6 deletions(-) create mode 100644 gdb/testsuite/gdb.mi/mi-sym-info-1.c create mode 100644 gdb/testsuite/gdb.mi/mi-sym-info-2.c create mode 100644 gdb/testsuite/gdb.mi/mi-sym-info.exp diff --git a/gdb/NEWS b/gdb/NEWS index 779fd91d3a6..9c1d08a24c4 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -302,6 +302,10 @@ focus, winheight, +, -, >, < These can be used to catch C++ exceptions in a similar fashion to the CLI commands 'catch throw', 'catch rethrow', and 'catch catch'. +-symbol-info-functions, -symbol-info-types, and -symbol-info-variables + These commands are the MI equivalent of the CLI commands 'info + functions', 'info types', and 'info variables' respectively. + * Other MI changes ** The default version of the MI interpreter is now 3 (-i=mi3). diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index f2713c03960..59c84f029c2 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -33694,27 +33694,227 @@ @subsubheading Example N.A. +@end ignore + +@subheading The @code{-symbol-info-functions} Command +@findex -symbol-info-functions +@anchor{-symbol-info-functions} + +@subsubheading Synopsis +@smallexample + -symbol-info-functions [--include-nondebug] [--type @var{type_regexp}] + [--name @var{name_regexp}] +@end smallexample -@subheading The @code{-symbol-info-function} Command -@findex -symbol-info-function +@noindent +Returns a list containing the names and types for all global functions +taken from the debug information. The functions are grouped by source +file, and the line number on which each function is defined is given. + +When @code{--include-nondebug} is passed then the output also includes +code symbols from the symbol table. + +The options @code{--type} and @code{--name} allow the symbols returned +to be filtered based on either the name of the function, or the type +signature of the function. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info functions}. + +@subsubheading Example +@smallexample +(gdb) +-symbol-info-functions +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{line="36",definition="void f4(int *);"@}, + @{line="42",definition="int main();"@}, + @{line="30",definition="static my_int_t f1(int, int);"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + definitions=[@{line="33",definition="float f2(another_float_t);"@}, + @{line="39",definition="int f3(another_int_t);"@}, + @{line="27",definition="static another_float_t f1(int);"@}]@}]@} +(gdb) +-symbol-info-functions --name f1 +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{line="30",definition="static my_int_t f1(int, int);"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + definitions=[@{line="27",definition="static another_float_t f1(int);"@}]@}]@} +(gdb) +-symbol-info-functions --type void +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{line="36",definition="void f4(int *);"@}]@}]@} +(gdb) +-symbol-info-functions --include-nondebug +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{line="36",definition="void f4(int *);"@}, + @{line="42",definition="int main();"@}, + @{line="30",definition="static my_int_t f1(int, int);"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + definitions=[@{line="33",definition="float f2(another_float_t);"@}, + @{line="39",definition="int f3(another_int_t);"@}, + @{line="27",definition="static another_float_t f1(int);"@}]@}], + nondebug= + [@{address="0x0000000000400398",name="_init"@}, + @{address="0x00000000004003b0",name="_start"@}, + ... + ]@} +@end smallexample + +@subheading The @code{-symbol-info-types} Command +@findex -symbol-info-types +@anchor{-symbol-info-types} @subsubheading Synopsis @smallexample - -symbol-info-function + -symbol-info-types [--name @var{name_regexp}] @end smallexample -Show which function the symbol lives in. +@noindent +Returns a list of all defined types. The types are grouped by source +file, and the line number on which each user defined type is defined. +Some base types are not defined in the source code but are added to +the debug information by the compiler, for example @code{int}, +@code{float}, etc, these types do not have an associated line number. + +The options @code{--name} allows the list of types returned to be +filtered by name. @subsubheading @value{GDBN} Command -@samp{gdb_get_function} in @code{gdbtk}. +The corresponding @value{GDBN} command is @samp{info types}. @subsubheading Example -N.A. +@smallexample +(gdb) +-symbol-info-types +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{definition="float"@}, + @{definition="int"@}, + @{line="27",definition="typedef int my_int_t;"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + definitions=[@{line="24",definition="typedef float another_float_t;"@}, + @{line="23",definition="typedef int another_int_t;"@}, + @{definition="float"@}, + @{definition="int"@}]@}]@} +(gdb) +-symbol-info-types --name _int_ +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{line="27",definition="typedef int my_int_t;"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + definitions=[@{line="23",definition="typedef int another_int_t;"@}]@}]@} +@end smallexample + +@subheading The @code{-symbol-info-variables} Command +@findex -symbol-info-variables +@anchor{-symbol-info-variables} + +@subsubheading Synopsis + +@smallexample + -symbol-info-variables [--include-nondebug] [--type @var{type_regexp}] + [--name @var{name_regexp}] +@end smallexample + +@noindent +Returns a list containing the names and types for all global variables +taken from the debug information. The variables are grouped by source +file, and the line number on which each variable is definedd given. + +When @code{--include-nondebug} is passed then the output also includes +data symbols from the symbol table. +The options @code{--type} and @code{--name} allow the symbols returned +to be filtered based on either the name of the variable, or the type +of the variable. +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info variables}. + +@subsubheading Example +@smallexample +(gdb) +-symbol-info-variables +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{line="25",definition="static float global_f1;"@}, + @{line="24",definition="static int global_i1;"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + definitions=[@{line="21",definition="int global_f2;"@}, + @{line="20",definition="int global_i2;"@}, + @{line="19",definition="static float global_f1;"@}, + @{line="18",definition="static int global_i1;"@}]@}]@} +(gdb) +-symbol-info-variables --name f1 +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{line="25",definition="static float global_f1;"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + definitions=[@{line="19",definition="static float global_f1;"@}]@}]@} +(gdb) +-symbol-info-variables --type float +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{line="25",definition="static float global_f1;"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + definitions=[@{line="19",definition="static float global_f1;"@}]@}]@} +(gdb) +-symbol-info-variables --include-nondebug +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + definitions=[@{line="25",definition="static float global_f1;"@}, + @{line="24",definition="static int global_i1;"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + definitions=[@{line="21",definition="int global_f2;"@}, + @{line="20",definition="int global_i2;"@}, + @{line="19",definition="static float global_f1;"@}, + @{line="18",definition="static int global_i1;"@}]@}], + nondebug= + [@{address="0x00000000004005d0",name="_IO_stdin_used"@}, + @{address="0x00000000004005d8",name="__dso_handle"@} + ... + ]@} +@end smallexample + +@ignore @subheading The @code{-symbol-info-line} Command @findex -symbol-info-line diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 37eab01de9e..df9f25fcbd0 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -151,6 +151,9 @@ static struct mi_cmd mi_cmds[] = DEF_MI_CMD_MI_1 ("stack-select-frame", mi_cmd_stack_select_frame, &mi_suppress_notification.user_selected_context), DEF_MI_CMD_MI ("symbol-list-lines", mi_cmd_symbol_list_lines), + DEF_MI_CMD_MI ("symbol-info-functions", mi_cmd_symbol_info_functions), + DEF_MI_CMD_MI ("symbol-info-variables", mi_cmd_symbol_info_variables), + DEF_MI_CMD_MI ("symbol-info-types", mi_cmd_symbol_info_types), DEF_MI_CMD_CLI ("target-attach", "attach", 1), DEF_MI_CMD_MI ("target-detach", mi_cmd_target_detach), DEF_MI_CMD_CLI ("target-disconnect", "disconnect", 0), diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h index 91ce4cd4070..5fa4fafbb05 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -94,6 +94,9 @@ extern mi_cmd_argv_ftype mi_cmd_stack_list_locals; extern mi_cmd_argv_ftype mi_cmd_stack_list_variables; extern mi_cmd_argv_ftype mi_cmd_stack_select_frame; extern mi_cmd_argv_ftype mi_cmd_symbol_list_lines; +extern mi_cmd_argv_ftype mi_cmd_symbol_info_functions; +extern mi_cmd_argv_ftype mi_cmd_symbol_info_variables; +extern mi_cmd_argv_ftype mi_cmd_symbol_info_types; extern mi_cmd_argv_ftype mi_cmd_target_detach; extern mi_cmd_argv_ftype mi_cmd_target_file_get; extern mi_cmd_argv_ftype mi_cmd_target_file_put; diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c index 63142e8e7e9..6c0cefcf88c 100644 --- a/gdb/mi/mi-symbol-cmds.c +++ b/gdb/mi/mi-symbol-cmds.c @@ -21,6 +21,8 @@ #include "symtab.h" #include "objfiles.h" #include "ui-out.h" +#include "source.h" +#include "mi-getopt.h" /* Print the list of all pc addresses and lines of code for the provided (full or base) source file name. The entries are sorted @@ -59,3 +61,196 @@ mi_cmd_symbol_list_lines (const char *command, char **argv, int argc) uiout->field_signed ("line", SYMTAB_LINETABLE (s)->item[i].line); } } + +/* This is the guts of the commands '-symbol-info-functions', + '-symbol-info-variables', and '-symbol-info-types'. It calls + search_symbols to find all matches and then prints the matching + [m]symbols in an MI structured format. This is similar to + symtab_symbol_info in symtab.c. */ + +static void +mi_symbol_info (bool exclude_minsyms, const char *regexp, + enum search_domain kind, const char *t_regexp) +{ + struct ui_out *uiout = current_uiout; + + /* Must make sure that if we're interrupted, symbols gets freed. */ + std::vector symbols = search_symbols (regexp, kind, + t_regexp, 0, NULL, + exclude_minsyms); + + /* The outer container for all the matched symbols. */ + ui_out_emit_tuple all_matching_symbols (uiout, "symbols"); + + /* The order of these optional emitters is critical as they will be + deleted in reverse order, which is important as these are popped from + the uiout stack as they are destroyed. */ + gdb::optional debug_func_emitter_outer; + gdb::optional debug_func_emitter_symtab; + gdb::optional debug_func_emitter_symbols; + gdb::optional nondebug_func_emitter; + + const symtab *last_symtab = nullptr; + + for (const symbol_search &p : symbols) + { + QUIT; + + if (p.msymbol.minsym != NULL) + { + if (debug_func_emitter_outer.has_value ()) + { + gdb_assert (debug_func_emitter_symbols.has_value ()); + gdb_assert (debug_func_emitter_symtab.has_value ()); + debug_func_emitter_symbols.reset (); + debug_func_emitter_symtab.reset (); + debug_func_emitter_outer.reset (); + } + + if (!nondebug_func_emitter.has_value ()) + nondebug_func_emitter.emplace (uiout, "nondebug"); + struct bound_minimal_symbol msymbol = p.msymbol; + struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile); + ui_out_emit_tuple tuple_emitter (uiout, NULL); + uiout->field_core_addr ("address", gdbarch, + BMSYMBOL_VALUE_ADDRESS (msymbol)); + uiout->field_string ("name", MSYMBOL_PRINT_NAME (msymbol.minsym)); + } + else + { + struct symbol *sym = p.symbol; + struct symtab *s = symbol_symtab (sym); + + /* All debug symbols should appear in the list before all + non-debug symbols. */ + gdb_assert (!nondebug_func_emitter.has_value ()); + + /* Start the list of debug symbols. */ + if (!debug_func_emitter_outer.has_value ()) + debug_func_emitter_outer.emplace (uiout, "debug"); + + if (s != last_symtab) + { + /* Reset a possible previous symbol list within a symtab. */ + debug_func_emitter_symbols.reset (); + debug_func_emitter_symtab.reset (); + + /* Start a new symtab and symbol list within the symtab. */ + debug_func_emitter_symtab.emplace (uiout, nullptr); + uiout->field_string ("filename", + symtab_to_filename_for_display (s)); + uiout->field_string ("fullname", symtab_to_fullname (s)); + debug_func_emitter_symbols.emplace (uiout, "definitions"); + + /* Record the current symtab. */ + last_symtab = s; + } + + ui_out_emit_tuple tuple_emitter (uiout, NULL); + if (SYMBOL_LINE (sym) != 0) + uiout->field_unsigned ("line", SYMBOL_LINE (sym)); + std::string str = symbol_to_info_string (sym, p.block, kind); + uiout->field_string ("definition", str.c_str ()); + } + } +} + +/* Helper for mi_cmd_symbol_info_{functions,variables} - depending on KIND. + Processes command line options from ARGV and ARGC. */ + +static void +mi_info_functions_or_variables (enum search_domain kind, char **argv, int argc) +{ + const char *regexp = nullptr; + const char *t_regexp = nullptr; + bool exclude_minsyms = true; + + enum opt + { + INCLUDE_NONDEBUG_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT + }; + static const struct mi_opt opts[] = + { + {"-include-nondebug" , INCLUDE_NONDEBUG_OPT, 0}, + {"-type", TYPE_REGEXP_OPT, 1}, + {"-name", NAME_REGEXP_OPT, 1}, + { 0, 0, 0 } + }; + + int oind = 0; + char *oarg = nullptr; + + while (1) + { + const char *cmd_string + = ((kind == FUNCTIONS_DOMAIN) + ? "-symbol-info-functions" : "-symbol-info-variables"); + int opt = mi_getopt (cmd_string, argc, argv, opts, &oind, &oarg); + if (opt < 0) + break; + switch ((enum opt) opt) + { + case INCLUDE_NONDEBUG_OPT: + exclude_minsyms = false; + break; + case TYPE_REGEXP_OPT: + t_regexp = oarg; + break; + case NAME_REGEXP_OPT: + regexp = oarg; + break; + } + } + + mi_symbol_info (exclude_minsyms, regexp, kind, t_regexp); +} + +/* Implement -symbol-info-functions command. */ +void +mi_cmd_symbol_info_functions (const char *command, char **argv, int argc) +{ + mi_info_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc); +} + +/* Implement -symbol-info-variables command. */ +void +mi_cmd_symbol_info_variables (const char *command, char **argv, int argc) +{ + mi_info_functions_or_variables (VARIABLES_DOMAIN, argv, argc); +} + +/* Implement -symbol-info-types command. */ +void +mi_cmd_symbol_info_types (const char *command, char **argv, int argc) +{ + const char *regexp = nullptr; + + enum opt + { + NAME_REGEXP_OPT + }; + static const struct mi_opt opts[] = + { + {"-name", NAME_REGEXP_OPT, 1}, + { 0, 0, 0 } + }; + + int oind = 0; + char *oarg = nullptr; + + while (1) + { + int opt = mi_getopt ("-symbol-info-types", argc, argv, opts, + &oind, &oarg); + if (opt < 0) + break; + switch ((enum opt) opt) + { + case NAME_REGEXP_OPT: + regexp = oarg; + break; + } + } + + mi_symbol_info (true, regexp, TYPES_DOMAIN, nullptr); +} diff --git a/gdb/testsuite/gdb.mi/mi-sym-info-1.c b/gdb/testsuite/gdb.mi/mi-sym-info-1.c new file mode 100644 index 00000000000..9b6dc7396ad --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-sym-info-1.c @@ -0,0 +1,48 @@ +/* Copyright 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +/* Function and variables declared in mi-sym-info-2.c. */ +extern float f2 (float arg); +extern int f3 (int arg); +extern int global_i2; +extern float global_f2; + +static int global_i1; +static float global_f1; + +typedef int my_int_t; + +static my_int_t +f1 (int arg1, int arg2) +{ + return arg1 + arg2; +} + +void +f4 (int *arg) +{ + (*arg)++; +} + +int +main () +{ + int v = f3 (4); + f4 (&v); + float tmp = f2 (1.0); + return f1 (3, v) + ((int) tmp); +} diff --git a/gdb/testsuite/gdb.mi/mi-sym-info-2.c b/gdb/testsuite/gdb.mi/mi-sym-info-2.c new file mode 100644 index 00000000000..c80877d8e7b --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-sym-info-2.c @@ -0,0 +1,43 @@ +/* Copyright 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +static int global_i1; +static float global_f1; +int global_i2; +int global_f2; + +typedef int another_int_t; +typedef float another_float_t; + +static another_float_t +f1 (int arg) +{ + return (float) arg; +} + +float +f2 (another_float_t arg) +{ + return arg + f1 (1); +} + +int +f3 (another_int_t arg) +{ + return arg + 2; +} + diff --git a/gdb/testsuite/gdb.mi/mi-sym-info.exp b/gdb/testsuite/gdb.mi/mi-sym-info.exp new file mode 100644 index 00000000000..ce7216be7fa --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-sym-info.exp @@ -0,0 +1,179 @@ +# 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 . + +# Test -symbol-info-functions, -symbol-info-variables, and +# -symbol-info-types. + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +standard_testfile mi-sym-info-1.c mi-sym-info-2.c + +if {[prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $srcfile2] {debug}]} { + return -1 +} + +gdb_exit +if {[mi_gdb_start]} { + continue +} + +mi_run_to_main + +set qstr "\"\[^\"\]+\"" +set fun_re "\{line=\"$decimal\",definition=${qstr}\}" +set type_re "\{(?:line=\"$decimal\",)*definition=${qstr}\}" +set def_list "\\\[${fun_re}(?:,$fun_re)*\\\]" +set type_def_list "\\\[${type_re}(?:,$type_re)*\\\]" +set symtab_re \ + "\{filename=${qstr},fullname=${qstr},definitions=${def_list}\}" +set symtab_type_re \ + "\{filename=${qstr},fullname=${qstr},definitions=${type_def_list}\}" +set debug_only_syms \ + "symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\]\}" +set all_syms \ + "symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\],nondebug=\\\[.*\\\]\}" +set type_syms \ + "symbols=\{debug=\\\[${symtab_type_re}(?:,${symtab_type_re})*\\\]\}" + +# Fetch all functions, variables and types without any non-debug +# symbols. +mi_gdb_test "111-symbol-info-functions" \ + "111\\^done,${debug_only_syms}" \ + "List all functions from debug information only" + +mi_gdb_test "112-symbol-info-variables" \ + "112\\^done,${debug_only_syms}" \ + "List all variables from debug information only" + +mi_gdb_test "113-symbol-info-types" \ + "113\\^done,${type_syms}" \ + "List all types" + +# Fetch functions and variables but also grab the non-debug symbols +# (from the symbol table). There's often so much output output from +# this command that we overflow expect's buffers, avoid this by +# fetching the output piece by piece. +set testname "List all functions" +gdb_test_multiple "114-symbol-info-functions --include-nondebug" ${testname} { + -re "114\\^done,symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\],nondebug=\\\[" { + exp_continue + } + + -re "\{address=${qstr},name=${qstr}\}," { + exp_continue + } + + -re "\{address=${qstr},name=${qstr}\}\\\]\}\r\n${mi_gdb_prompt}$" { + pass ${testname} + } +} + +set testname "List all variables" +gdb_test_multiple "115-symbol-info-variables --include-nondebug" ${testname} { + -re "115\\^done,symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\],nondebug=\\\[" { + verbose -log "Got the first part of the input" + exp_continue + } + + -re "\{address=${qstr},name=${qstr}\}," { + exp_continue + } + + -re "\{address=${qstr},name=${qstr}\}\\\]\}\r\n${mi_gdb_prompt}$" { + pass ${testname} + } +} + +# Filter functions by name and type. +set lineno [gdb_get_line_number "f3 (another_int_t arg)" ${srcfile2}] +mi_gdb_test "116-symbol-info-functions --name f3" \ + [join \ + [list \ + "116\\^done,symbols=\{debug=\\\[" \ + "\{filename=\"\[^\"\]+${srcfile2}\"," \ + "fullname=\"\[^\"\]+${srcfile2}\"," \ + "definitions=\\\[" \ + "\{line=\"${lineno}\"," \ + "definition=\"int f3\\(another_int_t\\);\"\}" \ + "\\\]\}\\\]\}" ] "" ] \ + "List all functions matching pattern f3" + +set lineno [gdb_get_line_number "f4 (int *arg)" ${srcfile}] +mi_gdb_test "117-symbol-info-functions --type void" \ + [join \ + [list \ + "117\\^done,symbols=\{debug=\\\[" \ + "\{filename=\"\[^\"\]+${srcfile}\"," \ + "fullname=\"\[^\"\]+${srcfile}\"," \ + "definitions=\\\[\{line=\"${lineno}\"," \ + "definition=\"void f4\\(int \\*\\);\"\}" \ + "\\\]\}\\\]\}" ] "" ] \ + "List all functions matching type void" + +# Filter variables by name and type. +set lineno [gdb_get_line_number "int global_f2;" ${srcfile2}] +mi_gdb_test "118-symbol-info-variables --name global_f2" \ + [join \ + [list \ + "118\\^done,symbols=\{debug=\\\[" \ + "\{filename=\"\[^\"\]+${srcfile2}\"," \ + "fullname=\"\[^\"\]+${srcfile2}\"," \ + "definitions=\\\[" \ + "\{line=\"${lineno}\"," \ + "definition=\"int global_f2;\"\}\\\]\}\\\]\}" ] ""] \ + "List all variables matching pattern global_f2" + +set lineno1 [gdb_get_line_number "static float global_f1;" ${srcfile}] +set lineno2 [gdb_get_line_number "static float global_f1;" ${srcfile2}] +mi_gdb_test "119-symbol-info-variables --type float" \ + [join \ + [list \ + "119\\^done,symbols=" \ + "\{debug=\\\[" \ + "\{filename=\"\[^\"\]+${srcfile}\"," \ + "fullname=\"\[^\"\]+${srcfile}\"," \ + "definitions=\\\[" \ + "\{line=\"${lineno1}\"," \ + "definition=\"static float global_f1;\"\}\\\]\}," \ + "\{filename=\"\[^\"\]+${srcfile2}\"," \ + "fullname=\"\[^\"\]+${srcfile2}\"," \ + "definitions=\\\[" \ + "\{line=\"${lineno2}\"," \ + "definition=\"static float global_f1;\"\}" \ + "\\\]\}\\\]\}"] "" ] \ + "List all variables matching type float" + +# Fetch types, filtering by name. +set lineno1 [gdb_get_line_number "typedef int my_int_t;" ${srcfile}] +set lineno2 [gdb_get_line_number "typedef int another_int_t;" ${srcfile2}] +mi_gdb_test "120-symbol-info-types --name _int_" \ + [join \ + [list \ + "120\\^done,symbols=" \ + "\{debug=\\\[" \ + "\{filename=\"\[^\"\]+${srcfile}\"," \ + "fullname=\"\[^\"\]+${srcfile}\"," \ + "definitions=\\\[" \ + "\{line=\"${lineno1}\"," \ + "definition=\"typedef int my_int_t;\"\}\\\]\}," \ + "\{filename=\"\[^\"\]+${srcfile2}\"," \ + "fullname=\"\[^\"\]+${srcfile2}\"," \ + "definitions=\\\[" \ + "\{line=\"${lineno2}\"," \ + "definition=\"typedef int another_int_t;\"\}" \ + "\\\]\}\\\]\}"] "" ] \ + "List all types matching _int_"