* [PATCH] command trace / source verbose mode
@ 2005-11-16 18:01 Andrew STUBBS
2005-11-16 20:11 ` Eli Zaretskii
0 siblings, 1 reply; 13+ messages in thread
From: Andrew STUBBS @ 2005-11-16 18:01 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 837 bytes --]
Hi,
This patch adds a new command
set debug commandtrace
and a new option, '-v', to the existing 'source' command.
These features allow the user to see commands as they are executed. This
is useful for debugging GDB scripts or just as a progress indicator.
The source command still permits file names with spaces, as it did
before, so the -v must appear at either the beginning or the end.
Because the -x option is implemented by means of the source command the
-x option gets -v as a sub-option 'for free'. I'm not sure if this is a
bad thing or not - it certainly might be useful somewhere. It can be
fixed, if necessary, by moving the guts of source_command() to another
function.
When -v is given or commandtrace is enabled, each command is printed as
it is executed prefixed with 'Command issued: '.
Andrew Stubbs
[-- Attachment #2: command-trace.patch --]
[-- Type: text/plain, Size: 11197 bytes --]
2005-11-16 Andrew Stubbs <andrew.stubbs@st.com>
* cli/cli-cmds.c (source_verbose, commandtrace): New variables.
(source_command): Add -v option.
(init_cli_cmds): Update source command help.
Add 'set debug commandtrace' command.
* cli/cli-script.c (execute_control_command): Add instrumentation
for the source_verbose and commandtrace modes.
* top.c (execute_command): Likewise.
* cli/cli-cmds.h (source_verbose, commandtrace): New extern variables.
docs/
* gdb.texinfo (Choosing files): Add '-v' option to -command.
(Optional warnings and messages): Add 'set/show debug commandtrace'.
(Command files): Add '-v' to source command.
testsuite/
*gdb.base/help.exp: Update 'help source' message.
Index: src/gdb/cli/cli-cmds.c
===================================================================
--- src.orig/gdb/cli/cli-cmds.c 2005-11-14 14:49:25.000000000 +0000
+++ src/gdb/cli/cli-cmds.c 2005-11-14 17:37:07.000000000 +0000
@@ -170,6 +170,11 @@ struct cmd_list_element *showdebuglist;
struct cmd_list_element *setchecklist;
struct cmd_list_element *showchecklist;
+
+/* Command tracing state. */
+
+int source_verbose = 0;
+int commandtrace = 0;
\f
/* Utility used everywhere when at least one argument is needed and
none is supplied. */
@@ -426,8 +431,54 @@ source_command (char *args, int from_tty
FILE *stream;
struct cleanup *old_cleanups;
char *file = args;
+ char *minusv=NULL;
+ int old_source_verbose = source_verbose;
+
+ /* -v causes the source command to run in verbose mode.
+ We still have to be able to handle filenames with spaces. */
+
+ /* Is there a '-v' in the string somewhere? */
+ if (args && (minusv = strstr(args,"-v")))
+ {
+ char *t;
+ /* Make sure leading and trailing white space
+ does not break the comparisons. */
+ while (args[0] == ' ')
+ args++;
+ t = args+strlen(args);
+ while (t[-1] == ' ')
+ t--;
+ t[0] = '\0';
+
+ /* Is -v the first thing in the string? */
+ if (args == minusv && minusv[2] == ' ')
+ {
+ source_verbose = 1;
+
+ /* Trim -v and whitespace from the filename. */
+ file = &minusv[3];
+ while (file[0] == ' ')
+ file++;
+ }
+ /* Is -v the last thing in the string? */
+ else if (minusv[2] == '\0' && minusv[-1] == ' ')
+ {
+ source_verbose = 1;
- if (file == NULL)
+ /* Trim -v and whitespace from the filename. */
+ file = args;
+ while (minusv[-1] == ' ')
+ --minusv;
+ minusv[0] = '\0';
+ }
+ /* Otherwise -v just happens to be part of the filename. */
+ else
+ file = args;
+ }
+ else
+ file = args;
+
+ if (file == NULL || strlen (file) == 0)
{
error (_("source command requires pathname of file to source."));
}
@@ -438,6 +489,7 @@ source_command (char *args, int from_tty
stream = fopen (file, FOPEN_RT);
if (!stream)
{
+ source_verbose = old_source_verbose;
if (from_tty)
perror_with_name (file);
else
@@ -447,6 +499,7 @@ source_command (char *args, int from_tty
script_from_file (stream, file);
do_cleanups (old_cleanups);
+ source_verbose = old_source_verbose;
}
static void
@@ -1167,7 +1220,8 @@ Commands defined in this way may have up
source_help_text = xstrprintf (_("\
Read commands from a file named FILE.\n\
Note that the file \"%s\" is read automatically in this way\n\
-when gdb is started."), gdbinit);
+when gdb is started.\n\
+Use -v to see the name of the commands issued."), gdbinit);
c = add_cmd ("source", class_support, source_command,
source_help_text, &cmdlist);
set_cmd_completer (c, filename_completer);
@@ -1348,4 +1402,12 @@ Show the max call depth for user-defined
NULL,
show_max_user_call_depth,
&setlist, &showlist);
+
+ add_setshow_boolean_cmd ("commandtrace", no_class, &commandtrace, _("\
+Set tracing of GDB CLI commands."), _("\
+Show state of GDB CLI command tracing."), _("\
+When 'on', each command executed is displayed."),
+ NULL,
+ NULL,
+ &setdebuglist, &showdebuglist);
}
Index: src/gdb/cli/cli-script.c
===================================================================
--- src.orig/gdb/cli/cli-script.c 2005-11-14 17:35:31.000000000 +0000
+++ src/gdb/cli/cli-script.c 2005-11-14 17:37:07.000000000 +0000
@@ -316,7 +316,18 @@ execute_control_command (struct command_
break;
case continue_control:
+ if (source_verbose || commandtrace)
+ printf_unfiltered ("Command issued: loop_continue %s\n", cmd->line);
+
+ /* Return for "continue", and "break" so we can either
+ continue the loop at the top, or break out. */
+ ret = cmd->control_type;
+ break;
+
case break_control:
+ if (source_verbose || commandtrace)
+ printf_unfiltered ("Command issued: loop_break %s\n", cmd->line);
+
/* Return for "continue", and "break" so we can either
continue the loop at the top, or break out. */
ret = cmd->control_type;
@@ -324,6 +335,10 @@ execute_control_command (struct command_
case while_control:
{
+ if ((source_verbose || commandtrace)
+ && control_level > 1) /* Top level printed in execute_command(). */
+ printf_unfiltered ("Command issued: while %s\n", cmd->line);
+
/* Parse the loop control expression for the while statement. */
new_line = insert_args (cmd->line);
if (!new_line)
@@ -356,7 +371,9 @@ execute_control_command (struct command_
current = *cmd->body_list;
while (current)
{
+ control_level++;
ret = execute_control_command (current);
+ control_level--;
/* If we got an error, or a "break" command, then stop
looping. */
@@ -385,6 +402,10 @@ execute_control_command (struct command_
case if_control:
{
+ if ((source_verbose || commandtrace)
+ && control_level > 1) /* Top level printed in execute_command(). */
+ printf_unfiltered ("Command issued: if %s\n", cmd->line);
+
new_line = insert_args (cmd->line);
if (!new_line)
break;
@@ -411,7 +432,9 @@ execute_control_command (struct command_
/* Execute commands in the given arm. */
while (current)
{
+ control_level++;
ret = execute_control_command (current);
+ control_level--;
/* If we got an error, get out. */
if (ret != simple_control)
Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c 2005-11-14 17:37:06.000000000 +0000
+++ src/gdb/top.c 2005-11-14 17:37:07.000000000 +0000
@@ -395,6 +395,11 @@ execute_command (char *p, int from_tty)
while (*p == ' ' || *p == '\t')
p++;
+
+ if ((source_verbose || commandtrace)
+ && strlen (p) > 0)
+ printf_unfiltered ("Command issued: %s\n", p);
+
if (*p)
{
char *arg;
Index: src/gdb/testsuite/gdb.base/help.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/help.exp 2005-11-14 14:49:25.000000000 +0000
+++ src/gdb/testsuite/gdb.base/help.exp 2005-11-14 17:37:07.000000000 +0000
@@ -533,7 +533,7 @@ gdb_test "help stepi" "Step one instruct
gdb_test "help signal" "Continue program giving it signal.*" "help signal"
# test help source
# vxgdb reads .vxgdbinit
-gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\." "help source"
+gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\.\[\r\n\]+Use -v to see the name of the commands issued\." "help source"
# test help stack
gdb_test "help stack" "Examining the stack\..*\[\r\n\]+When the program being debugged stops, gdb selects the innermost frame\.\[\r\n\]+The commands below can be used to select other frames by number or address\.\[\r\n\]+List of commands:\[\r\n\]+backtrace -- Print backtrace of all stack frames\[\r\n\]+bt -- Print backtrace of all stack frames\[\r\n\]+down -- Select and print stack frame called by this one\[\r\n\]+frame -- Select and print a stack frame\[\r\n\]+return -- Make selected stack frame return to its caller\[\r\n\]+select-frame -- Select a stack frame without printing anything\[\r\n\]+up -- Select and print stack frame that called this one\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help stack"
# test help status
Index: src/gdb/cli/cli-cmds.h
===================================================================
--- src.orig/gdb/cli/cli-cmds.h 2005-11-14 14:49:25.000000000 +0000
+++ src/gdb/cli/cli-cmds.h 2005-11-14 17:37:07.000000000 +0000
@@ -122,4 +122,9 @@ extern void source_command (char *, int)
extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
+/* Command tracing state. */
+
+extern int source_verbose;
+extern int commandtrace;
+
#endif /* !defined (CLI_CMDS_H) */
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2005-11-14 17:37:02.000000000 +0000
+++ src/gdb/doc/gdb.texinfo 2005-11-14 17:37:07.000000000 +0000
@@ -929,8 +929,9 @@ file named @var{number}.
@itemx -x @var{file}
@cindex @code{--command}
@cindex @code{-x}
-Execute @value{GDBN} commands from file @var{file}. @xref{Command
-Files,, Command files}.
+Execute @value{GDBN} commands from file @var{file}. If @var{file} begins or
+ends with @samp{-v} (separated by a space), then the commands are printed as
+they are executed. @xref{Command Files,, Command files}.
@item -eval-command @var{command}
@itemx -ex @var{command}
@@ -15612,6 +15613,20 @@ Displays state of confirmation requests.
@end table
+If you need to debug user-defined commands or sourced files you may find it
+useful to enable command tracing. In this mode each command will be printed
+as it is executed, prefixed with @samp{Command issued:}.
+
+@table @code
+@kindex set debug commandtrace
+@item set debug commandtrace on
+Enable command tracing.
+@item set debug commandtrace off
+Disable command tracing.
+@item show debug commandtrace
+Display the current state of command tracing.
+@end table
+
@node Debugging Output
@section Optional messages about internal happenings
@cindex optional debugging messages
@@ -15968,7 +15983,7 @@ command:
@table @code
@kindex source
-@item source @var{filename}
+@item source [@code{-v}] @var{filename}
Execute the command file @var{filename}.
@end table
@@ -15976,6 +15991,10 @@ The lines in a command file are executed
printed as they are executed. An error in any command terminates
execution of the command file and control is returned to the console.
+If @code{-v}, for verbose mode, is given then then each command will
+be displayed as it is executed. The option may be given before or after
+@var{filename}, but will be interpreted as part of the filename anywhere else.
+
Commands that would ask for confirmation if used interactively proceed
without asking when used in a command file. Many @value{GDBN} commands that
normally print messages to say what they are doing omit the messages
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2005-11-16 18:01 [PATCH] command trace / source verbose mode Andrew STUBBS
@ 2005-11-16 20:11 ` Eli Zaretskii
2005-11-17 16:21 ` Andrew STUBBS
0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2005-11-16 20:11 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: gdb-patches
> Date: Wed, 16 Nov 2005 16:45:28 +0000
> From: Andrew STUBBS <andrew.stubbs@st.com>
>
> + add_setshow_boolean_cmd ("commandtrace", no_class, &commandtrace, _("\
> +Set tracing of GDB CLI commands."), _("\
> +Show state of GDB CLI command tracing."), _("\
> +When 'on', each command executed is displayed."),
The last sentence will read better if it is rephrased as follows:
When 'on', each command is displayed as it is executed.
> Index: src/gdb/doc/gdb.texinfo
Thanks. Please take care of the following gotchas, and then the
documentation patch can go in when the code is approved.
> +Execute @value{GDBN} commands from file @var{file}.
It is better to say
Execute @value{GDBN} commands from the named @var{file}.
> +If you need to debug user-defined commands or sourced files you may find it
> +useful to enable command tracing. In this mode each command will be printed
^^
Need two blanks here.
> +If @code{-v}, for verbose mode, is given then then each command will
^^^^^^^^^
One "then" too much.
> +be displayed as it is executed. The option may be given before or after
^^
Need two blanks here.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2005-11-16 20:11 ` Eli Zaretskii
@ 2005-11-17 16:21 ` Andrew STUBBS
2006-07-06 13:16 ` Daniel Jacobowitz
0 siblings, 1 reply; 13+ messages in thread
From: Andrew STUBBS @ 2005-11-17 16:21 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 250 bytes --]
Eli Zaretskii wrote:
>>+be displayed as it is executed. The option may be given before or after
> ^^
> Need two blanks here.
This one is going to bite me forever :(
Anyway, updated patch attached.
Thanks
Andrew
[-- Attachment #2: command-trace.patch --]
[-- Type: text/plain, Size: 11208 bytes --]
2005-11-17 Andrew Stubbs <andrew.stubbs@st.com>
* cli/cli-cmds.c (source_verbose, commandtrace): New variables.
(source_command): Add -v option.
(init_cli_cmds): Update source command help.
Add 'set debug commandtrace' command.
* cli/cli-script.c (execute_control_command): Add instrumentation
for the source_verbose and commandtrace modes.
* top.c (execute_command): Likewise.
* cli/cli-cmds.h (source_verbose, commandtrace): New extern variables.
docs/
* gdb.texinfo (Choosing files): Add '-v' option to -command.
(Optional warnings and messages): Add 'set/show debug commandtrace'.
(Command files): Add '-v' to source command.
testsuite/
*gdb.base/help.exp: Update 'help source' message.
Index: src/gdb/cli/cli-cmds.c
===================================================================
--- src.orig/gdb/cli/cli-cmds.c 2005-11-16 15:37:58.000000000 +0000
+++ src/gdb/cli/cli-cmds.c 2005-11-17 14:44:45.000000000 +0000
@@ -170,6 +170,11 @@ struct cmd_list_element *showdebuglist;
struct cmd_list_element *setchecklist;
struct cmd_list_element *showchecklist;
+
+/* Command tracing state. */
+
+int source_verbose = 0;
+int commandtrace = 0;
\f
/* Utility used everywhere when at least one argument is needed and
none is supplied. */
@@ -426,8 +431,54 @@ source_command (char *args, int from_tty
FILE *stream;
struct cleanup *old_cleanups;
char *file = args;
+ char *minusv=NULL;
+ int old_source_verbose = source_verbose;
+
+ /* -v causes the source command to run in verbose mode.
+ We still have to be able to handle filenames with spaces. */
+
+ /* Is there a '-v' in the string somewhere? */
+ if (args && (minusv = strstr(args,"-v")))
+ {
+ char *t;
+ /* Make sure leading and trailing white space
+ does not break the comparisons. */
+ while (args[0] == ' ')
+ args++;
+ t = args+strlen(args);
+ while (t[-1] == ' ')
+ t--;
+ t[0] = '\0';
+
+ /* Is -v the first thing in the string? */
+ if (args == minusv && minusv[2] == ' ')
+ {
+ source_verbose = 1;
+
+ /* Trim -v and whitespace from the filename. */
+ file = &minusv[3];
+ while (file[0] == ' ')
+ file++;
+ }
+ /* Is -v the last thing in the string? */
+ else if (minusv[2] == '\0' && minusv[-1] == ' ')
+ {
+ source_verbose = 1;
- if (file == NULL)
+ /* Trim -v and whitespace from the filename. */
+ file = args;
+ while (minusv[-1] == ' ')
+ --minusv;
+ minusv[0] = '\0';
+ }
+ /* Otherwise -v just happens to be part of the filename. */
+ else
+ file = args;
+ }
+ else
+ file = args;
+
+ if (file == NULL || strlen (file) == 0)
{
error (_("source command requires pathname of file to source."));
}
@@ -438,6 +489,7 @@ source_command (char *args, int from_tty
stream = fopen (file, FOPEN_RT);
if (!stream)
{
+ source_verbose = old_source_verbose;
if (from_tty)
perror_with_name (file);
else
@@ -447,6 +499,7 @@ source_command (char *args, int from_tty
script_from_file (stream, file);
do_cleanups (old_cleanups);
+ source_verbose = old_source_verbose;
}
static void
@@ -1167,7 +1220,8 @@ Commands defined in this way may have up
source_help_text = xstrprintf (_("\
Read commands from a file named FILE.\n\
Note that the file \"%s\" is read automatically in this way\n\
-when gdb is started."), gdbinit);
+when gdb is started.\n\
+Use -v to see the name of the commands issued."), gdbinit);
c = add_cmd ("source", class_support, source_command,
source_help_text, &cmdlist);
set_cmd_completer (c, filename_completer);
@@ -1348,4 +1402,12 @@ Show the max call depth for user-defined
NULL,
show_max_user_call_depth,
&setlist, &showlist);
+
+ add_setshow_boolean_cmd ("commandtrace", no_class, &commandtrace, _("\
+Set tracing of GDB CLI commands."), _("\
+Show state of GDB CLI command tracing."), _("\
+When 'on', each command is displayed as it is executed."),
+ NULL,
+ NULL,
+ &setdebuglist, &showdebuglist);
}
Index: src/gdb/cli/cli-script.c
===================================================================
--- src.orig/gdb/cli/cli-script.c 2005-11-16 15:37:58.000000000 +0000
+++ src/gdb/cli/cli-script.c 2005-11-16 17:04:22.000000000 +0000
@@ -316,7 +316,18 @@ execute_control_command (struct command_
break;
case continue_control:
+ if (source_verbose || commandtrace)
+ printf_unfiltered ("Command issued: loop_continue %s\n", cmd->line);
+
+ /* Return for "continue", and "break" so we can either
+ continue the loop at the top, or break out. */
+ ret = cmd->control_type;
+ break;
+
case break_control:
+ if (source_verbose || commandtrace)
+ printf_unfiltered ("Command issued: loop_break %s\n", cmd->line);
+
/* Return for "continue", and "break" so we can either
continue the loop at the top, or break out. */
ret = cmd->control_type;
@@ -324,6 +335,10 @@ execute_control_command (struct command_
case while_control:
{
+ if ((source_verbose || commandtrace)
+ && control_level > 1) /* Top level printed in execute_command(). */
+ printf_unfiltered ("Command issued: while %s\n", cmd->line);
+
/* Parse the loop control expression for the while statement. */
new_line = insert_args (cmd->line);
if (!new_line)
@@ -356,7 +371,9 @@ execute_control_command (struct command_
current = *cmd->body_list;
while (current)
{
+ control_level++;
ret = execute_control_command (current);
+ control_level--;
/* If we got an error, or a "break" command, then stop
looping. */
@@ -385,6 +402,10 @@ execute_control_command (struct command_
case if_control:
{
+ if ((source_verbose || commandtrace)
+ && control_level > 1) /* Top level printed in execute_command(). */
+ printf_unfiltered ("Command issued: if %s\n", cmd->line);
+
new_line = insert_args (cmd->line);
if (!new_line)
break;
@@ -411,7 +432,9 @@ execute_control_command (struct command_
/* Execute commands in the given arm. */
while (current)
{
+ control_level++;
ret = execute_control_command (current);
+ control_level--;
/* If we got an error, get out. */
if (ret != simple_control)
Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c 2005-11-16 17:04:21.000000000 +0000
+++ src/gdb/top.c 2005-11-16 17:04:22.000000000 +0000
@@ -395,6 +395,11 @@ execute_command (char *p, int from_tty)
while (*p == ' ' || *p == '\t')
p++;
+
+ if ((source_verbose || commandtrace)
+ && strlen (p) > 0)
+ printf_unfiltered ("Command issued: %s\n", p);
+
if (*p)
{
char *arg;
Index: src/gdb/testsuite/gdb.base/help.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/help.exp 2005-11-16 15:37:58.000000000 +0000
+++ src/gdb/testsuite/gdb.base/help.exp 2005-11-16 17:04:22.000000000 +0000
@@ -533,7 +533,7 @@ gdb_test "help stepi" "Step one instruct
gdb_test "help signal" "Continue program giving it signal.*" "help signal"
# test help source
# vxgdb reads .vxgdbinit
-gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\." "help source"
+gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\.\[\r\n\]+Use -v to see the name of the commands issued\." "help source"
# test help stack
gdb_test "help stack" "Examining the stack\..*\[\r\n\]+When the program being debugged stops, gdb selects the innermost frame\.\[\r\n\]+The commands below can be used to select other frames by number or address\.\[\r\n\]+List of commands:\[\r\n\]+backtrace -- Print backtrace of all stack frames\[\r\n\]+bt -- Print backtrace of all stack frames\[\r\n\]+down -- Select and print stack frame called by this one\[\r\n\]+frame -- Select and print a stack frame\[\r\n\]+return -- Make selected stack frame return to its caller\[\r\n\]+select-frame -- Select a stack frame without printing anything\[\r\n\]+up -- Select and print stack frame that called this one\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help stack"
# test help status
Index: src/gdb/cli/cli-cmds.h
===================================================================
--- src.orig/gdb/cli/cli-cmds.h 2005-11-16 15:37:58.000000000 +0000
+++ src/gdb/cli/cli-cmds.h 2005-11-16 17:04:22.000000000 +0000
@@ -122,4 +122,9 @@ extern void source_command (char *, int)
extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
+/* Command tracing state. */
+
+extern int source_verbose;
+extern int commandtrace;
+
#endif /* !defined (CLI_CMDS_H) */
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2005-11-16 17:04:18.000000000 +0000
+++ src/gdb/doc/gdb.texinfo 2005-11-17 14:47:52.000000000 +0000
@@ -929,8 +929,9 @@ file named @var{number}.
@itemx -x @var{file}
@cindex @code{--command}
@cindex @code{-x}
-Execute @value{GDBN} commands from file @var{file}. @xref{Command
-Files,, Command files}.
+Execute @value{GDBN} commands from the named @var{file}. If @var{file}
+begins or ends with @samp{-v} (separated by a space), then the commands are
+printed as they are executed. @xref{Command Files,, Command files}.
@item -eval-command @var{command}
@itemx -ex @var{command}
@@ -15612,6 +15613,20 @@ Displays state of confirmation requests.
@end table
+If you need to debug user-defined commands or sourced files you may find it
+useful to enable command tracing. In this mode each command will be printed
+as it is executed, prefixed with @samp{Command issued:}.
+
+@table @code
+@kindex set debug commandtrace
+@item set debug commandtrace on
+Enable command tracing.
+@item set debug commandtrace off
+Disable command tracing.
+@item show debug commandtrace
+Display the current state of command tracing.
+@end table
+
@node Debugging Output
@section Optional messages about internal happenings
@cindex optional debugging messages
@@ -15968,7 +15983,7 @@ command:
@table @code
@kindex source
-@item source @var{filename}
+@item source [@code{-v}] @var{filename}
Execute the command file @var{filename}.
@end table
@@ -15976,6 +15991,10 @@ The lines in a command file are executed
printed as they are executed. An error in any command terminates
execution of the command file and control is returned to the console.
+If @code{-v}, for verbose mode, is given then each command will
+be displayed as it is executed. The option may be given before or after
+@var{filename}, but will be interpreted as part of the filename anywhere else.
+
Commands that would ask for confirmation if used interactively proceed
without asking when used in a command file. Many @value{GDBN} commands that
normally print messages to say what they are doing omit the messages
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2005-11-17 16:21 ` Andrew STUBBS
@ 2006-07-06 13:16 ` Daniel Jacobowitz
2006-07-06 17:23 ` Andrew STUBBS
0 siblings, 1 reply; 13+ messages in thread
From: Daniel Jacobowitz @ 2006-07-06 13:16 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: Eli Zaretskii, gdb-patches
Hi Andrew,
Sorry for not getting back to you on this. Never made it back here
when reviewing patches in reverse. Trying in patch tracker order
today.
On Thu, Nov 17, 2005 at 03:04:39PM +0000, Andrew STUBBS wrote:
> +/* Command tracing state. */
> +
> +int source_verbose = 0;
> +int commandtrace = 0;
You've got two of these, but you always check them together. One
variable and incrementing/decrementing the trace level around source
would work too, right?
> + char *minusv=NULL;
Spaces around operators please.
> + int old_source_verbose = source_verbose;
You do this in a couple places, at least here and for control_level.
Given the way GDB handles errors with longjmp, this isn't safe. I
recommend you use cleanups instead. Either one to decrement
commandtrace (trace_commands?) and one to decrement control_level,
or write a general function in utils.c to make a cleanup which
decrements an integer.
> + /* Is there a '-v' in the string somewhere? */
> + if (args && (minusv = strstr(args,"-v")))
Is there any benefit to supporting this at the end? We've already got
some other commands that are strictly command [options] [args], I
think, or at least we do in MI; I would recommend following the same
model here. If it starts with -v it's an option.
> + add_setshow_boolean_cmd ("commandtrace", no_class, &commandtrace, _("\
I don't feel too strongly about this, just personal bias, but how about
something other than run-together words for this? We have a lot of
those in the existing code e.g. remotetimeout, but we've been trying to
either use hyphens or use spaces and sub-menus lately, I think.
Something like "set trace-commands". Or, alternatively "set debug
cli-commands".
> case continue_control:
> + if (source_verbose || commandtrace)
> + printf_unfiltered ("Command issued: loop_continue %s\n", cmd->line);
If we do this, we should also use _() so that "Command issued" can be
translated. Another alternative would be to use the time-honored shell
syntax for this: prefix with plusses up to the nesting level, like sh
-x. What do you think?
:REVIEWMAIL:
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2006-07-06 13:16 ` Daniel Jacobowitz
@ 2006-07-06 17:23 ` Andrew STUBBS
2006-07-06 17:33 ` Daniel Jacobowitz
0 siblings, 1 reply; 13+ messages in thread
From: Andrew STUBBS @ 2006-07-06 17:23 UTC (permalink / raw)
To: Eli Zaretskii, gdb-patches
Daniel Jacobowitz wrote:
> Sorry for not getting back to you on this. Never made it back here
> when reviewing patches in reverse. Trying in patch tracker order
> today.
No problem, but I knew the patch tracker would be a good thing. :)
> On Thu, Nov 17, 2005 at 03:04:39PM +0000, Andrew STUBBS wrote:
>> +/* Command tracing state. */
>> +
>> +int source_verbose = 0;
>> +int commandtrace = 0;
>
> You've got two of these, but you always check them together. One
> variable and incrementing/decrementing the trace level around source
> would work too, right?
Yeah, that might work too. But the downside is that if the 'set debug
commandtrace on' is issued multiple times then the user will have to
turn it off that many times also.
>> + /* Is there a '-v' in the string somewhere? */
>> + if (args && (minusv = strstr(args,"-v")))
>
> Is there any benefit to supporting this at the end? We've already got
> some other commands that are strictly command [options] [args], I
> think, or at least we do in MI; I would recommend following the same
> model here. If it starts with -v it's an option.
Does it do any harm beyond making the code a little more complex? I was
rather expecting you to say something about the fact that it changes the
argument to the --command option (I documented the change).
>> + add_setshow_boolean_cmd ("commandtrace", no_class, &commandtrace, _("\
>
> I don't feel too strongly about this, just personal bias, but how about
> something other than run-together words for this? We have a lot of
> those in the existing code e.g. remotetimeout, but we've been trying to
> either use hyphens or use spaces and sub-menus lately, I think.
> Something like "set trace-commands". Or, alternatively "set debug
> cli-commands".
Well, since we have been using this for a long time now (long before I
posted the patch) I will need to keep this version in our own sources
for purposes of backwards compatibility. That being so, it really
doesn't matter to me what official name is chosen.
I think keeping it under 'set debug' is a good idea, but maybe because
it is for debugging other than GDB itself it should be promoted to
somewhere more prominent. Hmmm, perhaps "set trace-commands" it the best
option.
I'll have a think about it, work on the other points you raised, and get
back to you.
Andrew
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2006-07-06 17:23 ` Andrew STUBBS
@ 2006-07-06 17:33 ` Daniel Jacobowitz
2006-07-07 16:18 ` Andrew STUBBS
0 siblings, 1 reply; 13+ messages in thread
From: Daniel Jacobowitz @ 2006-07-06 17:33 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: Eli Zaretskii, gdb-patches
On Thu, Jul 06, 2006 at 06:22:42PM +0100, Andrew STUBBS wrote:
> >On Thu, Nov 17, 2005 at 03:04:39PM +0000, Andrew STUBBS wrote:
> >>+/* Command tracing state. */
> >>+
> >>+int source_verbose = 0;
> >>+int commandtrace = 0;
> >
> >You've got two of these, but you always check them together. One
> >variable and incrementing/decrementing the trace level around source
> >would work too, right?
>
> Yeah, that might work too. But the downside is that if the 'set debug
> commandtrace on' is issued multiple times then the user will have to
> turn it off that many times also.
Oh, good point. Your way it is.
> >>+ /* Is there a '-v' in the string somewhere? */
> >>+ if (args && (minusv = strstr(args,"-v")))
> >
> >Is there any benefit to supporting this at the end? We've already got
> >some other commands that are strictly command [options] [args], I
> >think, or at least we do in MI; I would recommend following the same
> >model here. If it starts with -v it's an option.
>
> Does it do any harm beyond making the code a little more complex? I was
> rather expecting you to say something about the fact that it changes the
> argument to the --command option (I documented the change).
I think that's pretty strange too; I'd rather it didn't.
I don't know if it does any harm, but it does make the code more
complex, and I don't think it's particularly useful.
> I think keeping it under 'set debug' is a good idea, but maybe because
> it is for debugging other than GDB itself it should be promoted to
> somewhere more prominent. Hmmm, perhaps "set trace-commands" it the best
> option.
>
> I'll have a think about it, work on the other points you raised, and get
> back to you.
Sounds good. I think you're right about keeping it out of set debug
after all. Got to be careful here: we're debugging user commands
during debugging of a user program, but not debugging the debugger.
Say that three times fast, I dare you.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2006-07-06 17:33 ` Daniel Jacobowitz
@ 2006-07-07 16:18 ` Andrew STUBBS
2006-07-08 12:02 ` Eli Zaretskii
0 siblings, 1 reply; 13+ messages in thread
From: Andrew STUBBS @ 2006-07-07 16:18 UTC (permalink / raw)
To: Eli Zaretskii, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1817 bytes --]
Here is a new version of the patch.
I have changed the command from 'set debug commandtrace' to 'set
trace-commands' and adjusted the variable name to match.
The source_verbose is now reset with a cleanup.
The -v option is only valid before the filename.
The -v option no longer applies to the --command option. This change has
meant that I have had to stop main.c using source_command() and invent a
new function, source_script(), for it to use.
The strings are now surrounded by _(...)
> You do this in a couple places, at least here and for control_level.
> Given the way GDB handles errors with longjmp, this isn't safe.
control_level is not a problem. It is always re-initialised whenever an
'if', 'while', or user defined command is encountered. The new code only
uses it to prevent the same command getting printed more than once. This
is necessary due to the way the execute_command() and
execute_control_command() interact.
> Another alternative would be to use the time-honored shell
> syntax for this: prefix with plusses up to the nesting level, like sh
> -x. What do you think?
I have considered this feature in some detail. There is, of course,
nothing to stop us using any string or symbol we like, but the nesting
level is tricky. As it stands the code does not really know how deep it
is. The control_level is not the real depth - it only really says how
deep it is from the last simple command such as 'source' or a
user-defined command, as opposed to control commands such 'if'.
If you really want to show the depth then some more thought will be
required. The depth will have to be calculated properly somehow and it
will have to be exposed to top.c which prints all the top level commands
and nested simple commands.
What do you think?
:ADDPATCH CLI:
Andrew Stubbs
[-- Attachment #2: command-trace.patch --]
[-- Type: text/plain, Size: 13333 bytes --]
2006-07-07 Andrew Stubbs <andrew.stubbs@st.com>
* cli/cli-cmds.c (source_verbose, trace_commands): New variables.
(source_script): New function.
(source_verbose_cleanup): New function.
(source_command): Move old contents to source_script().
Make function static. Parse -v option and call source_script.
(init_cli_cmds): Update source command help.
Add 'set trace_commands' command.
* cli/cli-script.c (execute_user_command): Set control_level.
(execute_control_command): Add instrumentation for the source_verbose
and trace_command modes.
* top.c (execute_command): Likewise.
* cli/cli-cmds.h (source_verbose, trace_commands): New extern variables.
(source_command): Change to source_script.
* main.c (captued_main): Use source_script instead of source_command.
* top.h (source_command): Change to source_script.
docs/
* gdb.texinfo (Optional warnings and messages): Add
'set/show trace-commands'.
(Command files): Add '-v' to source command.
testsuite/
*gdb.base/help.exp: Update 'help source' message.
Index: src/gdb/cli/cli-cmds.c
===================================================================
--- src.orig/gdb/cli/cli-cmds.c 2006-07-07 16:17:17.000000000 +0100
+++ src/gdb/cli/cli-cmds.c 2006-07-07 16:30:26.000000000 +0100
@@ -173,6 +173,11 @@ struct cmd_list_element *showdebuglist;
struct cmd_list_element *setchecklist;
struct cmd_list_element *showchecklist;
+
+/* Command tracing state. */
+
+int source_verbose = 0;
+int trace_commands = 0;
\f
/* Utility used everywhere when at least one argument is needed and
none is supplied. */
@@ -424,15 +429,14 @@ cd_command (char *dir, int from_tty)
}
\f
void
-source_command (char *args, int from_tty)
+source_script (char *file, int from_tty)
{
FILE *stream;
struct cleanup *old_cleanups;
- char *file = args;
char *full_pathname = NULL;
int fd;
- if (file == NULL)
+ if (file == NULL || strlen (file) == 0)
{
error (_("source command requires pathname of file to source."));
}
@@ -465,6 +469,48 @@ source_command (char *args, int from_tty
do_cleanups (old_cleanups);
}
+/* Return the source_verbose global variable to its previous state
+ on exit from the source command, by whatever means. */
+static void
+source_verbose_cleanup (void *old_value)
+{
+ source_verbose = (int) old_value;
+}
+
+static void
+source_command (char *args, int from_tty)
+{
+ struct cleanup *old_cleanups;
+ char *file = args;
+
+ old_cleanups = make_cleanup (source_verbose_cleanup, (void *)source_verbose);
+
+ /* -v causes the source command to run in verbose mode.
+ We still have to be able to handle filenames with spaces in a
+ backward compatible way, so buildargv is not appropriate. */
+
+ if (args)
+ {
+ /* Make sure leading white space does not break the comparisons. */
+ while (isspace(args[0]))
+ args++;
+
+ /* Is -v the first thing in the string? */
+ if (args[0] == '-' && args[1] == 'v' && isspace (args[2]))
+ {
+ source_verbose = 1;
+
+ /* Trim -v and whitespace from the filename. */
+ file = &args[3];
+ while (isspace (file[0]))
+ file++;
+ }
+ }
+
+ return source_script (file, from_tty);
+}
+
+
static void
echo_command (char *text, int from_tty)
{
@@ -1183,7 +1229,8 @@ Commands defined in this way may have up
source_help_text = xstrprintf (_("\
Read commands from a file named FILE.\n\
Note that the file \"%s\" is read automatically in this way\n\
-when gdb is started."), gdbinit);
+when gdb is started.\n\
+Use -v to see the name of the commands issued."), gdbinit);
c = add_cmd ("source", class_support, source_command,
source_help_text, &cmdlist);
set_cmd_completer (c, filename_completer);
@@ -1364,4 +1411,12 @@ Show the max call depth for user-defined
NULL,
show_max_user_call_depth,
&setlist, &showlist);
+
+ add_setshow_boolean_cmd ("trace-commands", no_class, &trace_commands, _("\
+Set tracing of GDB CLI commands."), _("\
+Show state of GDB CLI command tracing."), _("\
+When 'on', each command is displayed as it is executed."),
+ NULL,
+ NULL,
+ &setlist, &showlist);
}
Index: src/gdb/cli/cli-script.c
===================================================================
--- src.orig/gdb/cli/cli-script.c 2006-07-07 16:17:17.000000000 +0100
+++ src/gdb/cli/cli-script.c 2006-07-07 16:17:55.000000000 +0100
@@ -280,6 +280,10 @@ execute_user_command (struct cmd_list_el
not confused with Insight. */
in_user_command = 1;
+ /* Set the control level to ensure that all control commands are
+ printed when trace_commands is set. */
+ control_level = 2;
+
while (cmdlines)
{
ret = execute_control_command (cmdlines);
@@ -322,7 +326,18 @@ execute_control_command (struct command_
break;
case continue_control:
+ if (source_verbose || trace_commands)
+ printf_unfiltered (_("Command issued: loop_continue %s\n"), cmd->line);
+
+ /* Return for "continue", and "break" so we can either
+ continue the loop at the top, or break out. */
+ ret = cmd->control_type;
+ break;
+
case break_control:
+ if (source_verbose || trace_commands)
+ printf_unfiltered (_("Command issued: loop_break %s\n"), cmd->line);
+
/* Return for "continue", and "break" so we can either
continue the loop at the top, or break out. */
ret = cmd->control_type;
@@ -330,6 +345,10 @@ execute_control_command (struct command_
case while_control:
{
+ if ((source_verbose || trace_commands)
+ && control_level > 1) /* Top level printed in execute_command(). */
+ printf_unfiltered (_("Command issued: while %s\n"), cmd->line);
+
/* Parse the loop control expression for the while statement. */
new_line = insert_args (cmd->line);
if (!new_line)
@@ -362,7 +381,9 @@ execute_control_command (struct command_
current = *cmd->body_list;
while (current)
{
+ control_level++;
ret = execute_control_command (current);
+ control_level--;
/* If we got an error, or a "break" command, then stop
looping. */
@@ -391,6 +412,10 @@ execute_control_command (struct command_
case if_control:
{
+ if ((source_verbose || trace_commands)
+ && control_level > 1) /* Top level printed in execute_command(). */
+ printf_unfiltered (_("Command issued: if %s\n"), cmd->line);
+
new_line = insert_args (cmd->line);
if (!new_line)
break;
@@ -417,7 +442,9 @@ execute_control_command (struct command_
/* Execute commands in the given arm. */
while (current)
{
+ control_level++;
ret = execute_control_command (current);
+ control_level--;
/* If we got an error, get out. */
if (ret != simple_control)
Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c 2006-07-07 16:17:17.000000000 +0100
+++ src/gdb/top.c 2006-07-07 16:17:55.000000000 +0100
@@ -395,6 +395,11 @@ execute_command (char *p, int from_tty)
while (*p == ' ' || *p == '\t')
p++;
+
+ if ((source_verbose || trace_commands)
+ && strlen (p) > 0)
+ printf_unfiltered (_("Command issued: %s\n"), p);
+
if (*p)
{
char *arg;
Index: src/gdb/testsuite/gdb.base/help.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/help.exp 2006-07-07 16:17:17.000000000 +0100
+++ src/gdb/testsuite/gdb.base/help.exp 2006-07-07 16:17:55.000000000 +0100
@@ -533,7 +533,7 @@ gdb_test "help stepi" "Step one instruct
gdb_test "help signal" "Continue program giving it signal.*" "help signal"
# test help source
# vxgdb reads .vxgdbinit
-gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\." "help source"
+gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\.\[\r\n\]+Use -v to see the name of the commands issued\." "help source"
# test help stack
gdb_test "help stack" "Examining the stack\..*\[\r\n\]+When the program being debugged stops, gdb selects the innermost frame\.\[\r\n\]+The commands below can be used to select other frames by number or address\.\[\r\n\]+List of commands:\[\r\n\]+backtrace -- Print backtrace of all stack frames\[\r\n\]+bt -- Print backtrace of all stack frames\[\r\n\]+down -- Select and print stack frame called by this one\[\r\n\]+frame -- Select and print a stack frame\[\r\n\]+return -- Make selected stack frame return to its caller\[\r\n\]+select-frame -- Select a stack frame without printing anything\[\r\n\]+up -- Select and print stack frame that called this one\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help stack"
# test help status
Index: src/gdb/cli/cli-cmds.h
===================================================================
--- src.orig/gdb/cli/cli-cmds.h 2006-07-07 16:17:17.000000000 +0100
+++ src/gdb/cli/cli-cmds.h 2006-07-07 16:34:16.000000000 +0100
@@ -115,11 +115,16 @@ extern void cd_command (char *, int);
extern void quit_command (char *, int);
-extern void source_command (char *, int);
+extern void source_script (char *, int);
/* Used everywhere whenever at least one parameter is required and
none is specified. */
extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
+/* Command tracing state. */
+
+extern int source_verbose;
+extern int trace_commands;
+
#endif /* !defined (CLI_CMDS_H) */
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2006-07-07 16:17:17.000000000 +0100
+++ src/gdb/doc/gdb.texinfo 2006-07-07 16:17:55.000000000 +0100
@@ -15999,6 +15999,20 @@ Displays state of confirmation requests.
@end table
+If you need to debug user-defined commands or sourced files you may find it
+useful to enable command tracing. In this mode each command will be printed
+as it is executed, prefixed with @samp{Command issued:}.
+
+@table @code
+@kindex set debug commandtrace
+@item set debug commandtrace on
+Enable command tracing.
+@item set debug commandtrace off
+Disable command tracing.
+@item show debug commandtrace
+Display the current state of command tracing.
+@end table
+
@node Debugging Output
@section Optional messages about internal happenings
@cindex optional debugging messages
@@ -16347,7 +16361,7 @@ command:
@table @code
@kindex source
@cindex execute commands from a file
-@item source @var{filename}
+@item source [@code{-v}] @var{filename}
Execute the command file @var{filename}.
@end table
@@ -16360,6 +16374,10 @@ execution of the command file and contro
@value{GDBN} searches for @var{filename} in the current directory and then
on the search path (specified with the @samp{directory} command).
+If @code{-v}, for verbose mode, is given then each command will
+be displayed as it is executed. The option must be given before
+@var{filename}, and will be interpreted as part of the filename anywhere else.
+
Commands that would ask for confirmation if used interactively proceed
without asking when used in a command file. Many @value{GDBN} commands that
normally print messages to say what they are doing omit the messages
Index: src/gdb/main.c
===================================================================
--- src.orig/gdb/main.c 2006-02-21 19:46:48.000000000 +0000
+++ src/gdb/main.c 2006-07-07 16:35:19.000000000 +0100
@@ -643,7 +643,7 @@ extern int gdbtk_test (char *);
if (!inhibit_gdbinit)
{
- catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);
+ catch_command_errors (source_script, homeinit, 0, RETURN_MASK_ALL);
}
/* Do stats; no need to do them elsewhere since we'll only
@@ -730,7 +730,7 @@ extern int gdbtk_test (char *);
|| memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
if (!inhibit_gdbinit)
{
- catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL);
+ catch_command_errors (source_script, gdbinit, 0, RETURN_MASK_ALL);
}
for (i = 0; i < ncmd; i++)
@@ -748,12 +748,12 @@ extern int gdbtk_test (char *);
read_command_file (stdin);
else
#endif
- source_command (cmdarg[i], !batch);
+ source_script (cmdarg[i], !batch);
do_cleanups (ALL_CLEANUPS);
}
#endif
if (cmdarg[i].type == CMDARG_FILE)
- catch_command_errors (source_command, cmdarg[i].string,
+ catch_command_errors (source_script, cmdarg[i].string,
!batch, RETURN_MASK_ALL);
else /* cmdarg[i].type == CMDARG_COMMAND */
catch_command_errors (execute_command, cmdarg[i].string,
Index: src/gdb/top.h
===================================================================
--- src.orig/gdb/top.h 2006-03-29 23:53:33.000000000 +0100
+++ src/gdb/top.h 2006-07-07 16:33:50.000000000 +0100
@@ -36,7 +36,7 @@ extern char gdbinit[];
extern void print_gdb_version (struct ui_file *);
-extern void source_command (char *, int);
+extern void source_script (char *, int);
extern void cd_command (char *, int);
extern void read_command_file (FILE *);
extern void init_history (void);
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2006-07-07 16:18 ` Andrew STUBBS
@ 2006-07-08 12:02 ` Eli Zaretskii
2006-07-20 16:46 ` Andrew STUBBS
0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2006-07-08 12:02 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: gdb-patches
> Date: Fri, 07 Jul 2006 17:17:38 +0100
> From: Andrew STUBBS <andrew.stubbs@st.com>
>
> Here is a new version of the patch.
Thanks.
> (source_command): Move old contents to source_script().
Please don't use foo() to signal that `foo' is a function. That
syntax looks like a call to `foo' with no arguments, which is not what
you mean. Just source_script or `source_script' is enough.
> +/* Return the source_verbose global variable to its previous state
> + on exit from the source command, by whatever means. */
> +static void
> +source_verbose_cleanup (void *old_value)
> +{
> + source_verbose = (int) old_value;
> +}
> +
> +static void
> +source_command (char *args, int from_tty)
> +{
> + struct cleanup *old_cleanups;
> + char *file = args;
> +
> + old_cleanups = make_cleanup (source_verbose_cleanup, (void *)source_verbose);
> +
Ouch! Can't we use something cleaner than casting an int to a void
pointer and back? Don't we risk here tripping on issues like int vs
pointer size, sign extension, etc.?
> case continue_control:
> + if (source_verbose || trace_commands)
> + printf_unfiltered (_("Command issued: loop_continue %s\n"), cmd->line);
Perhaps it's better to have a function to print these messages, which
you will then call with a single argument--the command to announce.
If nothing else, it will reduce the number of messages to translate to
a bare minimum.
Also, how about making the message more self-explaining, like this:
Trace: loop_continue %s\n
or
source: loop_continue %s\n
or even
%s: loop_continue %s
where the first %s gets replaced by the file from which we read the
commands. I find ``Command issued'' too general to make immediately
evident what is being reported here.
> @@ -1183,7 +1229,8 @@ Commands defined in this way may have up
> source_help_text = xstrprintf (_("\
> Read commands from a file named FILE.\n\
> Note that the file \"%s\" is read automatically in this way\n\
> -when gdb is started."), gdbinit);
> +when gdb is started.\n\
> +Use -v to see the name of the commands issued."), gdbinit);
I think the second sentence of the doc string should come after the
third, since it's just a note.
Also ``to see the name of the commands issued'' sounds awkward to me.
I suggest the following text instead:
Optional -v switch causes each command in FILE to be echoed
as it is executed.
> +If you need to debug user-defined commands or sourced files you may find it
> +useful to enable command tracing. In this mode each command will be printed
> +as it is executed, prefixed with @samp{Command issued:}.
An @cindex entry here would be useful. Imagine yourself trying to
look for this command without knowing its name, and think about the
words or phrases you'd have in mind to try to locate the description
of such a command--these should be the phrases in the @cindex entry.
> +If @code{-v}, for verbose mode, is given then each command will
> +be displayed as it is executed. The option must be given before
> +@var{filename}, and will be interpreted as part of the filename anywhere else.
Please try to rewrite this without passive tense. Active tense tends
to make the text more concise and clear.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2006-07-08 12:02 ` Eli Zaretskii
@ 2006-07-20 16:46 ` Andrew STUBBS
2006-07-20 19:24 ` Eli Zaretskii
2006-07-20 19:38 ` Daniel Jacobowitz
0 siblings, 2 replies; 13+ messages in thread
From: Andrew STUBBS @ 2006-07-20 16:46 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 300 bytes --]
Here is an updated version of my patch. I think I have addressed all
your points. I have also implemented Daniel's suggestion that it should
use '+' before each command to indicate the nesting depth.
Sorry this has taken a while. I have been busy with other things.
:ADDPATCH CLI:
Andrew Stubbs
[-- Attachment #2: command-trace.patch --]
[-- Type: text/plain, Size: 17100 bytes --]
2006-07-20 Andrew Stubbs <andrew.stubbs@st.com>
* cli/cli-cmds.c (source_verbose, trace_commands): New variables.
(source_script): New function.
(source_verbose_cleanup): New function.
(source_command): Move old contents to source_script.
Make function static. Parse -v option and call source_script.
(init_cli_cmds): Update source command help.
Add 'set trace-commands' command.
* cli/cli-script.c (command_next_depth): New static variable.
(suppress_next_print_command_trace): New static variable.
(reset_command_nest_depth): New function.
(print_command_trace): New function.
(execute_control_command): Split the continue_control and break_control
cases, add calls to print_command_trace and count the nest depth.
(while_command): Set suppress_next_print_command_trace.
(if_command): Likewise.
* top.c (execute_command): Call print_command_trace.
* cli/cli-cmds.h (source_verbose, trace_commands): New extern variables.
(source_command): Change to source_script.
* main.c (captued_main): Use source_script instead of source_command.
* top.h (source_command): Change to source_script.
* event-top.c (display_gdb_prompt): Call reset_command_nest_depth.
* cli/cli-script.h (print_command_trace): Export.
(reset_command_nest_depth): Likewise.
docs/
* gdb.texinfo (Optional warnings and messages): Add
'set/show trace-commands'.
(Command files): Add '-v' to source command.
testsuite/
*gdb.base/help.exp: Update 'help source' message.
Index: src/gdb/cli/cli-cmds.c
===================================================================
--- src.orig/gdb/cli/cli-cmds.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/cli/cli-cmds.c 2006-07-20 15:52:22.000000000 +0100
@@ -173,6 +173,11 @@ struct cmd_list_element *showdebuglist;
struct cmd_list_element *setchecklist;
struct cmd_list_element *showchecklist;
+
+/* Command tracing state. */
+
+int source_verbose = 0;
+int trace_commands = 0;
\f
/* Utility used everywhere when at least one argument is needed and
none is supplied. */
@@ -424,15 +429,14 @@ cd_command (char *dir, int from_tty)
}
\f
void
-source_command (char *args, int from_tty)
+source_script (char *file, int from_tty)
{
FILE *stream;
struct cleanup *old_cleanups;
- char *file = args;
char *full_pathname = NULL;
int fd;
- if (file == NULL)
+ if (file == NULL || strlen (file) == 0)
{
error (_("source command requires pathname of file to source."));
}
@@ -465,6 +469,51 @@ source_command (char *args, int from_tty
do_cleanups (old_cleanups);
}
+/* Return the source_verbose global variable to its previous state
+ on exit from the source command, by whatever means. */
+static void
+source_verbose_cleanup (void *old_value)
+{
+ source_verbose = *(int *)old_value;
+ xfree (old_value);
+}
+
+static void
+source_command (char *args, int from_tty)
+{
+ struct cleanup *old_cleanups;
+ char *file = args;
+ int *old_source_verbose = xmalloc (sizeof(int));
+
+ *old_source_verbose = source_verbose;
+ old_cleanups = make_cleanup (source_verbose_cleanup, old_source_verbose);
+
+ /* -v causes the source command to run in verbose mode.
+ We still have to be able to handle filenames with spaces in a
+ backward compatible way, so buildargv is not appropriate. */
+
+ if (args)
+ {
+ /* Make sure leading white space does not break the comparisons. */
+ while (isspace(args[0]))
+ args++;
+
+ /* Is -v the first thing in the string? */
+ if (args[0] == '-' && args[1] == 'v' && isspace (args[2]))
+ {
+ source_verbose = 1;
+
+ /* Trim -v and whitespace from the filename. */
+ file = &args[3];
+ while (isspace (file[0]))
+ file++;
+ }
+ }
+
+ return source_script (file, from_tty);
+}
+
+
static void
echo_command (char *text, int from_tty)
{
@@ -1182,6 +1231,8 @@ Commands defined in this way may have up
source_help_text = xstrprintf (_("\
Read commands from a file named FILE.\n\
+Optional -v switch (before the filename) causes each command in\n\
+FILE to be echo as it is executed.\n\
Note that the file \"%s\" is read automatically in this way\n\
when gdb is started."), gdbinit);
c = add_cmd ("source", class_support, source_command,
@@ -1364,4 +1415,12 @@ Show the max call depth for user-defined
NULL,
show_max_user_call_depth,
&setlist, &showlist);
+
+ add_setshow_boolean_cmd ("trace-commands", no_class, &trace_commands, _("\
+Set tracing of GDB CLI commands."), _("\
+Show state of GDB CLI command tracing."), _("\
+When 'on', each command is displayed as it is executed."),
+ NULL,
+ NULL,
+ &setlist, &showlist);
}
Index: src/gdb/cli/cli-script.c
===================================================================
--- src.orig/gdb/cli/cli-script.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/cli/cli-script.c 2006-07-20 15:52:22.000000000 +0100
@@ -46,9 +46,15 @@ static struct cleanup * setup_user_args
static void validate_comname (char *);
-/* Level of control structure. */
+/* Level of control structure when reading. */
static int control_level;
+/* Level of control structure when executing. */
+static int command_nest_depth = 1;
+
+/* This is to prevent certain commands being printed twice. */
+static int suppress_next_print_command_trace = 0;
+
/* Structure for arguments to user defined functions. */
#define MAXUSERARGS 10
struct user_args
@@ -293,6 +299,46 @@ execute_user_command (struct cmd_list_el
do_cleanups (old_chain);
}
+/* This function is called every time GDB prints a prompt.
+ It ensures that errors and the like to not confuse the command tracing. */
+
+void
+reset_command_nest_depth (void)
+{
+ command_nest_depth = 1;
+
+ /* Just in case. */
+ suppress_next_print_command_trace = 0;
+}
+
+/* Print the command, prefixed with '+' to represent the call depth.
+ This is slightly complicated because this function may be called
+ from execute_command and execute_control_command. Unfortunately
+ execute_command also prints the top level control commands.
+ In these cases execute_command will call execute_control_command
+ via while_command or if_command. Inner levels of 'if' and 'while'
+ are dealt with directly. Therefore we can use these functions
+ to determine whether the command has been printed already or not. */
+void
+print_command_trace (const char *cmd)
+{
+ int i;
+
+ if (suppress_next_print_command_trace)
+ {
+ suppress_next_print_command_trace = 0;
+ return;
+ }
+
+ if (!source_verbose && !trace_commands)
+ return;
+
+ for (i=0; i < command_nest_depth; i++)
+ printf_filtered ("+");
+
+ printf_filtered ("%s\n", cmd);
+}
+
enum command_control_type
execute_control_command (struct command_line *cmd)
{
@@ -322,7 +368,16 @@ execute_control_command (struct command_
break;
case continue_control:
+ print_command_trace ("loop_continue");
+
+ /* Return for "continue", and "break" so we can either
+ continue the loop at the top, or break out. */
+ ret = cmd->control_type;
+ break;
+
case break_control:
+ print_command_trace ("loop_break");
+
/* Return for "continue", and "break" so we can either
continue the loop at the top, or break out. */
ret = cmd->control_type;
@@ -330,6 +385,10 @@ execute_control_command (struct command_
case while_control:
{
+ char *buffer = alloca (strlen (cmd->line) + 7);
+ sprintf (buffer, "while %s", cmd->line);
+ print_command_trace (buffer);
+
/* Parse the loop control expression for the while statement. */
new_line = insert_args (cmd->line);
if (!new_line)
@@ -362,7 +421,9 @@ execute_control_command (struct command_
current = *cmd->body_list;
while (current)
{
+ command_nest_depth++;
ret = execute_control_command (current);
+ command_nest_depth--;
/* If we got an error, or a "break" command, then stop
looping. */
@@ -391,6 +452,10 @@ execute_control_command (struct command_
case if_control:
{
+ char *buffer = alloca (strlen (cmd->line) + 4);
+ sprintf (buffer, "if %s", cmd->line);
+ print_command_trace (buffer);
+
new_line = insert_args (cmd->line);
if (!new_line)
break;
@@ -417,7 +482,9 @@ execute_control_command (struct command_
/* Execute commands in the given arm. */
while (current)
{
+ command_nest_depth++;
ret = execute_control_command (current);
+ command_nest_depth--;
/* If we got an error, get out. */
if (ret != simple_control)
@@ -454,6 +521,7 @@ while_command (char *arg, int from_tty)
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&command);
}
@@ -472,6 +540,7 @@ if_command (char *arg, int from_tty)
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&command);
}
Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/top.c 2006-07-20 15:52:30.000000000 +0100
@@ -400,6 +400,9 @@ execute_command (char *p, int from_tty)
char *arg;
line = p;
+ /* If trace-commands is set then this will print this command. */
+ print_command_trace (p);
+
c = lookup_cmd (&p, cmdlist, "", 0, 1);
/* If the target is running, we allow only a limited set of
Index: src/gdb/testsuite/gdb.base/help.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/help.exp 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/testsuite/gdb.base/help.exp 2006-07-20 17:37:17.000000000 +0100
@@ -533,7 +533,7 @@ gdb_test "help stepi" "Step one instruct
gdb_test "help signal" "Continue program giving it signal.*" "help signal"
# test help source
# vxgdb reads .vxgdbinit
-gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\." "help source"
+gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Optional -v switch \\(before the filename\\) causes each command in\[\r\n\]+FILE to be echo as it is executed\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\." "help source"
# test help stack
gdb_test "help stack" "Examining the stack\..*\[\r\n\]+When the program being debugged stops, gdb selects the innermost frame\.\[\r\n\]+The commands below can be used to select other frames by number or address\.\[\r\n\]+List of commands:\[\r\n\]+backtrace -- Print backtrace of all stack frames\[\r\n\]+bt -- Print backtrace of all stack frames\[\r\n\]+down -- Select and print stack frame called by this one\[\r\n\]+frame -- Select and print a stack frame\[\r\n\]+return -- Make selected stack frame return to its caller\[\r\n\]+select-frame -- Select a stack frame without printing anything\[\r\n\]+up -- Select and print stack frame that called this one\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help stack"
# test help status
Index: src/gdb/cli/cli-cmds.h
===================================================================
--- src.orig/gdb/cli/cli-cmds.h 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/cli/cli-cmds.h 2006-07-20 15:52:22.000000000 +0100
@@ -115,11 +115,16 @@ extern void cd_command (char *, int);
extern void quit_command (char *, int);
-extern void source_command (char *, int);
+extern void source_script (char *, int);
/* Used everywhere whenever at least one parameter is required and
none is specified. */
extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
+/* Command tracing state. */
+
+extern int source_verbose;
+extern int trace_commands;
+
#endif /* !defined (CLI_CMDS_H) */
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/doc/gdb.texinfo 2006-07-20 15:52:22.000000000 +0100
@@ -15999,6 +15999,22 @@ Displays state of confirmation requests.
@end table
+If you need to debug user-defined commands or sourced files you may find it
+useful to enable command tracing. In this mode each command will be printed
+as it is executed, prefixed with one or more @samp{+} symbols, the quantity
+denoting the call depth of each command.
+
+@table @code
+@kindex set trace-commands
+@cindex command scripts, debugging
+@item set trace-commands on
+Enable command tracing.
+@item set trace-commands off
+Disable command tracing.
+@item show trace-commands
+Display the current state of command tracing.
+@end table
+
@node Debugging Output
@section Optional messages about internal happenings
@cindex optional debugging messages
@@ -16347,7 +16363,7 @@ command:
@table @code
@kindex source
@cindex execute commands from a file
-@item source @var{filename}
+@item source [@code{-v}] @var{filename}
Execute the command file @var{filename}.
@end table
@@ -16360,6 +16376,10 @@ execution of the command file and contro
@value{GDBN} searches for @var{filename} in the current directory and then
on the search path (specified with the @samp{directory} command).
+If @code{-v}, for verbose mode, is given then @value{GDBN} displays
+each command as it is executed. The option must be given before
+@var{filename}, and is interpreted as part of the filename anywhere else.
+
Commands that would ask for confirmation if used interactively proceed
without asking when used in a command file. Many @value{GDBN} commands that
normally print messages to say what they are doing omit the messages
Index: src/gdb/main.c
===================================================================
--- src.orig/gdb/main.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/main.c 2006-07-20 15:52:22.000000000 +0100
@@ -643,7 +643,7 @@ extern int gdbtk_test (char *);
if (!inhibit_gdbinit)
{
- catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);
+ catch_command_errors (source_script, homeinit, 0, RETURN_MASK_ALL);
}
/* Do stats; no need to do them elsewhere since we'll only
@@ -730,7 +730,7 @@ extern int gdbtk_test (char *);
|| memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
if (!inhibit_gdbinit)
{
- catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL);
+ catch_command_errors (source_script, gdbinit, 0, RETURN_MASK_ALL);
}
for (i = 0; i < ncmd; i++)
@@ -748,12 +748,12 @@ extern int gdbtk_test (char *);
read_command_file (stdin);
else
#endif
- source_command (cmdarg[i], !batch);
+ source_script (cmdarg[i], !batch);
do_cleanups (ALL_CLEANUPS);
}
#endif
if (cmdarg[i].type == CMDARG_FILE)
- catch_command_errors (source_command, cmdarg[i].string,
+ catch_command_errors (source_script, cmdarg[i].string,
!batch, RETURN_MASK_ALL);
else /* cmdarg[i].type == CMDARG_COMMAND */
catch_command_errors (execute_command, cmdarg[i].string,
Index: src/gdb/top.h
===================================================================
--- src.orig/gdb/top.h 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/top.h 2006-07-20 15:52:22.000000000 +0100
@@ -36,7 +36,7 @@ extern char gdbinit[];
extern void print_gdb_version (struct ui_file *);
-extern void source_command (char *, int);
+extern void source_script (char *, int);
extern void cd_command (char *, int);
extern void read_command_file (FILE *);
extern void init_history (void);
Index: src/gdb/event-top.c
===================================================================
--- src.orig/gdb/event-top.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/event-top.c 2006-07-20 15:52:22.000000000 +0100
@@ -32,6 +32,7 @@
#include "interps.h"
#include <signal.h>
#include "exceptions.h"
+#include "cli/cli-script.h" /* for reset_command_nest_depth */
/* For dont_repeat() */
#include "gdbcmd.h"
@@ -260,6 +261,9 @@ display_gdb_prompt (char *new_prompt)
int prompt_length = 0;
char *gdb_prompt = get_prompt ();
+ /* Reset the nesting depth used when trace-commands is set. */
+ reset_command_nest_depth ();
+
/* Each interpreter has its own rules on displaying the command
prompt. */
if (!current_interp_display_prompt_p ())
Index: src/gdb/cli/cli-script.h
===================================================================
--- src.orig/gdb/cli/cli-script.h 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/cli/cli-script.h 2006-07-20 15:52:22.000000000 +0100
@@ -53,4 +53,12 @@ struct cleanup *make_cleanup_free_comman
extern void execute_user_command (struct cmd_list_element *c, char *args);
+/* Exported to top.c */
+
+extern void print_command_trace (const char *cmd);
+
+/* Exported to event-top.c */
+
+extern void reset_command_nest_depth (void);
+
#endif /* !defined (CLI_SCRIPT_H) */
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2006-07-20 16:46 ` Andrew STUBBS
@ 2006-07-20 19:24 ` Eli Zaretskii
2006-07-21 14:48 ` Andrew STUBBS
2006-07-20 19:38 ` Daniel Jacobowitz
1 sibling, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2006-07-20 19:24 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: gdb-patches
> Date: Thu, 20 Jul 2006 17:46:21 +0100
> From: Andrew STUBBS <andrew.stubbs@st.com>
> Cc: gdb-patches@sources.redhat.com
>
> Here is an updated version of my patch. I think I have addressed all
> your points.
Thanks.
> - if (file == NULL)
> + if (file == NULL || strlen (file) == 0)
^^^^^^^^^^^^^^^^^^
Nitpicking: isn't it better to use *file == 0 instead?
> error (_("source command requires pathname of file to source."));
Another nit: the GNU project does not like to use ``pathname''; please
use ``file name'' (yes, two words) instead.
> +Optional -v switch (before the filename) causes each command in\n\
> +FILE to be echo as it is executed.\n\
^^^^^^^^^^
You meant "to be echoed", right?
> Note that the file \"%s\" is read automatically in this way\n\
> when gdb is started."), gdbinit);
I think "gdb" should be up-cased.
> +If you need to debug user-defined commands or sourced files you may find it
> +useful to enable command tracing.
This paragraph could benefit from two small changes:
. enclose "command tracing" in the above sentence in @dfn{}, to make
it stand out--this is a new term you are introducing here
. add "@cindex command tracing" before the paragraph
Otherwise, the patch is okay with me. Thanks.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2006-07-20 16:46 ` Andrew STUBBS
2006-07-20 19:24 ` Eli Zaretskii
@ 2006-07-20 19:38 ` Daniel Jacobowitz
1 sibling, 0 replies; 13+ messages in thread
From: Daniel Jacobowitz @ 2006-07-20 19:38 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: Eli Zaretskii, gdb-patches
On Thu, Jul 20, 2006 at 05:46:21PM +0100, Andrew STUBBS wrote:
> Here is an updated version of my patch. I think I have addressed all
> your points. I have also implemented Daniel's suggestion that it should
> use '+' before each command to indicate the nesting depth.
Thanks! Aside from Eli's comments, this looks great.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2006-07-20 19:24 ` Eli Zaretskii
@ 2006-07-21 14:48 ` Andrew STUBBS
2006-07-21 14:49 ` Daniel Jacobowitz
0 siblings, 1 reply; 13+ messages in thread
From: Andrew STUBBS @ 2006-07-21 14:48 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1497 bytes --]
Eli Zaretskii wrote:
>> - if (file == NULL)
>> + if (file == NULL || strlen (file) == 0)
> ^^^^^^^^^^^^^^^^^^
> Nitpicking: isn't it better to use *file == 0 instead?
Ok.
>> error (_("source command requires pathname of file to source."));
>
> Another nit: the GNU project does not like to use ``pathname''; please
> use ``file name'' (yes, two words) instead.
This is the original text. I have taken the opportunity to change it.
>> +Optional -v switch (before the filename) causes each command in\n\
>> +FILE to be echo as it is executed.\n\
> ^^^^^^^^^^
> You meant "to be echoed", right?
Quite so.
>> Note that the file \"%s\" is read automatically in this way\n\
>> when gdb is started."), gdbinit);
>
> I think "gdb" should be up-cased.
Again, this is the original text, but I have changed it as suggested.
>> +If you need to debug user-defined commands or sourced files you may find it
>> +useful to enable command tracing.
>
> This paragraph could benefit from two small changes:
>
> . enclose "command tracing" in the above sentence in @dfn{}, to make
> it stand out--this is a new term you are introducing here
> . add "@cindex command tracing" before the paragraph
Fixed.
> Otherwise, the patch is okay with me. Thanks.
Thanks, I have committed the attached.
I suppose I ought to write a test case for this. Is there any existing
test file where this sort of thing belongs, or should I just create a
new file?
Andrew
[-- Attachment #2: command-trace.patch --]
[-- Type: text/plain, Size: 18184 bytes --]
2006-07-21 Andrew Stubbs <andrew.stubbs@st.com>
* cli/cli-cmds.c (source_verbose, trace_commands): New variables.
(source_script): New function.
(source_verbose_cleanup): New function.
(source_command): Move old contents to source_script.
Make function static. Parse -v option and call source_script.
(init_cli_cmds): Update source command help.
Add 'set trace-commands' command.
* cli/cli-script.c (command_next_depth): New static variable.
(suppress_next_print_command_trace): New static variable.
(reset_command_nest_depth): New function.
(print_command_trace): New function.
(execute_control_command): Split the continue_control and break_control
cases, add calls to print_command_trace and count the nest depth.
(while_command): Set suppress_next_print_command_trace.
(if_command): Likewise.
* top.c (execute_command): Call print_command_trace.
* cli/cli-cmds.h (source_verbose, trace_commands): New extern variables.
(source_command): Change to source_script.
* main.c (captued_main): Use source_script instead of source_command.
* top.h (source_command): Change to source_script.
* event-top.c (display_gdb_prompt): Call reset_command_nest_depth.
* cli/cli-script.h (print_command_trace): Export.
(reset_command_nest_depth): Likewise.
docs/
* gdb.texinfo (Optional warnings and messages): Add
'set/show trace-commands'.
(Command files): Add '-v' to source command.
testsuite/
* gdb.base/default.exp: Update source command error message.
* gdb.base/help.exp: Update 'help source' message.
Index: src/gdb/cli/cli-cmds.c
===================================================================
--- src.orig/gdb/cli/cli-cmds.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/cli/cli-cmds.c 2006-07-21 10:39:22.000000000 +0100
@@ -173,6 +173,11 @@ struct cmd_list_element *showdebuglist;
struct cmd_list_element *setchecklist;
struct cmd_list_element *showchecklist;
+
+/* Command tracing state. */
+
+int source_verbose = 0;
+int trace_commands = 0;
\f
/* Utility used everywhere when at least one argument is needed and
none is supplied. */
@@ -424,17 +429,16 @@ cd_command (char *dir, int from_tty)
}
\f
void
-source_command (char *args, int from_tty)
+source_script (char *file, int from_tty)
{
FILE *stream;
struct cleanup *old_cleanups;
- char *file = args;
char *full_pathname = NULL;
int fd;
- if (file == NULL)
+ if (file == NULL || *file == 0)
{
- error (_("source command requires pathname of file to source."));
+ error (_("source command requires file name of file to source."));
}
file = tilde_expand (file);
@@ -465,6 +469,51 @@ source_command (char *args, int from_tty
do_cleanups (old_cleanups);
}
+/* Return the source_verbose global variable to its previous state
+ on exit from the source command, by whatever means. */
+static void
+source_verbose_cleanup (void *old_value)
+{
+ source_verbose = *(int *)old_value;
+ xfree (old_value);
+}
+
+static void
+source_command (char *args, int from_tty)
+{
+ struct cleanup *old_cleanups;
+ char *file = args;
+ int *old_source_verbose = xmalloc (sizeof(int));
+
+ *old_source_verbose = source_verbose;
+ old_cleanups = make_cleanup (source_verbose_cleanup, old_source_verbose);
+
+ /* -v causes the source command to run in verbose mode.
+ We still have to be able to handle filenames with spaces in a
+ backward compatible way, so buildargv is not appropriate. */
+
+ if (args)
+ {
+ /* Make sure leading white space does not break the comparisons. */
+ while (isspace(args[0]))
+ args++;
+
+ /* Is -v the first thing in the string? */
+ if (args[0] == '-' && args[1] == 'v' && isspace (args[2]))
+ {
+ source_verbose = 1;
+
+ /* Trim -v and whitespace from the filename. */
+ file = &args[3];
+ while (isspace (file[0]))
+ file++;
+ }
+ }
+
+ return source_script (file, from_tty);
+}
+
+
static void
echo_command (char *text, int from_tty)
{
@@ -1182,8 +1231,10 @@ Commands defined in this way may have up
source_help_text = xstrprintf (_("\
Read commands from a file named FILE.\n\
+Optional -v switch (before the filename) causes each command in\n\
+FILE to be echoed as it is executed.\n\
Note that the file \"%s\" is read automatically in this way\n\
-when gdb is started."), gdbinit);
+when GDB is started."), gdbinit);
c = add_cmd ("source", class_support, source_command,
source_help_text, &cmdlist);
set_cmd_completer (c, filename_completer);
@@ -1364,4 +1415,12 @@ Show the max call depth for user-defined
NULL,
show_max_user_call_depth,
&setlist, &showlist);
+
+ add_setshow_boolean_cmd ("trace-commands", no_class, &trace_commands, _("\
+Set tracing of GDB CLI commands."), _("\
+Show state of GDB CLI command tracing."), _("\
+When 'on', each command is displayed as it is executed."),
+ NULL,
+ NULL,
+ &setlist, &showlist);
}
Index: src/gdb/cli/cli-script.c
===================================================================
--- src.orig/gdb/cli/cli-script.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/cli/cli-script.c 2006-07-20 15:52:22.000000000 +0100
@@ -46,9 +46,15 @@ static struct cleanup * setup_user_args
static void validate_comname (char *);
-/* Level of control structure. */
+/* Level of control structure when reading. */
static int control_level;
+/* Level of control structure when executing. */
+static int command_nest_depth = 1;
+
+/* This is to prevent certain commands being printed twice. */
+static int suppress_next_print_command_trace = 0;
+
/* Structure for arguments to user defined functions. */
#define MAXUSERARGS 10
struct user_args
@@ -293,6 +299,46 @@ execute_user_command (struct cmd_list_el
do_cleanups (old_chain);
}
+/* This function is called every time GDB prints a prompt.
+ It ensures that errors and the like to not confuse the command tracing. */
+
+void
+reset_command_nest_depth (void)
+{
+ command_nest_depth = 1;
+
+ /* Just in case. */
+ suppress_next_print_command_trace = 0;
+}
+
+/* Print the command, prefixed with '+' to represent the call depth.
+ This is slightly complicated because this function may be called
+ from execute_command and execute_control_command. Unfortunately
+ execute_command also prints the top level control commands.
+ In these cases execute_command will call execute_control_command
+ via while_command or if_command. Inner levels of 'if' and 'while'
+ are dealt with directly. Therefore we can use these functions
+ to determine whether the command has been printed already or not. */
+void
+print_command_trace (const char *cmd)
+{
+ int i;
+
+ if (suppress_next_print_command_trace)
+ {
+ suppress_next_print_command_trace = 0;
+ return;
+ }
+
+ if (!source_verbose && !trace_commands)
+ return;
+
+ for (i=0; i < command_nest_depth; i++)
+ printf_filtered ("+");
+
+ printf_filtered ("%s\n", cmd);
+}
+
enum command_control_type
execute_control_command (struct command_line *cmd)
{
@@ -322,7 +368,16 @@ execute_control_command (struct command_
break;
case continue_control:
+ print_command_trace ("loop_continue");
+
+ /* Return for "continue", and "break" so we can either
+ continue the loop at the top, or break out. */
+ ret = cmd->control_type;
+ break;
+
case break_control:
+ print_command_trace ("loop_break");
+
/* Return for "continue", and "break" so we can either
continue the loop at the top, or break out. */
ret = cmd->control_type;
@@ -330,6 +385,10 @@ execute_control_command (struct command_
case while_control:
{
+ char *buffer = alloca (strlen (cmd->line) + 7);
+ sprintf (buffer, "while %s", cmd->line);
+ print_command_trace (buffer);
+
/* Parse the loop control expression for the while statement. */
new_line = insert_args (cmd->line);
if (!new_line)
@@ -362,7 +421,9 @@ execute_control_command (struct command_
current = *cmd->body_list;
while (current)
{
+ command_nest_depth++;
ret = execute_control_command (current);
+ command_nest_depth--;
/* If we got an error, or a "break" command, then stop
looping. */
@@ -391,6 +452,10 @@ execute_control_command (struct command_
case if_control:
{
+ char *buffer = alloca (strlen (cmd->line) + 4);
+ sprintf (buffer, "if %s", cmd->line);
+ print_command_trace (buffer);
+
new_line = insert_args (cmd->line);
if (!new_line)
break;
@@ -417,7 +482,9 @@ execute_control_command (struct command_
/* Execute commands in the given arm. */
while (current)
{
+ command_nest_depth++;
ret = execute_control_command (current);
+ command_nest_depth--;
/* If we got an error, get out. */
if (ret != simple_control)
@@ -454,6 +521,7 @@ while_command (char *arg, int from_tty)
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&command);
}
@@ -472,6 +540,7 @@ if_command (char *arg, int from_tty)
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&command);
}
Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/top.c 2006-07-20 15:52:30.000000000 +0100
@@ -400,6 +400,9 @@ execute_command (char *p, int from_tty)
char *arg;
line = p;
+ /* If trace-commands is set then this will print this command. */
+ print_command_trace (p);
+
c = lookup_cmd (&p, cmdlist, "", 0, 1);
/* If the target is running, we allow only a limited set of
Index: src/gdb/testsuite/gdb.base/help.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/help.exp 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/testsuite/gdb.base/help.exp 2006-07-21 10:44:33.000000000 +0100
@@ -533,7 +533,7 @@ gdb_test "help stepi" "Step one instruct
gdb_test "help signal" "Continue program giving it signal.*" "help signal"
# test help source
# vxgdb reads .vxgdbinit
-gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\." "help source"
+gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Optional -v switch \\(before the filename\\) causes each command in\[\r\n\]+FILE to be echoed as it is executed\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when GDB is started\." "help source"
# test help stack
gdb_test "help stack" "Examining the stack\..*\[\r\n\]+When the program being debugged stops, gdb selects the innermost frame\.\[\r\n\]+The commands below can be used to select other frames by number or address\.\[\r\n\]+List of commands:\[\r\n\]+backtrace -- Print backtrace of all stack frames\[\r\n\]+bt -- Print backtrace of all stack frames\[\r\n\]+down -- Select and print stack frame called by this one\[\r\n\]+frame -- Select and print a stack frame\[\r\n\]+return -- Make selected stack frame return to its caller\[\r\n\]+select-frame -- Select a stack frame without printing anything\[\r\n\]+up -- Select and print stack frame that called this one\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help stack"
# test help status
Index: src/gdb/cli/cli-cmds.h
===================================================================
--- src.orig/gdb/cli/cli-cmds.h 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/cli/cli-cmds.h 2006-07-20 15:52:22.000000000 +0100
@@ -115,11 +115,16 @@ extern void cd_command (char *, int);
extern void quit_command (char *, int);
-extern void source_command (char *, int);
+extern void source_script (char *, int);
/* Used everywhere whenever at least one parameter is required and
none is specified. */
extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
+/* Command tracing state. */
+
+extern int source_verbose;
+extern int trace_commands;
+
#endif /* !defined (CLI_CMDS_H) */
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/doc/gdb.texinfo 2006-07-21 10:42:11.000000000 +0100
@@ -15999,6 +15999,23 @@ Displays state of confirmation requests.
@end table
+@cindex command tracing
+If you need to debug user-defined commands or sourced files you may find it
+useful to enable @dfn{command tracing}. In this mode each command will be
+printed as it is executed, prefixed with one or more @samp{+} symbols, the
+quantity denoting the call depth of each command.
+
+@table @code
+@kindex set trace-commands
+@cindex command scripts, debugging
+@item set trace-commands on
+Enable command tracing.
+@item set trace-commands off
+Disable command tracing.
+@item show trace-commands
+Display the current state of command tracing.
+@end table
+
@node Debugging Output
@section Optional messages about internal happenings
@cindex optional debugging messages
@@ -16347,7 +16364,7 @@ command:
@table @code
@kindex source
@cindex execute commands from a file
-@item source @var{filename}
+@item source [@code{-v}] @var{filename}
Execute the command file @var{filename}.
@end table
@@ -16360,6 +16377,10 @@ execution of the command file and contro
@value{GDBN} searches for @var{filename} in the current directory and then
on the search path (specified with the @samp{directory} command).
+If @code{-v}, for verbose mode, is given then @value{GDBN} displays
+each command as it is executed. The option must be given before
+@var{filename}, and is interpreted as part of the filename anywhere else.
+
Commands that would ask for confirmation if used interactively proceed
without asking when used in a command file. Many @value{GDBN} commands that
normally print messages to say what they are doing omit the messages
Index: src/gdb/main.c
===================================================================
--- src.orig/gdb/main.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/main.c 2006-07-20 15:52:22.000000000 +0100
@@ -643,7 +643,7 @@ extern int gdbtk_test (char *);
if (!inhibit_gdbinit)
{
- catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);
+ catch_command_errors (source_script, homeinit, 0, RETURN_MASK_ALL);
}
/* Do stats; no need to do them elsewhere since we'll only
@@ -730,7 +730,7 @@ extern int gdbtk_test (char *);
|| memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
if (!inhibit_gdbinit)
{
- catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL);
+ catch_command_errors (source_script, gdbinit, 0, RETURN_MASK_ALL);
}
for (i = 0; i < ncmd; i++)
@@ -748,12 +748,12 @@ extern int gdbtk_test (char *);
read_command_file (stdin);
else
#endif
- source_command (cmdarg[i], !batch);
+ source_script (cmdarg[i], !batch);
do_cleanups (ALL_CLEANUPS);
}
#endif
if (cmdarg[i].type == CMDARG_FILE)
- catch_command_errors (source_command, cmdarg[i].string,
+ catch_command_errors (source_script, cmdarg[i].string,
!batch, RETURN_MASK_ALL);
else /* cmdarg[i].type == CMDARG_COMMAND */
catch_command_errors (execute_command, cmdarg[i].string,
Index: src/gdb/top.h
===================================================================
--- src.orig/gdb/top.h 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/top.h 2006-07-20 15:52:22.000000000 +0100
@@ -36,7 +36,7 @@ extern char gdbinit[];
extern void print_gdb_version (struct ui_file *);
-extern void source_command (char *, int);
+extern void source_script (char *, int);
extern void cd_command (char *, int);
extern void read_command_file (FILE *);
extern void init_history (void);
Index: src/gdb/event-top.c
===================================================================
--- src.orig/gdb/event-top.c 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/event-top.c 2006-07-20 15:52:22.000000000 +0100
@@ -32,6 +32,7 @@
#include "interps.h"
#include <signal.h>
#include "exceptions.h"
+#include "cli/cli-script.h" /* for reset_command_nest_depth */
/* For dont_repeat() */
#include "gdbcmd.h"
@@ -260,6 +261,9 @@ display_gdb_prompt (char *new_prompt)
int prompt_length = 0;
char *gdb_prompt = get_prompt ();
+ /* Reset the nesting depth used when trace-commands is set. */
+ reset_command_nest_depth ();
+
/* Each interpreter has its own rules on displaying the command
prompt. */
if (!current_interp_display_prompt_p ())
Index: src/gdb/cli/cli-script.h
===================================================================
--- src.orig/gdb/cli/cli-script.h 2006-07-20 15:41:13.000000000 +0100
+++ src/gdb/cli/cli-script.h 2006-07-20 15:52:22.000000000 +0100
@@ -53,4 +53,12 @@ struct cleanup *make_cleanup_free_comman
extern void execute_user_command (struct cmd_list_element *c, char *args);
+/* Exported to top.c */
+
+extern void print_command_trace (const char *cmd);
+
+/* Exported to event-top.c */
+
+extern void reset_command_nest_depth (void);
+
#endif /* !defined (CLI_SCRIPT_H) */
Index: src/gdb/testsuite/gdb.base/default.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/default.exp 2006-02-23 18:24:34.000000000 +0000
+++ src/gdb/testsuite/gdb.base/default.exp 2006-07-21 10:46:31.000000000 +0100
@@ -682,7 +682,7 @@ gdb_test "stepi" "The program is not bei
#test signal
gdb_test "signal" "The program is not being run." "signal"
#test source
-gdb_test "source" "source command requires pathname of file to source..*|No such file or directory.*" "source"
+gdb_test "source" "source command requires file name of file to source..*|No such file or directory.*" "source"
#test step "s" abbreviation
gdb_test "s" "The program is not being run." "step \"s\" abbreviation #2"
#test step
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] command trace / source verbose mode
2006-07-21 14:48 ` Andrew STUBBS
@ 2006-07-21 14:49 ` Daniel Jacobowitz
0 siblings, 0 replies; 13+ messages in thread
From: Daniel Jacobowitz @ 2006-07-21 14:49 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: Eli Zaretskii, gdb-patches
On Fri, Jul 21, 2006 at 03:48:12PM +0100, Andrew STUBBS wrote:
> Thanks, I have committed the attached.
Great!
> I suppose I ought to write a test case for this. Is there any existing
> test file where this sort of thing belongs, or should I just create a
> new file?
If you want to do this, I would recommend a new file.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2006-07-21 14:49 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-16 18:01 [PATCH] command trace / source verbose mode Andrew STUBBS
2005-11-16 20:11 ` Eli Zaretskii
2005-11-17 16:21 ` Andrew STUBBS
2006-07-06 13:16 ` Daniel Jacobowitz
2006-07-06 17:23 ` Andrew STUBBS
2006-07-06 17:33 ` Daniel Jacobowitz
2006-07-07 16:18 ` Andrew STUBBS
2006-07-08 12:02 ` Eli Zaretskii
2006-07-20 16:46 ` Andrew STUBBS
2006-07-20 19:24 ` Eli Zaretskii
2006-07-21 14:48 ` Andrew STUBBS
2006-07-21 14:49 ` Daniel Jacobowitz
2006-07-20 19:38 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox