Compare commits

...

4 Commits

Author SHA1 Message Date
Simon Marchi
90c3c3ef0b Hi Andrew
Change-Id: I695d9860d6f7dae86f966dfc0524b934660478da
2019-11-21 00:27:37 -05:00
Andrew Burgess
379876d22a gdb/mi: Add new commands -symbol-info-{functions,variables,types}
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 (mi_cmds): 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_info_one_symbol_details): New function.
	(class mi_symbol_info_emitter): New class.
	(mi_symbol_info): New function.
	(mi_info_functions_or_variables): New function.
	(mi_cmd_symbol_info_functions): New function.
	(mi_cmd_symbol_info_types): New function.
	(mi_cmd_symbol_info_variables): 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.

Change-Id: Ic2fc6a6750bbce91cdde2344791014e5ef45642d
2019-11-20 23:11:41 -05:00
Andrew Burgess
ce8ccaa665 gdb: Split print_symbol_info into two parts
Split the function print_symbol_info into two parts, the new worker
core returns a string, which print_symbol_info then prints.  This will
be useful in a later commit when some new MI commands will be added
which will use the worker core to fill some MI output fields.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* symtab.c (symbol_to_info_string): New function, most content
	moved from print_symbol_info, but updated to return a std::string.
	(print_symbol_info): Update to use symbol_to_info_string and print
	returned string.
	* symtab.h (symbol_to_info_string): Declare new function.

Change-Id: I6454ce43cacb61d32fbadb9e3655e70823085777
2019-11-20 23:11:40 -05:00
Andrew Burgess
2c05882ed4 gdb: Introduce global_symbol_searcher
Introduce a new class to wrap up the parameters needed for the
function search_symbols, which has now become a member function of
this new class.

The motivation is that search_symbols already takes a lot of
parameters, and a future commit is going to add even more.  This
commit hopefully makes collecting the state required for a search
easier.

As part of this conversion the list of filenames in which to search
has been converted to a std::vector.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* python/python.c (gdbpy_rbreak): Convert to using
	global_symbol_searcher.
	* symtab.c (file_matches): Convert return type to bool, change
	file list to std::vector.
	(search_symbols): Rename to...
	(global_symbol_searcher::search): ...this and update now its
	a member function of global_symbol_searcher.  Take account of the
	changes to file_matches.
	(symtab_symbol_info): Convert to using global_symbol_searcher.
	(rbreak_command): Likewise.
	(search_module_symbols): Likewise.
	* symtab.h (enum symbol_search): Update comment.
	(search_symbols): Remove declaration.
	(class global_symbol_searcher): New class.

Change-Id: I488ab292a892d9e9e84775c632c5f198b6ad3710
2019-11-20 23:11:40 -05:00
14 changed files with 938 additions and 147 deletions

View File

@@ -1,3 +1,45 @@
2019-11-01 Andrew Burgess <andrew.burgess@embecosm.com>
* mi/mi-cmds.c (mi_cmds): 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_info_one_symbol_details): New function.
(class mi_symbol_info_emitter): New class.
(mi_symbol_info): New function.
(mi_info_functions_or_variables): New function.
(mi_cmd_symbol_info_functions): New function.
(mi_cmd_symbol_info_types): New function.
(mi_cmd_symbol_info_variables): New function.
* NEWS: Mention new commands.
2019-11-01 Andrew Burgess <andrew.burgess@embecosm.com>
* symtab.c (symbol_to_info_string): New function, most content
moved from print_symbol_info, but updated to return a std::string.
(print_symbol_info): Update to use symbol_to_info_string and print
returned string.
* symtab.h (symbol_to_info_string): Declare new function.
2019-11-01 Andrew Burgess <andrew.burgess@embecosm.com>
* python/python.c (gdbpy_rbreak): Convert to using
global_symbol_searcher.
* symtab.c (file_matches): Convert return type to bool, change
file list to std::vector.
(search_symbols): Rename to...
(global_symbol_searcher::search): ...this and update now its
a member function of global_symbol_searcher. Take account of the
changes to file_matches.
(symtab_symbol_info): Convert to using global_symbol_searcher.
(rbreak_command): Likewise.
(search_module_symbols): Likewise.
* symtab.h (enum symbol_search): Update comment.
(search_symbols): Remove declaration.
(class global_symbol_searcher): New class.
2019-11-19 Tom Tromey <tom@tromey.com>
* tui/tui-win.c (tui_partial_win_by_name): Move from tui-data.c.

