This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA v3 01/13] Rationalize "backtrace" command line parsing
- From: Tom Tromey <tom at tromey dot com>
- To: gdb-patches at sourceware dot org
- Cc: Tom Tromey <tom at tromey dot com>
- Date: Fri, 23 Mar 2018 14:55:00 -0600
- Subject: [RFA v3 01/13] Rationalize "backtrace" command line parsing
- References: <20180323205512.14434-1-tom@tromey.com>
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-23 Tom Tromey <tom@tromey.com>
* stack.c (backtrace_command): Rewrite command line parsing.
gdb/doc/ChangeLog
2018-03-23 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Backtrace): Describe options individually.
---
gdb/ChangeLog | 4 ++++
gdb/doc/ChangeLog | 4 ++++
gdb/doc/gdb.texinfo | 54 ++++++++++++++++++++--------------------------
gdb/stack.c | 62 +++++++++++++++++------------------------------------
4 files changed, 51 insertions(+), 73 deletions(-)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 74e0fdb4a4..b48dd4ed4b 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7307,39 +7307,31 @@ frame (frame zero), followed by its caller (frame one), and on up the
stack.
@anchor{backtrace-command}
-@table @code
@kindex backtrace
@kindex bt @r{(@code{backtrace})}
-@item backtrace
-@itemx bt
-Print a backtrace of the entire stack: one line per frame for all
-frames in the stack.
-
-You can stop the backtrace at any time by typing the system interrupt
-character, normally @kbd{Ctrl-c}.
-
-@item backtrace @var{n}
-@itemx bt @var{n}
-Similar, but print only the innermost @var{n} frames.
-
-@item backtrace -@var{n}
-@itemx bt -@var{n}
-Similar, but print only the outermost @var{n} frames.
-
-@item backtrace full
-@itemx bt full
-@itemx bt full @var{n}
-@itemx bt full -@var{n}
-Print the values of the local variables also. As described above,
-@var{n} specifies the number of frames to print.
-
-@item backtrace no-filters
-@itemx bt no-filters
-@itemx bt no-filters @var{n}
-@itemx bt no-filters -@var{n}
-@itemx bt no-filters full
-@itemx bt no-filters full @var{n}
-@itemx bt no-filters full -@var{n}
+Print a backtrace of the entire stack, use the @code{backtrace}
+command, or its alias @code{bt}. This command will print one line per
+frame for frames in the stack. By default, all stack frames are
+printed. You can stop the backtrace at any time by typing the system
+interrupt character, normally @kbd{Ctrl-c}. @code{backtrace} can
+accept some arguments:
+
+@table @code
+@item @var{n}
+@itemx @var{n}
+Print only the innermost @var{n} frames, where @var{n} is a positive
+number.
+
+@item -@var{n}
+@itemx -@var{n}
+Print only the outermost @var{n} frames, where @var{n} is a positive
+number.
+
+@item full
+Print the values of the local variables also. This can be combined
+with a number to limit the number of frames shown.
+
+@item no-filters
Do not run Python frame filters on this backtrace. @xref{Frame
Filter API}, for more information. Additionally use @ref{disable
frame-filter all} to turn off all frame filters. This is only
diff --git a/gdb/stack.c b/gdb/stack.c
index aad8fcd987..13af6594a9 100644
--- a/gdb/stack.c
+++ b/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]);
- }
- }
- 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 ();
+ /* Not a recognized argument, so stop. */
+ arg = save_arg;
+ done = true;
}
- 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
--
2.13.6