mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-05-30 07:49:07 +08:00
Rationalize "backtrace" command line parsing
The backtrace command has peculiar command-line parsing. In particular, it splits the command line, then loops over the arguments. If it sees a word it recognizes, like "full", it effectively drops this word from the argument vector. Then, it pastes together the remaining arguments, passing them on to backtrace_command_1, which in turn passes the resulting string to parse_and_eval_long. The documentation doesn't mention the parse_and_eval_long at all, so it is a bit of a hidden feature that you can "bt 3*2". The strange algorithm above also means you can "bt 3 * no-filters 2" and get 6 frames... This patch changes backtrace's command line parsing to be a bit more rational. Now, special words like "full" are only recognized at the start of the command. This also updates the documentation to describe the various bt options individually. gdb/ChangeLog 2018-03-26 Tom Tromey <tom@tromey.com> * stack.c (backtrace_command): Rewrite command line parsing. gdb/doc/ChangeLog 2018-03-26 Tom Tromey <tom@tromey.com> * gdb.texinfo (Backtrace): Describe options individually.
This commit is contained in:
62
gdb/stack.c
62
gdb/stack.c
@ -1850,61 +1850,39 @@ backtrace_command_1 (const char *count_exp, int show_locals, int no_filters,
|
||||
static void
|
||||
backtrace_command (const char *arg, int from_tty)
|
||||
{
|
||||
int fulltrace_arg = -1, arglen = 0, argc = 0, no_filters = -1;
|
||||
int user_arg = 0;
|
||||
bool fulltrace = false;
|
||||
bool filters = true;
|
||||
|
||||
std::string reconstructed_arg;
|
||||
if (arg)
|
||||
{
|
||||
char **argv;
|
||||
int i;
|
||||
bool done = false;
|
||||
|
||||
gdb_argv built_argv (arg);
|
||||
argv = built_argv.get ();
|
||||
argc = 0;
|
||||
for (i = 0; argv[i]; i++)
|
||||
while (!done)
|
||||
{
|
||||
unsigned int j;
|
||||
const char *save_arg = arg;
|
||||
std::string this_arg = extract_arg (&arg);
|
||||
|
||||
for (j = 0; j < strlen (argv[i]); j++)
|
||||
argv[i][j] = TOLOWER (argv[i][j]);
|
||||
if (this_arg.empty ())
|
||||
break;
|
||||
|
||||
if (no_filters < 0 && subset_compare (argv[i], "no-filters"))
|
||||
no_filters = argc;
|
||||
if (subset_compare (this_arg.c_str (), "no-filters"))
|
||||
filters = false;
|
||||
else if (subset_compare (this_arg.c_str (), "full"))
|
||||
fulltrace = true;
|
||||
else
|
||||
{
|
||||
if (fulltrace_arg < 0 && subset_compare (argv[i], "full"))
|
||||
fulltrace_arg = argc;
|
||||
else
|
||||
{
|
||||
user_arg++;
|
||||
arglen += strlen (argv[i]);
|
||||
}
|
||||
/* Not a recognized argument, so stop. */
|
||||
arg = save_arg;
|
||||
done = true;
|
||||
}
|
||||
argc++;
|
||||
}
|
||||
arglen += user_arg;
|
||||
if (fulltrace_arg >= 0 || no_filters >= 0)
|
||||
{
|
||||
if (arglen > 0)
|
||||
{
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (i != fulltrace_arg && i != no_filters)
|
||||
{
|
||||
reconstructed_arg += argv[i];
|
||||
reconstructed_arg += " ";
|
||||
}
|
||||
}
|
||||
arg = reconstructed_arg.c_str ();
|
||||
}
|
||||
else
|
||||
arg = NULL;
|
||||
}
|
||||
|
||||
if (*arg == '\0')
|
||||
arg = NULL;
|
||||
}
|
||||
|
||||
backtrace_command_1 (arg, fulltrace_arg >= 0 /* show_locals */,
|
||||
no_filters >= 0 /* no frame-filters */, from_tty);
|
||||
backtrace_command_1 (arg, fulltrace /* show_locals */,
|
||||
!filters /* no frame-filters */, from_tty);
|
||||
}
|
||||
|
||||
/* Iterate over the local variables of a block B, calling CB with
|
||||
|
Reference in New Issue
Block a user