View File

@@ -353,6 +353,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).

View File

@@ -1,3 +1,9 @@
2019-11-01 Andrew Burgess <andrew.burgess@embecosm.com>
* doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command
-symbol-info-functions, -symbol-info-types, and
-symbol-info-variables.
2019-11-14 Tom de Vries <tdevries@suse.de>
* gdb.texinfo: Fix typos.

View File

@@ -33874,27 +33874,283 @@ There's no equivalent @value{GDBN} command. @code{gdbtk} has
@subsubheading Example
N.A.
@end ignore
@subheading The @code{-symbol-info-function} Command
@findex -symbol-info-function
@subheading The @code{-symbol-info-functions} Command
@findex -symbol-info-functions
@anchor{-symbol-info-functions}
@subsubheading Synopsis
@smallexample
-symbol-info-function
-symbol-info-functions [--include-nondebug]
[--type @var{type_regexp}]
[--name @var{name_regexp}]
@end smallexample
Show which function the symbol lives in.
@noindent
Return a list containing the names and types for all global functions
taken from the debug information. The functions are grouped by source
file, and shown with the line number on which each function is
defined.
The @code{--include-nondebug} option causes the output to include
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
@samp{gdb_get_function} in @code{gdbtk}.
The corresponding @value{GDBN} command is @samp{info functions}.
@subsubheading Example
N.A.
@smallexample
@group
(gdb)
-symbol-info-functions
^done,symbols=
@{debug=
[@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
symbols=[@{line="36", name="f4", type="void (int *)",
description="void f4(int *);"@},
@{line="42", name="main", type="int ()",
description="int main();"@},
@{line="30", name="f1", type="my_int_t (int, int)",
description="static my_int_t f1(int, int);"@}]@},
@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
symbols=[@{line="33", name="f2", type="float (another_float_t)",
description="float f2(another_float_t);"@},
@{line="39", name="f3", type="int (another_int_t)",
description="int f3(another_int_t);"@},
@{line="27", name="f1", type="another_float_t (int)",
description="static another_float_t f1(int);"@}]@}]@}
@end group
@group
(gdb)
-symbol-info-functions --name f1
^done,symbols=
@{debug=
[@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
symbols=[@{line="30", name="f1", type="my_int_t (int, int)",
description="static my_int_t f1(int, int);"@}]@},
@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
symbols=[@{line="27", name="f1", type="another_float_t (int)",
description="static another_float_t f1(int);"@}]@}]@}
@end group
@group
(gdb)
-symbol-info-functions --type void
^done,symbols=
@{debug=
[@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
symbols=[@{line="36", name="f4", type="void (int *)",
description="void f4(int *);"@}]@}]@}
@end group
@group
(gdb)
-symbol-info-functions --include-nondebug
^done,symbols=
@{debug=
[@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
symbols=[@{line="36", name="f4", type="void (int *)",
description="void f4(int *);"@},
@{line="42", name="main", type="int ()",
description="int main();"@},
@{line="30", name="f1", type="my_int_t (int, int)",
description="static my_int_t f1(int, int);"@}]@},
@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
symbols=[@{line="33", name="f2", type="float (another_float_t)",
description="float f2(another_float_t);"@},
@{line="39", name="f3", type="int (another_int_t)",
description="int f3(another_int_t);"@},
@{line="27", name="f1", type="another_float_t (int)",
description="static another_float_t f1(int);"@}]@}],
nondebug=
[@{address="0x0000000000400398",name="_init"@},
@{address="0x00000000004003b0",name="_start"@},
...
]@}
@end group
@end smallexample
@subheading The @code{-symbol-info-types} Command
@findex -symbol-info-types
@anchor{-symbol-info-types}
@subsubheading Synopsis
@smallexample
-symbol-info-types [--name @var{name_regexp}]
@end smallexample
@noindent
Return a list of all defined types. The types are grouped by source
file, and shown with 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 option @code{--name} allows the list of types returned to be
filtered by name.
@subsubheading @value{GDBN} Command
The corresponding @value{GDBN} command is @samp{info types}.
@subsubheading Example
@smallexample
@group
(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",
symbols=[@{name="float"@},
@{name="int"@},
@{line="27",name="typedef int my_int_t;"@}]@},
@{filename="gdb.mi/mi-sym-info-2.c",
fullname="/project/gdb.mi/mi-sym-info-2.c",
symbols=[@{line="24",name="typedef float another_float_t;"@},
@{line="23",name="typedef int another_int_t;"@},
@{name="float"@},
@{name="int"@}]@}]@}
@end group
@group
(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",
symbols=[@{line="27",name="typedef int my_int_t;"@}]@},
@{filename="gdb.mi/mi-sym-info-2.c",
fullname="/project/gdb.mi/mi-sym-info-2.c",
symbols=[@{line="23",name="typedef int another_int_t;"@}]@}]@}
@end group
@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
Return a list containing the names and types for all global variables
taken from the debug information. The variables are grouped by source
file, and shown with the line number on which each variable is
defined.
The @code{--include-nondebug} option causes the output to include
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
@group
(gdb)
-symbol-info-variables
^done,symbols=
@{debug=
[@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
symbols=[@{line="25",name="global_f1",type="float",
description="static float global_f1;"@},
@{line="24",name="global_i1",type="int",
description="static int global_i1;"@}]@},
@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
symbols=[@{line="21",name="global_f2",type="int",
description="int global_f2;"@},
@{line="20",name="global_i2",type="int",
description="int global_i2;"@},
@{line="19",name="global_f1",type="float",
description="static float global_f1;"@},
@{line="18",name="global_i1",type="int",
description="static int global_i1;"@}]@}]@}
@end group
@group
(gdb)
-symbol-info-variables --name f1
^done,symbols=
@{debug=
[@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
symbols=[@{line="25",name="global_f1",type="float",
description="static float global_f1;"@}]@},
@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
symbols=[@{line="19",name="global_f1",type="float",
description="static float global_f1;"@}]@}]@}
@end group
@group
(gdb)
-symbol-info-variables --type float
^done,symbols=
@{debug=
[@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
symbols=[@{line="25",name="global_f1",type="float",
description="static float global_f1;"@}]@},
@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
symbols=[@{line="19",name="global_f1",type="float",
description="static float global_f1;"@}]@}]@}
@end group
@group
(gdb)
-symbol-info-variables --include-nondebug
^done,symbols=
@{debug=
[@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c",
symbols=[@{line="25",name="global_f1",type="float",
description="static float global_f1;"@},
@{line="24",name="global_i1",type="int",
description="static int global_i1;"@}]@},
@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c",
symbols=[@{line="21",name="global_f2",type="int",
description="int global_f2;"@},
@{line="20",name="global_i2",type="int",
description="int global_i2;"@},
@{line="19",name="global_f1",type="float",
description="static float global_f1;"@},
@{line="18",name="global_i1",type="int",
description="static int global_i1;"@}]@}],
nondebug=
[@{address="0x00000000004005d0",name="_IO_stdin_used"@},
@{address="0x00000000004005d8",name="__dso_handle"@}
...
]@}
@end group
@end smallexample
@ignore
@subheading The @code{-symbol-info-line} Command
@findex -symbol-info-line

