@@ -45,7 +45,7 @@
compile code [-raw|-r] [--] [source code]
compile file [-raw|-r] filename
-* New commands
+* New commands (for set/show, see "New options" below)
queue-signal signal-name-or-number
Queue a signal to be delivered to the thread when it is resumed.
@@ -66,6 +66,15 @@ compile file [-r|-raw] filename
produced by compiling the source code stored in the filename
provided.
+* New options
+
+set max-completions
+show max-completions
+ Set the maximum number of candidates to be considered during
+ completion. The default value is 200. This limit allows GDB
+ to avoid generating large completion lists, the computation of
+ which can cause the debugger to become temporarily unresponsive.
+
* On resume, GDB now always passes the signal the program had stopped
for to the thread the signal was sent to, even if the user changed
threads before resuming. Previously GDB would often (but not
@@ -236,7 +236,8 @@ help_command (char *command, int from_tty)
help_cmd (command, gdb_stdout);
}
-/* The "complete" command is used by Emacs to implement completion. */
+/* Note: The "complete" command is used by Emacs to implement completion.
+ [Is that why this function writes output with *_unfiltered?] */
static void
complete_command (char *arg, int from_tty)
@@ -247,6 +248,18 @@ complete_command (char *arg, int from_tty)
dont_repeat ();
+ if (max_completions == 0)
+ {
+ /* Only print this for non-mi frontends. An MI frontend may not
+ be able to handle this. */
+ if (!ui_out_is_mi_like_p (current_uiout))
+ {
+ printf_unfiltered (_("max-completions is zero,"
+ " completion is disabled.\n"));
+ }
+ return;
+ }
+
if (arg == NULL)
arg = "";
argpoint = strlen (arg);
@@ -293,6 +306,13 @@ complete_command (char *arg, int from_tty)
xfree (prev);
VEC_free (char_ptr, completions);
+
+ if (size == max_completions)
+ {
+ printf_unfiltered (_("%s%s *** List may be truncated,"
+ " max-completions reached. ***\n"),
+ arg_prefix, point);
+ }
}
}
@@ -99,6 +99,12 @@ enum errors {
/* Requested feature, method, mechanism, etc. is not supported. */
NOT_SUPPORTED_ERROR,
+ /* The number of candidates generated during line completion has
+ reached the user's specified limit. This isn't an error, this exception
+ is used to halt searching for more completions, but for consistency
+ "_ERROR" is appended to the name. */
+ MAX_COMPLETIONS_REACHED_ERROR,
+
/* Add more errors here. */
NR_ERRORS
};
@@ -781,9 +781,93 @@ complete_line_internal (const char *text,
return list;
}
-/* Generate completions all at once. Returns a vector of strings.
- Each element is allocated with xmalloc. It can also return NULL if
- there are no completions.
+
+/* See completer.h. */
+
+int max_completions = 200;
+
+/* See completer.h. */
+
+completion_tracker_t
+new_completion_tracker (void)
+{
+ if (max_completions <= 0)
+ return NULL;
+
+ return htab_create_alloc (max_completions,
+ htab_hash_string, (htab_eq) streq,
+ NULL, xcalloc, xfree);
+}
+
+/* Cleanup routine to free a completion tracker and reset the pointer
+ to NULL. */
+
+static void
+free_completion_tracker (void *p)
+{
+ completion_tracker_t *tracker_ptr = p;
+
+ htab_delete (*tracker_ptr);
+ *tracker_ptr = NULL;
+}
+
+/* See completer.h. */
+
+struct cleanup *
+make_cleanup_free_completion_tracker (completion_tracker_t *tracker_ptr)
+{
+ if (*tracker_ptr == NULL)
+ return make_cleanup (null_cleanup, NULL);
+
+ return make_cleanup (free_completion_tracker, tracker_ptr);
+}
+
+/* See completer.h. */
+
+enum maybe_add_completion_enum
+maybe_add_completion (completion_tracker_t tracker, char *name)
+{
+ void **slot;
+
+ if (max_completions < 0)
+ return MAYBE_ADD_COMPLETION_OK;
+ if (max_completions == 0)
+ return MAYBE_ADD_COMPLETION_MAX_REACHED;
+
+ gdb_assert (tracker != NULL);
+
+ if (htab_elements (tracker) >= max_completions)
+ return MAYBE_ADD_COMPLETION_MAX_REACHED;
+
+ slot = htab_find_slot (tracker, name, INSERT);
+
+ if (*slot != HTAB_EMPTY_ENTRY)
+ return MAYBE_ADD_COMPLETION_DUPLICATE;
+
+ *slot = name;
+
+ return (htab_elements (tracker) < max_completions
+ ? MAYBE_ADD_COMPLETION_OK
+ : MAYBE_ADD_COMPLETION_OK_MAX_REACHED);
+}
+
+void
+throw_max_completions_reached_error (void)
+{
+ throw_error (MAX_COMPLETIONS_REACHED_ERROR, _("Max completions reached."));
+}
+
+/* Generate completions all at once. Returns a vector of unique strings
+ allocated with xmalloc. Returns NULL if there are no completions
+ or if max_completions is 0. If max_completions is non-negative, this will
+ return at most max_completions + 1 strings.
+
+ If max_completions strings are collected, an extra string is added which
+ is a text message to inform the user that the list may be truncated.
+ This extra string serves two purposes:
+ 1) Inform the user.
+ 2) Prevent readline from being able to find a common prefix to advance
+ point to, since it's working with an incomplete list.
TEXT is the caller's idea of the "word" we are looking at.
@@ -796,8 +880,66 @@ complete_line_internal (const char *text,
VEC (char_ptr) *
complete_line (const char *text, const char *line_buffer, int point)
{
- return complete_line_internal (text, line_buffer,
- point, handle_completions);
+ VEC (char_ptr) *list;
+ VEC (char_ptr) *result = NULL;
+ struct cleanup *cleanups;
+ completion_tracker_t tracker;
+ char *candidate;
+ int ix, max_reached;
+
+ if (max_completions == 0)
+ return NULL;
+ list = complete_line_internal (text, line_buffer, point,
+ handle_completions);
+ if (max_completions < 0)
+ return list;
+
+ tracker = new_completion_tracker ();
+ cleanups = make_cleanup_free_completion_tracker (&tracker);
+ make_cleanup_free_char_ptr_vec (list);
+
+ /* Do a final test for too many completions. Individual completers may
+ do some of this, but are not required to. Duplicates are also removed
+ here. Otherwise the user is left scratching his/her head: readline and
+ complete_command will remove duplicates, and if removal of duplicates
+ there brings the total under max_completions the user may think gdb quit
+ searching too early. */
+
+ for (ix = 0, max_reached = 0;
+ !max_reached && VEC_iterate (char_ptr, list, ix, candidate);
+ ++ix)
+ {
+ enum maybe_add_completion_enum add_status;
+
+ add_status = maybe_add_completion (tracker, candidate);
+
+ switch (add_status)
+ {
+ case MAYBE_ADD_COMPLETION_OK:
+ VEC_safe_push (char_ptr, result, xstrdup (candidate));
+ break;
+ case MAYBE_ADD_COMPLETION_OK_MAX_REACHED:
+ VEC_safe_push (char_ptr, result, xstrdup (candidate));
+ max_reached = 1;
+ break;
+ case MAYBE_ADD_COMPLETION_MAX_REACHED:
+ gdb_assert_not_reached ("more than max completions reached");
+ case MAYBE_ADD_COMPLETION_DUPLICATE:
+ break;
+ }
+ }
+
+ if (max_reached)
+ {
+ VEC_safe_push (char_ptr, result,
+ xstrprintf (_("%s *** List may be truncated,"
+ " max-completions reached. ***"),
+ text));
+ }
+
+ do_cleanups (cleanups);
+
+ return result;
}
/* Complete on command names. Used by "help". */
@@ -1020,3 +1162,90 @@ skip_quoted (const char *str)
{
return skip_quoted_chars (str, NULL, NULL);
}
+
+/* gdb version of readline/complete.c:get_y_or_n.
+ The user must press "y" or "n". Non-zero return means "y" pressed.
+ Also supported: space == 'y', RUBOUT == 'n', ctrl-g == start over. */
+
+static int
+gdb_get_y_or_n (void)
+{
+ int c;
+
+ for (;;)
+ {
+ RL_SETSTATE (RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE (RL_STATE_MOREINPUT);
+
+ if (c == 'y' || c == 'Y' || c == ' ')
+ return 1;
+ if (c == 'n' || c == 'N' || c == RUBOUT)
+ return 0;
+ if (c == ABORT_CHAR || c < 0)
+ {
+ /* Note: The arguments to rl_abort are ignored. */
+ rl_abort (0, 0);
+ }
+ rl_ding ();
+ }
+}
+
+/* See completer.h.
+ This follows complete.c:display_matches as close as possible. */
+
+void
+gdb_rl_display_match_list (char **matches, int len, int max)
+{
+ int actual_len = len;
+
+ /* Readline will never call this if complete_line returned NULL. */
+ gdb_assert (max_completions != 0);
+
+ /* complete_line will never return more than this. */
+ if (max_completions > 0)
+ gdb_assert (len <= max_completions + 1);
+
+ /* If max_completions is reached, complete_line adds a last entry. */
+ if (len == max_completions + 1)
+ actual_len = len - 1;
+
+ /* If there are many items, then ask the user if she really wants to
+ see them all. */
+ if (rl_completion_query_items > 0 && actual_len >= rl_completion_query_items)
+ {
+ /* We can't use *query here because they wait for <RET> which is
+ wrong here. This follows the readline version as closely as possible
+ for compatibility's sake. See readline/complete.c. */
+ rl_crlf ();
+ fprintf (rl_outstream, _("Display all %d possibilities? (y or n)"),
+ actual_len);
+ fflush (rl_outstream);
+ if (gdb_get_y_or_n () == 0)
+ {
+ rl_crlf ();
+ rl_forced_update_display ();
+ return;
+ }
+ }
+
+ rl_display_match_list (matches, len, max);
+
+ rl_forced_update_display ();
+}
+
+extern initialize_file_ftype _initialize_completer; /* -Wmissing-prototypes */
+
+void
+_initialize_completer (void)
+{
+ add_setshow_zuinteger_unlimited_cmd ("max-completions", no_class,
+ &max_completions, _("\
+Set maximum number of completion candidates."), _("\
+Show maximum number of completion candidates."), _("\
+Use this to limit the number of candidates considered\n\
+during completion. Specifying \"unlimited\" or -1\n\
+disables limiting. Note that setting either no limit or\n\
+a very large limit can make completion slow."),
+ NULL, NULL, &setlist, &showlist);
+}
@@ -59,6 +59,12 @@ extern char *gdb_completion_word_break_characters (void);
extern void set_gdb_completion_word_break_characters (completer_ftype *fn);
+/* rl_completion_display_matches_hook for gdb.
+ We wrap readline's default routine to be able to display an extra line
+ notifying the user that there may be more matches. */
+
+extern void gdb_rl_display_match_list (char **matches, int len, int max);
+
/* Exported to linespec.c */
extern const char *skip_quoted_chars (const char *, const char *,
@@ -66,4 +72,68 @@ extern const char *skip_quoted_chars (const char *, const char *,
extern const char *skip_quoted (const char *);
+/* Maximum number of candidates to consider before the completer
+ bails by throwing MAX_COMPLETIONS_REACHED_ERROR. Negative values
+ disable limiting. */
+
+extern int max_completions;
+
+/* Object to track how many unique completions have been generated.
+ Used to limit the size of generated completion lists. */
+
+typedef htab_t completion_tracker_t;
+
+/* Create a new completion tracker.
+ The result is a hash table to track added completions, or NULL
+ if max_completions <= 0. If max_completions < 0, tracking is disabled.
+ If max_completions == 0, the max is indeed zero. */
+
+extern completion_tracker_t new_completion_tracker (void);
+
+/* Make a cleanup to free a completion tracker, and reset its pointer
+ to NULL. */
+
+extern struct cleanup *make_cleanup_free_completion_tracker
+ (completion_tracker_t *tracker_ptr);
+
+/* Return values for maybe_add_completion. */
+
+enum maybe_add_completion_enum
+{
+ /* NAME has been recorded and max_completions has not been reached,
+ or completion tracking is disabled (max_completions < 0). */
+ MAYBE_ADD_COMPLETION_OK,
+
+ /* NAME has been recorded and max_completions has been reached
+ (thus the caller can stop searching). */
+ MAYBE_ADD_COMPLETION_OK_MAX_REACHED,
+
+ /* max-completions entries has been reached.
+ Whether NAME is a duplicate or not is not determined. */
+ MAYBE_ADD_COMPLETION_MAX_REACHED,
+
+ /* NAME has already been recorded.
+ Note that this is never returned if completion tracking is disabled
+ (max_completions < 0). */
+ MAYBE_ADD_COMPLETION_DUPLICATE
+};
+
+/* Add the completion NAME to the list of generated completions if
+ it is not there already.
+ If max_completions is negative, nothing is done, not even watching
+ for duplicates, and MAYBE_ADD_COMPLETION_OK is always returned.
+
+ If MAYBE_ADD_COMPLETION_MAX_REACHED is returned, callers are required to
+ record at least one more completion. The final list will be pruned to
+ max_completions, but recording at least one more than max_completions is
+ the signal to the completion machinery that too many completions were
+ found. */
+
+extern enum maybe_add_completion_enum
+ maybe_add_completion (completion_tracker_t tracker, char *name);
+
+/* Wrapper to throw MAX_COMPLETIONS_REACHED_ERROR. */
+
+extern void throw_max_completions_reached_error (void);
+
#endif /* defined (COMPLETER_H) */
@@ -60,6 +60,7 @@
#include "macroscope.h"
#include "parser-defs.h"
+#include "completer.h"
/* Forward declarations for local functions. */
@@ -4309,6 +4310,15 @@ static VEC (char_ptr) *return_val;
completion_list_add_name \
(MSYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word))
+/* Tracker for how many unique completions have been generated. Used
+ to terminate completion list generation early if the list has grown
+ to a size so large as to be useless. This helps avoid GDB seeming
+ to lock up in the event the user requests to complete on something
+ vague that necessitates the time consuming expansion of many symbol
+ tables. */
+
+static completion_tracker_t completion_tracker;
+
/* Test to see if the symbol specified by SYMNAME (which is already
demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
characters. If so, add it to the current completion list. */
@@ -4327,6 +4337,7 @@ completion_list_add_name (const char *symname,
{
char *new;
+ enum maybe_add_completion_enum add_status;
if (word == sym_text)
{
@@ -4348,7 +4359,22 @@ completion_list_add_name (const char *symname,
strcat (new, symname);
}
- VEC_safe_push (char_ptr, return_val, new);
+ add_status = maybe_add_completion (completion_tracker, new);
+
+ switch (add_status)
+ {
+ case MAYBE_ADD_COMPLETION_OK:
+ VEC_safe_push (char_ptr, return_val, new);
+ break;
+ case MAYBE_ADD_COMPLETION_OK_MAX_REACHED:
+ VEC_safe_push (char_ptr, return_val, new);
+ throw_max_completions_reached_error ();
+ case MAYBE_ADD_COMPLETION_MAX_REACHED:
+ throw_max_completions_reached_error ();
+ case MAYBE_ADD_COMPLETION_DUPLICATE:
+ xfree (new);
+ break;
+ }
}
}
@@ -4561,11 +4587,11 @@ symtab_expansion_callback (struct compunit_symtab *symtab,
datum->code);
}
-VEC (char_ptr) *
-default_make_symbol_completion_list_break_on (const char *text,
- const char *word,
- const char *break_on,
- enum type_code code)
+static void
+default_make_symbol_completion_list_break_on_1 (const char *text,
+ const char *word,
+ const char *break_on,
+ enum type_code code)
{
/* Problem: All of the symbols have to be copied because readline
frees them. I'm not going to worry about this; hopefully there
@@ -4583,7 +4609,7 @@ default_make_symbol_completion_list_break_on (const char *text,
/* Length of sym_text. */
int sym_text_len;
struct add_name_data datum;
- struct cleanup *back_to;
+ struct cleanup *cleanups;
/* Now look for the symbol we are supposed to complete on. */
{
@@ -4618,7 +4644,7 @@ default_make_symbol_completion_list_break_on (const char *text,
/* A double-quoted string is never a symbol, nor does it make sense
to complete it any other way. */
{
- return NULL;
+ return;
}
else
{
@@ -4654,8 +4680,8 @@ default_make_symbol_completion_list_break_on (const char *text,
}
gdb_assert (sym_text[sym_text_len] == '\0' || sym_text[sym_text_len] == '(');
- return_val = NULL;
- back_to = make_cleanup (do_free_completion_list, &return_val);
+ completion_tracker = new_completion_tracker ();
+ cleanups = make_cleanup_free_completion_tracker (&completion_tracker);
datum.sym_text = sym_text;
datum.sym_text_len = sym_text_len;
@@ -4769,8 +4795,34 @@ default_make_symbol_completion_list_break_on (const char *text,
macro_for_each (macro_user_macros, add_macro_name, &datum);
}
+ do_cleanups (cleanups);
+}
+
+VEC (char_ptr) *
+default_make_symbol_completion_list_break_on (const char *text,
+ const char *word,
+ const char *break_on,
+ enum type_code code)
+{
+ struct cleanup *back_to;
+ volatile struct gdb_exception except;
+
+ return_val = NULL;
+ back_to = make_cleanup (do_free_completion_list, &return_val);
+
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ default_make_symbol_completion_list_break_on_1 (text, word,
+ break_on, code);
+ }
+ if (except.reason < 0)
+ {
+ if (except.error != MAX_COMPLETIONS_REACHED_ERROR)
+ throw_exception (except);
+ }
+
discard_cleanups (back_to);
- return (return_val);
+ return return_val;
}
VEC (char_ptr) *
@@ -1761,6 +1761,7 @@ init_main (void)
rl_completion_entry_function = readline_line_completion_function;
rl_completer_word_break_characters = default_word_break_characters ();
rl_completer_quote_characters = get_gdb_completer_quote_characters ();
+ rl_completion_display_matches_hook = gdb_rl_display_match_list;
rl_readline_name = "gdb";
rl_terminal_name = getenv ("TERM");
@@ -37,6 +37,7 @@
#include <fcntl.h>
#include <signal.h>
#include "filestuff.h"
+#include "completer.h"
#include "gdb_curses.h"
@@ -132,6 +133,7 @@ static rl_getc_func_t *tui_old_rl_getc_function;
static rl_voidfunc_t *tui_old_rl_redisplay_function;
static rl_vintfunc_t *tui_old_rl_prep_terminal;
static rl_voidfunc_t *tui_old_rl_deprep_terminal;
+static rl_compdisp_func_t *tui_old_rl_display_matches_hook;
static int tui_old_rl_echoing_p;
/* Readline output stream.
@@ -412,18 +414,30 @@ tui_rl_display_match_list (char **matches, int len, int max)
int count, limit, printed_len;
int i, j, k, l;
const char *temp;
+ int actual_len = len;
/* Screen dimension correspond to the TUI command window. */
int screenwidth = TUI_CMD_WIN->generic.width;
+ /* Readline will never call this if complete_line returned NULL. */
+ gdb_assert (max_completions != 0);
+
+ /* complete_line will never return more than this. */
+ if (max_completions > 0)
+ gdb_assert (len <= max_completions + 1);
+
+ /* If max_completions is reached, complete_line adds a last entry. */
+ if (len == max_completions + 1)
+ actual_len = len - 1;
+
/* If there are many items, then ask the user if she really wants to
see them all. */
- if (len >= rl_completion_query_items)
+ if (actual_len >= rl_completion_query_items)
{
char msg[256];
xsnprintf (msg, sizeof (msg),
- "\nDisplay all %d possibilities? (y or n)", len);
+ "\nDisplay all %d possibilities? (y or n)", actual_len);
tui_puts (msg);
if (get_y_or_n () == 0)
{
@@ -521,6 +535,7 @@ tui_setup_io (int mode)
tui_old_rl_deprep_terminal = rl_deprep_term_function;
tui_old_rl_prep_terminal = rl_prep_term_function;
tui_old_rl_getc_function = rl_getc_function;
+ tui_old_rl_display_matches_hook = rl_completion_display_matches_hook;
tui_old_rl_outstream = rl_outstream;
tui_old_rl_echoing_p = _rl_echoing_p;
rl_redisplay_function = tui_redisplay_readline;
@@ -564,8 +579,8 @@ tui_setup_io (int mode)
rl_deprep_term_function = tui_old_rl_deprep_terminal;
rl_prep_term_function = tui_old_rl_prep_terminal;
rl_getc_function = tui_old_rl_getc_function;
+ rl_completion_display_matches_hook = tui_old_rl_display_matches_hook;
rl_outstream = tui_old_rl_outstream;
- rl_completion_display_matches_hook = 0;
_rl_echoing_p = tui_old_rl_echoing_p;
rl_already_prompted = 0;
@@ -1600,6 +1600,34 @@ means @kbd{@key{META} ?}. You can type this either by holding down a
key designated as the @key{META} shift on your keyboard (if there is
one) while typing @kbd{?}, or as @key{ESC} followed by @kbd{?}.
+If the number of possible completions is large, @value{GDBN} will
+print as much of the list as it has collected, as well as a message
+indicating that the list may be truncated.
+
+@smallexample
+(@value{GDBP}) b m@key{TAB}@key{TAB}
+m *** List may be truncated, max-completions reached. ***
+main
+<... the rest of the possible completions ...>
+(@value{GDBP}) b m
+@end smallexample
+
+@noindent
+This behavior can be controlled with the following commands:
+
+@table @code
+@kindex set max-completions
+@item set max-completions @var{limit}
+@itemx set max-completions unlimited
+Set the maximum number of candidates to be shown during completion.
+The default value is 200. A value of zero disables tab-completion.
+Note that setting either no limit or a very large limit can make
+completion slow.
+@kindex show max-completions
+@item show max-completions
+Show the maximum number of candidates to be shown during completion.
+@end table
+
@cindex quotes in commands
@cindex completion of quoted strings
Sometimes the string you need, while logically a ``word'', may contain
@@ -67,6 +67,7 @@ if ![runto_main] then {
}
set timeout 30
+gdb_test_no_output "set max-completions unlimited"
gdb_test_no_output "complete print values\[0\].x." \
"field completion with invalid field"
@@ -775,4 +776,86 @@ gdb_test_multiple "" "$test" {
}
}
-return 0
+#
+# Completion limiting.
+#
+
+gdb_test_no_output "set max-completions 5"
+
+set test "command-name completion limiting using tab character"
+send_gdb "p\t"
+gdb_test_multiple "" "$test" {
+ -re "^p\\\x07$" {
+ send_gdb "\t"
+ gdb_test_multiple "" "$test" {
+ -re "List may be truncated, max-completions reached.*\r\n$gdb_prompt p$" {
+ # Complete the command and ignore the output to resync
+ # gdb for the next test.
+ send_gdb "\n"
+ gdb_test_multiple "" "$test" {
+ -re "$gdb_prompt $" {
+ pass "$test"
+ }
+ }
+ }
+ -re "$gdb_prompt p$" {
+ # Complete the command and ignore the output to resync
+ # gdb for the next test.
+ send_gdb "\n"
+ gdb_test_multiple "" "$test" {
+ -re "$gdb_prompt $" {
+ fail "$test"
+ }
+ }
+ }
+ }
+ }
+}
+
+set test "command-name completion limiting using complete command"
+send_gdb "complete p\n"
+gdb_test_multiple "" "$test" {
+ -re "List may be truncated, max-completions reached.*\r\n$gdb_prompt $" {
+ pass "$test"
+ }
+}
+
+gdb_test_no_output "set max-completions 3"
+
+set test "symbol-name completion limiting using tab character"
+send_gdb "p marker\t"
+gdb_test_multiple "" "$test" {
+ -re "^p marker\\\x07$" {
+ send_gdb "\t"
+ gdb_test_multiple "" "$test" {
+ -re "List may be truncated, max-completions reached.*\r\n$gdb_prompt p marker$" {
+ # Complete the command and ignore the output to resync
+ # gdb for the next test.
+ send_gdb "\n"
+ gdb_test_multiple "" "$test" {
+ -re "$gdb_prompt $" {
+ pass "$test"
+ }
+ }
+ }
+ -re "$gdb_prompt p marker$" {
+ # Complete the command and ignore the output to resync
+ # gdb for the next test.
+ send_gdb "\n"
+ gdb_test_multiple "" "$test" {
+ -re "$gdb_prompt $" {
+ fail "$test"
+ }
+ }
+ }
+ }
+ }
+}
+
+set test "symbol-name completion limiting using complete command"
+send_gdb "complete p mark\n"
+gdb_test_multiple "" "$test" {
+ -re "List may be truncated, max-completions reached.*\r\n$gdb_prompt $" {
+ pass "$test"
+ }
+}
@@ -26,6 +26,9 @@ if {[prepare_for_testing $testfile $exefile $srcfile \
# Turn off the pending breakpoint queries.
gdb_test_no_output "set breakpoint pending off"
+# Turn off completion limiting
+gdb_test_no_output "set max-completions unlimited"
+
# We intentionally do not use gdb_breakpoint for these tests.
# Break at 'linespec' and expect the message in ::error_messages indexed by