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
This commit is contained in:
Andrew Burgess
2019-09-24 23:35:47 +01:00
committed by Simon Marchi
parent ce8ccaa665
commit 379876d22a
11 changed files with 828 additions and 7 deletions

View File

@@ -1,3 +1,20 @@
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

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,307 @@ 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
mi_info_one_symbol_details (enum search_domain kind,
struct symbol *sym, int block)
{
struct ui_out *uiout = current_uiout;
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 ());
}
}
/* This class is used to produce the nested structure of tuples and lists
required to present the results of the MI_SYMBOL_INFO function. */
class mi_symbol_info_emitter
{
/* When printing debug symbols we need to track the last symtab so we can
spot when we have entered a new one. */
const symtab *m_last_symtab;
/* The ui_out to which output will be sent. */
struct ui_out *m_uiout;
/* The outer container for all the matched symbols. */
ui_out_emit_tuple m_outer_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<ui_out_emit_list> m_debug_emitter;
gdb::optional<ui_out_emit_tuple> m_symtab_emitter;
gdb::optional<ui_out_emit_list> m_symbols_emitter;
gdb::optional<ui_out_emit_list> m_nondebug_emitter;
/* Called when we might want to print our first nondebug symbol in order
to shutdown any debug symbol printing that might be in progress. */
void maybe_finish_debug_output ()
{
/* If the debug emitter is in use. */
if (m_debug_emitter.has_value ())
{
/* Then we should have a symbols list inside a symtab tuple also
currently in use. */
gdb_assert (m_symbols_emitter.has_value ());
gdb_assert (m_symtab_emitter.has_value ());
/* Shut down the symbols list, symtab tuple, and debug list
emitters (in that order). We are now back to the level of the
outer_symbols tuple ready to (possibly) start a nondebug list,
though that is not done here. */
m_symbols_emitter.reset ();
m_symtab_emitter.reset ();
m_debug_emitter.reset ();
}
}
/* Return true if the nondebug emitter has been put in place. */
bool have_started_nondebug_symbol_output () const
{
return m_nondebug_emitter.has_value ();
}
/* Called before we print every nondebug symbol. If this is the first
nondebug symbol to be printed then it will setup the emitters required
to print nondebug symbols. */
void maybe_start_nondebug_symbol_output ()
{
if (!have_started_nondebug_symbol_output ())
m_nondebug_emitter.emplace (m_uiout, "nondebug");
}
/* Actually output one nondebug symbol, puts a tuple emitter in place
and then outputs the fields for this msymbol. */
void output_nondebug_symbol (const struct bound_minimal_symbol &msymbol)
{
struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile);
ui_out_emit_tuple tuple_emitter (m_uiout, NULL);
m_uiout->field_core_addr ("address", gdbarch,
BMSYMBOL_VALUE_ADDRESS (msymbol));
m_uiout->field_string ("name", MSYMBOL_PRINT_NAME (msymbol.minsym));
}
/* Called before we print every debug symbol. If this is the first debug
symbol to be printed then it will setup the top level of emitters
required to print debug symbols. */
void maybe_start_debug_symbol_output ()
{
if (!m_debug_emitter.has_value ())
m_debug_emitter.emplace (m_uiout, "debug");
}
/* Called before we print every debug symbol, S is the symtab for the
symbol to be printed. If S is different to the last symtab we printed
for then we close down the emitters for the last symtab, and create
new emitters for this new symtab. */
void setup_emitters_for_symtab (symtab *s)
{
if (s != m_last_symtab)
{
/* Reset a possible previous symbol list within a symtab. */
m_symbols_emitter.reset ();
m_symtab_emitter.reset ();
/* Start a new symtab and symbol list within the symtab. */
m_symtab_emitter.emplace (m_uiout, nullptr);
m_uiout->field_string ("filename",
symtab_to_filename_for_display (s));
m_uiout->field_string ("fullname", symtab_to_fullname (s));
m_symbols_emitter.emplace (m_uiout, "symbols");
/* Record the current symtab. */
m_last_symtab = s;
}
}
public:
/* Constructor. */
mi_symbol_info_emitter (struct ui_out *uiout)
: m_last_symtab (nullptr),
m_uiout (uiout),
m_outer_symbols (uiout, "symbols")
{ /* Nothing. */ }
/* Output P a symbol found by searching for symbols of type KIND. */
void output (const symbol_search &p, enum search_domain kind)
{
if (p.msymbol.minsym != NULL)
{
/* If this is the first nondebug symbol, and we have previous
outputted a debug symbol then we need to close down all of the
emitters related to printing debug symbols. */
maybe_finish_debug_output ();
/* If this is the first nondebug symbol then we need to create the
emitters related to printing nondebug symbols. */
maybe_start_nondebug_symbol_output ();
/* We are no safe to emit the nondebug symbol. */
output_nondebug_symbol (p.msymbol);
}
else
{
/* All debug symbols should appear in the list before all
non-debug symbols. */
gdb_assert (!have_started_nondebug_symbol_output ());
/* If this is the first debug symbol then we need to create the
outer level of emitters related to printing debug symbols. */
maybe_start_debug_symbol_output ();
/* Ensure the correct emitters are in place to emit this debug
symbol. */
setup_emitters_for_symtab (symbol_symtab (p.symbol));
/* Emit information for this debug symbol. */
mi_info_one_symbol_details (kind, p.symbol, p.block);
}
}
};
/* 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 ();
mi_symbol_info_emitter emitter (current_uiout);
for (const symbol_search &p : symbols)
{
QUIT;
emitter.output (p, kind);
}
}
/* 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

@@ -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_"