View File

@@ -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),

View File

@@ -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_types;
extern mi_cmd_argv_ftype mi_cmd_symbol_info_variables;
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;

View File

@@ -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,215 @@ mi_cmd_symbol_list_lines (const char *command, char **argv, int argc)
uiout->field_signed ("line", SYMTAB_LINETABLE (s)->item[i].line);
}
}
/* Used by the -symbol-info-* and -symbol-info-module-* commands to print
information about the symbol SYM in a block of index BLOCK (either
GLOBAL_BLOCK or STATIC_BLOCK). KIND is the kind of symbol we searched
for in order to find SYM, which impact which fields are displayed in the
results. */
static void
output_debug_symbol (ui_out *uiout, enum search_domain kind,
struct symbol *sym, int block)
{
ui_out_emit_tuple tuple_emitter (uiout, NULL);
if (SYMBOL_LINE (sym) != 0)
uiout->field_unsigned ("line", SYMBOL_LINE (sym));
uiout->field_string ("name", SYMBOL_PRINT_NAME (sym));
if (kind == FUNCTIONS_DOMAIN || kind == VARIABLES_DOMAIN)
{
string_file tmp_stream;
type_print (SYMBOL_TYPE (sym), "", &tmp_stream, -1);
uiout->field_string ("type", tmp_stream.string ());
std::string str = symbol_to_info_string (sym, block, kind);
uiout->field_string ("description", str.c_str ());
}
}
/* Actually output one nondebug symbol, puts a tuple emitter in place
and then outputs the fields for this msymbol. */
static void
output_nondebug_symbol (ui_out *uiout,
const struct bound_minimal_symbol &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));
}
/* 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. All the arguments are used to
initialise a SEARCH_SYMBOLS_SPEC, see symtab.h for a description of
their meaning. */
static void
mi_symbol_info (enum search_domain kind, const char *regexp,
const char *t_regexp, bool exclude_minsyms)
{
/* Must make sure that if we're interrupted, symbols gets freed. */
global_symbol_searcher sym_search (kind, regexp, t_regexp, exclude_minsyms);
std::vector<symbol_search> symbols = sym_search.search ();
ui_out *uiout = current_uiout;
int i = 0;
ui_out_emit_tuple outer_symbols_emitter (uiout, "symbols");
/* Debug symbols are placed first. */
if (i < symbols.size () && symbols[i].msymbol.minsym == nullptr)
{
ui_out_emit_list debug_symbols_list_emitter (uiout, "debug");
/* As long as we have debug symbols... */
while (i < symbols.size () && symbols[i].msymbol.minsym == nullptr)
{
symtab *symtab = symbol_symtab (symbols[i].symbol);
ui_out_emit_tuple symtab_tuple_emitter (uiout, nullptr);
uiout->field_string ("filename", symtab_to_filename_for_display (symtab));
uiout->field_string ("fullname", symtab_to_fullname (symtab));
ui_out_emit_list symbols_list_emitter (uiout, "symbols");
/* As long as we have debug symbols from this symtab... */
while (i < symbols.size ()
&& symbols[i].msymbol.minsym == nullptr
&& symbol_symtab (symbols[i].symbol) == symtab)
{
symbol_search &s = symbols[i];
output_debug_symbol(uiout, kind, s.symbol, s.block);
i++;
}
}
}
/* Non-debug symbols are placed after. */
if (i < symbols.size ())
{
ui_out_emit_list nondebug_symbols_list_emitter (uiout, "nondebug");
/* As long as we have nondebug symbols... */
while (i < symbols.size ())
{
gdb_assert (symbols[i].msymbol.minsym != nullptr);
output_nondebug_symbol(uiout, symbols[i].msymbol);
i++;
}
}
}
/* 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 (kind, regexp, t_regexp, exclude_minsyms);
}
/* 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-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 (TYPES_DOMAIN, regexp, nullptr, true);
}
/* 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);
}

View File

@@ -645,19 +645,6 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
static PyObject *
gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw)
{
/* A simple type to ensure clean up of a vector of allocated strings
when a C interface demands a const char *array[] type
interface. */
struct symtab_list_type
{
~symtab_list_type ()
{
for (const char *elem: vec)
xfree ((void *) elem);
}
std::vector<const char *> vec;
};
char *regex = NULL;
std::vector<symbol_search> symbols;
unsigned long count = 0;
@@ -667,7 +654,6 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw)
unsigned int throttle = 0;
static const char *keywords[] = {"regex","minsyms", "throttle",
"symtabs", NULL};
symtab_list_type symtab_paths;
if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!IO", keywords,
&regex, &PyBool_Type,
@@ -684,6 +670,12 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw)
minsyms_p = cmp;
}
global_symbol_searcher spec (FUNCTIONS_DOMAIN, regex);
SCOPE_EXIT {
for (const char *elem : spec.filenames)
xfree ((void *) elem);
};
/* The "symtabs" keyword is any Python iterable object that returns
a gdb.Symtab on each iteration. If specified, iterate through
the provided gdb.Symtabs and extract their full path. As
@@ -729,20 +721,13 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw)
/* Make sure there is a definite place to store the value of
filename before it is released. */
symtab_paths.vec.push_back (nullptr);
symtab_paths.vec.back () = filename.release ();
spec.filenames.push_back (nullptr);
spec.filenames.back () = filename.release ();
}
}
if (symtab_list)
{
const char **files = symtab_paths.vec.data ();
symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL,
symtab_paths.vec.size (), files, false);
}
else
symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 0, NULL, false);
/* The search spec. */
symbols = spec.search ();
/* Count the number of symbols (both symbols and optionally minimal
symbols) so we can correctly check the throttle limit. */

