summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog27
-rw-r--r--gdb/doc/ChangeLog5
-rw-r--r--gdb/doc/gdb.texinfo27
-rw-r--r--gdb/mi/mi-symbol-cmds.c46
-rw-r--r--gdb/symtab.c53
-rw-r--r--gdb/symtab.h33
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.mi/mi-sym-info.exp21
8 files changed, 180 insertions, 36 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 391b23e9e3f..aacc0c9b16c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,32 @@
2019-12-04 Andrew Burgess <andrew.burgess@embecosm.com>
+ * mi/mi-symbol-cmds.c (mi_symbol_info): Take extra parameter, and
+ add it into the search spec.
+ (parse_max_results_option): New function.
+ (mi_info_functions_or_variables): Parse -max-results flag and pass
+ it to mi_symbol_info.
+ (mi_cmd_symbol_info_modules): Likewise.
+ (mi_cmd_symbol_info_types): Likewise.
+ * symtab.c (global_symbol_searcher::add_matching_symbols): Change
+ return type to bool, change result container into a set, and don't
+ add new results if we have enough already.
+ (global_symbol_searcher::add_matching_msymbols): Change return
+ type to bool, and don't add new results if we have enough already.
+ (sort_search_symbols_remove_dups): Delete.
+ (global_symbol_searcher::search): Early exit from search loop when
+ we have enough results. Use a std::set to collect the results
+ from calling add_matching_symbols.
+ * symtab.h (global_symbol_searcher) <set_max_seach_results>: New
+ member function.
+ (global_symbol_searcher) <m_max_search_results>: New member
+ variable.
+ (global_symbol_searcher) <add_matching_symbols>: Update header
+ comment and change return type to bool.
+ (global_symbol_searcher) <add_matching_msymbols>: Update header
+ comment and change return type to bool.
+
+2019-12-04 Andrew Burgess <andrew.burgess@embecosm.com>
+
* symtab.c (symbol_search::compare_search_syms): Update header
comment.
(global_symbol_searcher::is_suitable_msymbol): New function.
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 5b3eab7d732..9a70de350c6 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,5 +1,10 @@
2019-12-04 Andrew Burgess <andrew.burgess@embecosm.com>
+ * doc/gdb.texinfo (GDB/MI Symbol Query): Add documentation of
+ -max-results to some -symbol-info-* commands.
+
+2019-12-04 Andrew Burgess <andrew.burgess@embecosm.com>
+
* doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command
-symbol-info-module-functions and -symbol-info-module-variables.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 6fb7e8ab7ea..544e632a46f 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -33962,6 +33962,7 @@ N.A.
-symbol-info-functions [--include-nondebug]
[--type @var{type_regexp}]
[--name @var{name_regexp}]
+ [--max-results @var{limit}]
@end smallexample
@noindent
@@ -33977,6 +33978,11 @@ 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.
+The option @code{--max-results} restricts the command to return no
+more than @var{limit} results. If exactly @var{limit} results are
+returned then there might be additional results available if a higher
+limit is used.
+
@subsubheading @value{GDBN} Command
The corresponding @value{GDBN} command is @samp{info functions}.
@@ -34208,6 +34214,8 @@ The corresponding @value{GDBN} command is @samp{info module variables}.
@smallexample
-symbol-info-modules [--name @var{name_regexp}]
+ [--max-results @var{limit}]
+
@end smallexample
@noindent
@@ -34218,6 +34226,11 @@ which each modules is defined.
The option @code{--name} allows the modules returned to be filtered
based the name of the module.
+The option @code{--max-results} restricts the command to return no
+more than @var{limit} results. If exactly @var{limit} results are
+returned then there might be additional results available if a higher
+limit is used.
+
@subsubheading @value{GDBN} Command
The corresponding @value{GDBN} command is @samp{info modules}.
@@ -34262,6 +34275,8 @@ The corresponding @value{GDBN} command is @samp{info modules}.
@smallexample
-symbol-info-types [--name @var{name_regexp}]
+ [--max-results @var{limit}]
+
@end smallexample
@noindent
@@ -34275,6 +34290,11 @@ line number.
The option @code{--name} allows the list of types returned to be
filtered by name.
+The option @code{--max-results} restricts the command to return no
+more than @var{limit} results. If exactly @var{limit} results are
+returned then there might be additional results available if a higher
+limit is used.
+
@subsubheading @value{GDBN} Command
The corresponding @value{GDBN} command is @samp{info types}.
@@ -34322,6 +34342,8 @@ The corresponding @value{GDBN} command is @samp{info types}.
-symbol-info-variables [--include-nondebug]
[--type @var{type_regexp}]
[--name @var{name_regexp}]
+ [--max-results @var{limit}]
+
@end smallexample
@noindent
@@ -34337,6 +34359,11 @@ 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.
+The option @code{--max-results} restricts the command to return no
+more than @var{limit} results. If exactly @var{limit} results are
+returned then there might be additional results available if a higher
+limit is used.
+
@subsubheading @value{GDBN} Command
The corresponding @value{GDBN} command is @samp{info variables}.
diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c
index 2bebd11f799..edbafe39447 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -111,11 +111,13 @@ output_nondebug_symbol (ui_out *uiout,
static void
mi_symbol_info (enum search_domain kind, const char *name_regexp,
- const char *type_regexp, bool exclude_minsyms)
+ const char *type_regexp, bool exclude_minsyms,
+ size_t max_results)
{
global_symbol_searcher sym_search (kind, name_regexp);
sym_search.set_symbol_type_regexp (type_regexp);
sym_search.set_exclude_minsyms (exclude_minsyms);
+ sym_search.set_max_search_results (max_results);
std::vector<symbol_search> symbols = sym_search.search ();
ui_out *uiout = current_uiout;
int i = 0;
@@ -166,25 +168,42 @@ mi_symbol_info (enum search_domain kind, const char *name_regexp,
}
}
+/* Helper to parse the option text from an -max-results argument and return
+ the parsed value. If the text can't be parsed then an error is thrown. */
+
+static size_t
+parse_max_results_option (char *arg)
+{
+ char *ptr = arg;
+ long long val = strtoll (arg, &ptr, 10);
+ if (arg == ptr || *ptr != '\0' || val > SIZE_MAX || val < 0)
+ error (_("invalid value for --max-results argument"));
+ size_t max_results = (size_t) val;
+
+ return max_results;
+}
+
/* 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)
{
+ size_t max_results = SIZE_MAX;
const char *regexp = nullptr;
const char *t_regexp = nullptr;
bool exclude_minsyms = true;
enum opt
{
- INCLUDE_NONDEBUG_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT
+ INCLUDE_NONDEBUG_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT, MAX_RESULTS_OPT
};
static const struct mi_opt opts[] =
{
{"-include-nondebug" , INCLUDE_NONDEBUG_OPT, 0},
{"-type", TYPE_REGEXP_OPT, 1},
{"-name", NAME_REGEXP_OPT, 1},
+ {"-max-results", MAX_RESULTS_OPT, 1},
{ 0, 0, 0 }
};
@@ -210,10 +229,13 @@ mi_info_functions_or_variables (enum search_domain kind, char **argv, int argc)
case NAME_REGEXP_OPT:
regexp = oarg;
break;
+ case MAX_RESULTS_OPT:
+ max_results = parse_max_results_option (oarg);
+ break;
}
}
- mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms);
+ mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms, max_results);
}
/* Type for an iterator over a vector of module_symbol_search results. */
@@ -384,15 +406,17 @@ mi_cmd_symbol_info_module_variables (const char *command, char **argv,
void
mi_cmd_symbol_info_modules (const char *command, char **argv, int argc)
{
+ size_t max_results = SIZE_MAX;
const char *regexp = nullptr;
enum opt
{
- NAME_REGEXP_OPT
+ NAME_REGEXP_OPT, MAX_RESULTS_OPT
};
static const struct mi_opt opts[] =
{
{"-name", NAME_REGEXP_OPT, 1},
+ {"-max-results", MAX_RESULTS_OPT, 1},
{ 0, 0, 0 }
};
@@ -410,10 +434,13 @@ mi_cmd_symbol_info_modules (const char *command, char **argv, int argc)
case NAME_REGEXP_OPT:
regexp = oarg;
break;
+ case MAX_RESULTS_OPT:
+ max_results = parse_max_results_option (oarg);
+ break;
}
}
- mi_symbol_info (MODULES_DOMAIN, regexp, nullptr, true);
+ mi_symbol_info (MODULES_DOMAIN, regexp, nullptr, true, max_results);
}
/* Implement -symbol-info-types command. */
@@ -421,15 +448,17 @@ mi_cmd_symbol_info_modules (const char *command, char **argv, int argc)
void
mi_cmd_symbol_info_types (const char *command, char **argv, int argc)
{
+ size_t max_results = SIZE_MAX;
const char *regexp = nullptr;
enum opt
{
- NAME_REGEXP_OPT
+ NAME_REGEXP_OPT, MAX_RESULTS_OPT
};
static const struct mi_opt opts[] =
{
{"-name", NAME_REGEXP_OPT, 1},
+ {"-max-results", MAX_RESULTS_OPT, 1},
{ 0, 0, 0 }
};
@@ -447,10 +476,13 @@ mi_cmd_symbol_info_types (const char *command, char **argv, int argc)
case NAME_REGEXP_OPT:
regexp = oarg;
break;
+ case MAX_RESULTS_OPT:
+ max_results = parse_max_results_option (oarg);
+ break;
}
}
- mi_symbol_info (TYPES_DOMAIN, regexp, nullptr, true);
+ mi_symbol_info (TYPES_DOMAIN, regexp, nullptr, true, max_results);
}
/* Implement -symbol-info-variables command. */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index d54ff144431..6fd1c8c4bc0 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4547,12 +4547,12 @@ global_symbol_searcher::expand_symtabs
/* See symtab.h. */
-void
+bool
global_symbol_searcher::add_matching_symbols
(objfile *objfile,
const gdb::optional<compiled_regex> &preg,
const gdb::optional<compiled_regex> &treg,
- std::vector<symbol_search> *results) const
+ std::set<symbol_search> *result_set) const
{
enum search_domain kind = m_kind;
@@ -4610,17 +4610,26 @@ global_symbol_searcher::add_matching_symbols
&& SYMBOL_DOMAIN (sym) == MODULE_DOMAIN
&& SYMBOL_LINE (sym) != 0))))
{
- /* Matching msymbol, add it to the results list. */
- results->emplace_back (block, sym);
+ if (result_set->size () < m_max_search_results)
+ {
+ /* Match, insert if not already in the results. */
+ symbol_search ss (block, sym);
+ if (result_set->find (ss) == result_set->end ())
+ result_set->insert (ss);
+ }
+ else
+ return false;
}
}
}
}
+
+ return true;
}
/* See symtab.h. */
-void
+bool
global_symbol_searcher::add_matching_msymbols
(objfile *objfile, const gdb::optional<compiled_regex> &preg,
std::vector<symbol_search> *results) const
@@ -4652,22 +4661,17 @@ global_symbol_searcher::add_matching_msymbols
VAR_DOMAIN).symbol == NULL)
{
/* Matching msymbol, add it to the results list. */
- results->emplace_back (GLOBAL_BLOCK, msymbol, objfile);
+ if (results->size () < m_max_search_results)
+ results->emplace_back (GLOBAL_BLOCK, msymbol, objfile);
+ else
+ return false;
}
}
}
}
}
-}
-/* Sort the symbols in RESULT and remove duplicates. */
-
-static void
-sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
-{
- std::sort (result->begin (), result->end ());
- result->erase (std::unique (result->begin (), result->end ()),
- result->end ());
+ return true;
}
/* See symtab.h. */
@@ -4733,20 +4737,24 @@ global_symbol_searcher::search () const
}
bool found_msymbol = false;
- std::vector<symbol_search> result;
+ std::set<symbol_search> result_set;
for (objfile *objfile : current_program_space->objfiles ())
{
/* Expand symtabs within objfile that possibly contain matching
symbols. */
found_msymbol |= expand_symtabs (objfile, preg);
- /* Find matching symbols within OBJFILE and add them in to the RESULT
- vector. */
- add_matching_symbols (objfile, preg, treg, &result);
+ /* Find matching symbols within OBJFILE and add them in to the
+ RESULT_SET set. Use a set here so that we can easily detect
+ duplicates as we go, and can therefore track how many unique
+ matches we have found so far. */
+ if (!add_matching_symbols (objfile, preg, treg, &result_set))
+ break;
}
- if (!result.empty ())
- sort_search_symbols_remove_dups (&result);
+ /* Convert the result set into a sorted result list, as std::set is
+ defined to be sorted then no explicit call to std::sort is needed. */
+ std::vector<symbol_search> result (result_set.begin (), result_set.end ());
/* If there are no debug symbols, then add matching minsyms. But if the
user wants to see symbols matching a type regexp, then never give a
@@ -4758,7 +4766,8 @@ global_symbol_searcher::search () const
{
gdb_assert (m_kind == VARIABLES_DOMAIN || m_kind == FUNCTIONS_DOMAIN);
for (objfile *objfile : current_program_space->objfiles ())
- add_matching_msymbols (objfile, preg, &result);
+ if (!add_matching_msymbols (objfile, preg, &result))
+ break;
}
return result;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 41abf1f38ff..e8321d4bb8c 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -23,6 +23,7 @@
#include <array>
#include <vector>
#include <string>
+#include <set>
#include "gdbsupport/gdb_vecs.h"
#include "gdbtypes.h"
#include "gdb_obstack.h"
@@ -2092,6 +2093,12 @@ public:
m_exclude_minsyms = exclude_minsyms;
}
+ /* Set the maximum number of search results to be returned. */
+ void set_max_search_results (size_t max_search_results)
+ {
+ m_max_search_results = max_search_results;
+ }
+
/* Search the symbols from all objfiles in the current program space
looking for matches as defined by the current state of this object.
@@ -2125,6 +2132,10 @@ private:
be included in the results, otherwise they are excluded. */
bool m_exclude_minsyms = false;
+ /* Maximum number of search results. We currently impose a hard limit
+ of SIZE_MAX, there is no "unlimited". */
+ size_t m_max_search_results = SIZE_MAX;
+
/* Expand symtabs in OBJFILE that match PREG, are of type M_KIND. Return
true if any msymbols were seen that we should later consider adding to
the results list. */
@@ -2132,15 +2143,23 @@ private:
const gdb::optional<compiled_regex> &preg) const;
/* Add symbols from symtabs in OBJFILE that match PREG, and TREG, and are
- of type M_KIND, to the results vector RESULTS. */
- void add_matching_symbols (objfile *objfile,
+ of type M_KIND, to the results set RESULTS_SET. Return false if we
+ stop adding results early due to having already found too many results
+ (based on M_MAX_SEARCH_RESULTS limit), otherwise return true.
+ Returning true does not indicate that any results were added, just
+ that we didn't _not_ add a result due to reaching MAX_SEARCH_RESULTS. */
+ bool add_matching_symbols (objfile *objfile,
const gdb::optional<compiled_regex> &preg,
const gdb::optional<compiled_regex> &treg,
- std::vector<symbol_search> *results) const;
-
- /* Add msymbols from OBJFILE that match PREG and M_KIND, to the
- results vector RESULTS. */
- void add_matching_msymbols (objfile *objfile,
+ std::set<symbol_search> *result_set) const;
+
+ /* Add msymbols from OBJFILE that match PREG and M_KIND, to the results
+ vector RESULTS. Return false if we stop adding results early due to
+ having already found too many results (based on max search results
+ limit M_MAX_SEARCH_RESULTS), otherwise return true. Returning true
+ does not indicate that any results were added, just that we didn't
+ _not_ add a result due to reaching MAX_SEARCH_RESULTS. */
+ bool add_matching_msymbols (objfile *objfile,
const gdb::optional<compiled_regex> &preg,
std::vector<symbol_search> *results) const;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 9ed64d1d4c3..112049f2ed2 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2019-12-04 Andrew Burgess <andrew.burgess@embecosm.com>
+ * gdb.mi/mi-sym-info.exp: Add tests for -max-results parameter.
+
+2019-12-04 Andrew Burgess <andrew.burgess@embecosm.com>
+
* gdb.mi/mi-fortran-modules.exp: Add additional tests for
-symbol-info-module-functions and -symbol-info-module-variables.
diff --git a/gdb/testsuite/gdb.mi/mi-sym-info.exp b/gdb/testsuite/gdb.mi/mi-sym-info.exp
index 33fe8657811..4a65bd6ee5d 100644
--- a/gdb/testsuite/gdb.mi/mi-sym-info.exp
+++ b/gdb/testsuite/gdb.mi/mi-sym-info.exp
@@ -127,3 +127,24 @@ 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_"
+
+# Test the --max-results parameter.
+mi_gdb_test "121-symbol-info-functions --max-results 0" \
+ "121\\^done,symbols=\{\}" \
+ "-symbol-info-functions --max-results 0"
+
+mi_gdb_test "122-symbol-info-functions --max-results 1" \
+ "122\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"39\",name=\"f3\",type=\"int \\(another_int_t\\)\",description=\"int f3\\(another_int_t\\);\"\}\\\]\}\\\]\}" \
+ "-symbol-info-functions --max-results 1"
+
+mi_gdb_test "123-symbol-info-functions --max-results 2" \
+ "123\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",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\\);\"\}\\\]\}\\\]\}" \
+ "-symbol-info-functions --max-results 2"
+
+mi_gdb_test "124-symbol-info-variables --max-results 3" \
+ "124\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",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;\"\}\\\]\}\\\]\}" \
+ "-symbol-info-variables --max-results 3"
+
+mi_gdb_test "125-symbol-info-types --max-results 4" \
+ "125\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"24\",name=\"another_float_t\"\},\{line=\"23\",name=\"another_int_t\"\},\{name=\"float\"\},\{name=\"int\"\}\\\]\}\\\]\}" \
+ "-symbol-info-types --max-results 4"