View File

@@ -4339,27 +4339,24 @@ info_sources_command (const char *args, int from_tty)
printf_filtered ("\n");
}
/* Compare FILE against all the NFILES entries of FILES. If BASENAMES is
non-zero compare only lbasename of FILES. */
/* Compare FILE against all the entries of FILENAMES. If BASENAMES is
non-zero compare only lbasename of FILENAMES. */
static int
file_matches (const char *file, const char *files[], int nfiles, int basenames)
static bool
file_matches (const char *file, const std::vector<const char *> &filenames,
bool basenames)
{
int i;
if (filenames.empty ())
return true;
if (file != NULL && nfiles != 0)
for (const char *name : filenames)
{
for (i = 0; i < nfiles; i++)
{
if (compare_filenames_for_search (file, (basenames
? lbasename (files[i])
: files[i])))
return 1;
}
name = (basenames ? lbasename (name) : name);
if (compare_filenames_for_search (file, name))
return true;
}
else if (nfiles == 0)
return 1;
return 0;
return false;
}
/* Helper function for sort_search_symbols_remove_dups and qsort. Can only
@@ -4436,31 +4433,16 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
result->end ());
}
/* Search the symbol table for matches to the regular expression REGEXP,
returning the results.
Only symbols of KIND are searched:
VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
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
Within each file the results are sorted locally; each symtab's global and
static blocks are separately alphabetized.
Duplicate entries are removed.
When EXCLUDE_MINSYMS is false then matching minsyms are also returned,
otherwise they are excluded. */
/* See symtab.h. */
std::vector<symbol_search>
search_symbols (const char *regexp, enum search_domain kind,
const char *t_regexp,
int nfiles, const char *files[],
bool exclude_minsyms)
global_symbol_searcher::search () const
{
const char *regexp = m_symbol_regexp;
const char *t_regexp = m_type_regexp;
enum search_domain kind = m_kind;
bool exclude_minsyms = m_exclude_minsyms;
int nfiles = filenames.size ();
const struct blockvector *bv;
const struct block *b;
int i = 0;
@@ -4543,8 +4525,11 @@ search_symbols (const char *regexp, enum search_domain kind,
the machinery below. */
expand_symtabs_matching ([&] (const char *filename, bool basenames)
{
return file_matches (filename, files, nfiles,
basenames);
/* EXPAND_SYMTABS_MATCHING expects a callback
that returns an integer, not a boolean as
FILE_MATCHES does. */
return file_matches (filename, filenames,
basenames) ? 1 : 0;
},
lookup_name_info::match_any (),
[&] (const char *symname)
@@ -4628,12 +4613,12 @@ search_symbols (const char *regexp, enum search_domain kind,
/* Check first sole REAL_SYMTAB->FILENAME. It does
not need to be a substring of symtab_to_fullname as
it may contain "./" etc. */
if ((file_matches (real_symtab->filename, files, nfiles, 0)
if ((file_matches (real_symtab->filename, filenames, false)
|| ((basenames_may_differ
|| file_matches (lbasename (real_symtab->filename),
files, nfiles, 1))
filenames, true))
&& file_matches (symtab_to_fullname (real_symtab),
files, nfiles, 0)))
filenames, false)))
&& ((!preg.has_value ()
|| preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
NULL, 0) == 0)
@@ -4725,11 +4710,66 @@ search_symbols (const char *regexp, enum search_domain kind,
return result;
}
/* Helper function for symtab_symbol_info, this function uses
the data returned from search_symbols() to print information
regarding the match to gdb_stdout. If LAST is not NULL,
print file and line number information for the symbol as
well. Skip printing the filename if it matches LAST. */
/* See symtab.h. */
std::string
symbol_to_info_string (struct symbol *sym, int block,
enum search_domain kind)
{
std::string str;
gdb_assert (block == GLOBAL_BLOCK || block == STATIC_BLOCK);
if (kind != TYPES_DOMAIN && block == STATIC_BLOCK)
str += "static ";
/* Typedef that is not a C++ class. */
if (kind == TYPES_DOMAIN
&& SYMBOL_DOMAIN (sym) != STRUCT_DOMAIN)
{
string_file tmp_stream;
/* FIXME: For C (and C++) we end up with a difference in output here
between how a typedef is printed, and non-typedefs are printed.
The TYPEDEF_PRINT code places a ";" at the end in an attempt to
appear C-like, while TYPE_PRINT doesn't.
For the struct printing case below, things are worse, we force
printing of the ";" in this function, which is going to be wrong
for languages that don't require a ";" between statements. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_TYPEDEF)
typedef_print (SYMBOL_TYPE (sym), sym, &tmp_stream);
else
type_print (SYMBOL_TYPE (sym), "", &tmp_stream, -1);
str += tmp_stream.string ();
}
/* variable, func, or typedef-that-is-c++-class. */
else if (kind < TYPES_DOMAIN
|| (kind == TYPES_DOMAIN
&& SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN))
{
string_file tmp_stream;
type_print (SYMBOL_TYPE (sym),
(SYMBOL_CLASS (sym) == LOC_TYPEDEF
? "" : SYMBOL_PRINT_NAME (sym)),
&tmp_stream, 0);
str += tmp_stream.string ();
str += ";";
}
else if (kind == MODULES_DOMAIN)
str += SYMBOL_PRINT_NAME (sym);
return str;
}
/* Helper function for symbol info commands, for example 'info functions',
'info variables', etc. KIND is the kind of symbol we searched for, and
BLOCK is the type of block the symbols was found in, either GLOBAL_BLOCK
or STATIC_BLOCK. SYM is the symbol we found. If LAST is not NULL,
print file and line number information for the symbol as well. Skip
printing the filename if it matches LAST. */
static void
print_symbol_info (enum search_domain kind,
@@ -4756,44 +4796,11 @@ print_symbol_info (enum search_domain kind,
puts_filtered ("\t");
}
if (kind != TYPES_DOMAIN && block == STATIC_BLOCK)
printf_filtered ("static ");
/* Typedef that is not a C++ class. */
if (kind == TYPES_DOMAIN
&& SYMBOL_DOMAIN (sym) != STRUCT_DOMAIN)
{
/* FIXME: For C (and C++) we end up with a difference in output here
between how a typedef is printed, and non-typedefs are printed.
The TYPEDEF_PRINT code places a ";" at the end in an attempt to
appear C-like, while TYPE_PRINT doesn't.
For the struct printing case below, things are worse, we force
printing of the ";" in this function, which is going to be wrong
for languages that don't require a ";" between statements. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_TYPEDEF)
typedef_print (SYMBOL_TYPE (sym), sym, gdb_stdout);
else
type_print (SYMBOL_TYPE (sym), "", gdb_stdout, -1);
printf_filtered ("\n");
}
/* variable, func, or typedef-that-is-c++-class. */
else if (kind < TYPES_DOMAIN
|| (kind == TYPES_DOMAIN
&& SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN))
{
type_print (SYMBOL_TYPE (sym),
(SYMBOL_CLASS (sym) == LOC_TYPEDEF
? "" : SYMBOL_PRINT_NAME (sym)),
gdb_stdout, 0);
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));
std::string str = symbol_to_info_string (sym, block, kind);
printf_filtered ("%s\n", str.c_str ());
}
/* This help function for symtab_symbol_info() prints information
@@ -4844,9 +4851,8 @@ symtab_symbol_info (bool quiet, bool exclude_minsyms,
regexp = nullptr;
/* Must make sure that if we're interrupted, symbols gets freed. */
std::vector<symbol_search> symbols = search_symbols (regexp, kind,
t_regexp, 0, NULL,
exclude_minsyms);
global_symbol_searcher spec (kind, regexp, t_regexp, exclude_minsyms);
std::vector<symbol_search> symbols = spec.search ();
if (!quiet)
{
@@ -5085,11 +5091,9 @@ static void
rbreak_command (const char *regexp, int from_tty)
{
std::string string;
const char **files = NULL;
const char *file_name;
int nfiles = 0;
const char *file_name = nullptr;
if (regexp)
if (regexp != nullptr)
{
const char *colon = strchr (regexp, ':');
@@ -5105,17 +5109,14 @@ rbreak_command (const char *regexp, int from_tty)
while (isspace (local_name[colon_index]))
local_name[colon_index--] = 0;
file_name = local_name;
files = &file_name;
nfiles = 1;
regexp = skip_spaces (colon + 1);
}
}
std::vector<symbol_search> symbols = search_symbols (regexp,
FUNCTIONS_DOMAIN,
NULL,
nfiles, files,
false);
global_symbol_searcher spec (FUNCTIONS_DOMAIN, regexp);
if (file_name != nullptr)
spec.filenames.push_back (file_name);
std::vector<symbol_search> symbols = spec.search ();
scoped_rbreak_breakpoints finalize;
for (const symbol_search &p : symbols)
@@ -6349,17 +6350,14 @@ search_module_symbols (const char *module_regexp, const char *regexp,
std::vector<module_symbol_search> results;
/* Search for all modules matching MODULE_REGEXP. */
std::vector<symbol_search> modules = search_symbols (module_regexp,
MODULES_DOMAIN,
NULL, 0, NULL,
true);
global_symbol_searcher spec1 (MODULES_DOMAIN, module_regexp, nullptr, true);
std::vector<symbol_search> modules = spec1.search ();
/* 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);
global_symbol_searcher spec2 (kind, regexp, type_regexp, true);
std::vector<symbol_search> symbols = spec2.search ();
/* Now iterate over all MODULES, checking to see which items from
SYMBOLS are in each module. */

View File

@@ -811,7 +811,7 @@ gdb_static_assert (NR_DOMAINS <= (1 << SYMBOL_DOMAIN_BITS));
extern const char *domain_name (domain_enum);
/* Searching domains, used for `search_symbols'. Element numbers are
/* Searching domains, used when searching for symbols. Element numbers are
hardcoded in GDB, check all enum uses before changing it. */
enum search_domain
@@ -2026,11 +2026,9 @@ extern struct symbol *fixup_symbol_section (struct symbol *,
extern symbol *find_function_alias_target (bound_minimal_symbol msymbol);
/* Symbol searching */
/* Note: struct symbol_search, search_symbols, et.al. are declared here,
instead of making them local to symtab.c, for gdbtk's sake. */
/* When using search_symbols, a vector of the following structs is
returned. */
/* When using the symbol_searcher struct to search for symbols, a vector of
the following structs is returned. */
struct symbol_search
{
symbol_search (int block_, struct symbol *symbol_)
@@ -2079,12 +2077,60 @@ private:
const symbol_search &sym_b);
};
extern std::vector<symbol_search> search_symbols (const char *,
enum search_domain,
const char *,
int,
const char **,
bool);
/* In order to search for global symbols of a particular kind matching
particular regular expressions, create an instance of this structure and
call the SEARCH member function. */
class global_symbol_searcher
{
public:
/* Constructor. */
global_symbol_searcher (enum search_domain kind,
const char *symbol_regexp = nullptr,
const char *type_regexp = nullptr,
bool exclude_minsyms = false,
std::vector<const char *> filename = {})
: m_kind (kind),
m_symbol_regexp (symbol_regexp),
m_type_regexp (type_regexp),
m_exclude_minsyms (exclude_minsyms)
{
/* The symbol searching is designed to only find one kind of thing. */
gdb_assert (m_kind != ALL_DOMAIN);
}
/* Search the symbol table for matches as defined by SEARCH_SPEC.
Within each file the results are sorted locally; each symtab's global
and static blocks are separately alphabetized. Duplicate entries are
removed. */
std::vector<symbol_search> search () const;
/* The set of source files to search in for matching symbols. This is
currently public so that it can be populated after this object has
been constructed. */
std::vector<const char *> filenames;
private:
/* The kind of symbols are we searching for.
VARIABLES_DOMAIN - Search all symbols, excluding functions, type
names, and constants (enums).
FUNCTIONS_DOMAIN - Search all functions..
TYPES_DOMAIN - Search all type names.
MODULES_DOMAIN - Search all Fortran modules.
ALL_DOMAIN - Not valid for this function. */
enum search_domain m_kind;
/* Regular expression to match against the symbol name. */
const char *m_symbol_regexp = nullptr;
/* Regular expression to match against the type of the symbol. */
const char *m_type_regexp = nullptr;
/* When this flag is false then minsyms that match M_SYMBOL_REGEXP will
be included in the results, otherwise they are excluded. */
bool m_exclude_minsyms = false;
};
/* When searching for Fortran symbols within modules (functions/variables)
we return a vector of this type. The first item in the pair is the
@@ -2101,6 +2147,14 @@ extern std::vector<module_symbol_search> search_module_symbols
(const char *module_regexp, const char *regexp,
const char *type_regexp, search_domain kind);
/* Convert a global or static symbol SYM (based on BLOCK, which should be
either GLOBAL_BLOCK or STATIC_BLOCK) into a string for use in 'info'
type commands (e.g. 'info variables', 'info functions', etc). KIND is
the type of symbol that was searched for which gave us SYM. */
extern std::string symbol_to_info_string (struct symbol *sym, int block,
enum search_domain kind);
extern bool treg_matches_sym_type_name (const compiled_regex &treg,
const struct symbol *sym);

View File

@@ -1,3 +1,9 @@
2019-11-01 Andrew Burgess <andrew.burgess@embecosm.com>
* 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.
2019-11-20 Sergio Durigan Junior <sergiodj@redhat.com>
* gdb.python/py-progspace.exp: Add missing parentheses on some

View File

@@ -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 <http://www.gnu.org/licenses/>. */
/* 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);
}

View File

@@ -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 <http://www.gnu.org/licenses/>. */
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;
}

View File

@@ -0,0 +1,129 @@
# 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/>.
# 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\",name=${qstr},type=${qstr},description=${qstr}\}"
set type_re "\{(?:line=\"$decimal\",)*name=${qstr}\}"
set sym_list "\\\[${fun_re}(?:,$fun_re)*\\\]"
set type_sym_list "\\\[${type_re}(?:,$type_re)*\\\]"
set symtab_re \
"\{filename=${qstr},fullname=${qstr},symbols=${sym_list}\}"
set symtab_type_re \
"\{filename=${qstr},fullname=${qstr},symbols=${type_sym_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" \
"116\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"39\",name=\"f3\",type=\"int \\(another_int_t\\)\",description=\"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" \
"117\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"36\",name=\"f4\",type=\"void \\(int \\*\\)\",description=\"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" \
"118\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"21\",name=\"global_f2\",type=\"int\",description=\"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" \
"119\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"25\",name=\"global_f1\",type=\"float\",description=\"static float global_f1;\"\}\\\]\},\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"19\",name=\"global_f1\",type=\"float\",description=\"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_" \
"120\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"27\",name=\"my_int_t\"\}\\\]\},\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"23\",name=\"another_int_t\"\}\\\]\}\\\]\}" \
"List all types matching _int_"