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.
This commit is contained in:
Andrew Stubbs 2006-07-21 14:46:56 +00:00
parent 3e4cf9243a
commit 16026cd75d
14 changed files with 221 additions and 15 deletions

View file

@ -1,3 +1,29 @@
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.
2006-07-20 Daniel Jacobowitz <dan@codesourcery.com> 2006-07-20 Daniel Jacobowitz <dan@codesourcery.com>
* eval.c (evaluate_struct_tuple): Skip static fields. * eval.c (evaluate_struct_tuple): Skip static fields.

View file

@ -173,6 +173,11 @@ struct cmd_list_element *showdebuglist;
struct cmd_list_element *setchecklist; struct cmd_list_element *setchecklist;
struct cmd_list_element *showchecklist; struct cmd_list_element *showchecklist;
/* Command tracing state. */
int source_verbose = 0;
int trace_commands = 0;
/* Utility used everywhere when at least one argument is needed and /* Utility used everywhere when at least one argument is needed and
none is supplied. */ none is supplied. */
@ -424,17 +429,16 @@ cd_command (char *dir, int from_tty)
} }
void void
source_command (char *args, int from_tty) source_script (char *file, int from_tty)
{ {
FILE *stream; FILE *stream;
struct cleanup *old_cleanups; struct cleanup *old_cleanups;
char *file = args;
char *full_pathname = NULL; char *full_pathname = NULL;
int fd; 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); file = tilde_expand (file);
@ -465,6 +469,51 @@ source_command (char *args, int from_tty)
do_cleanups (old_cleanups); 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 static void
echo_command (char *text, int from_tty) echo_command (char *text, int from_tty)
{ {
@ -1182,8 +1231,10 @@ Commands defined in this way may have up to ten arguments."));
source_help_text = xstrprintf (_("\ source_help_text = xstrprintf (_("\
Read commands from a file named FILE.\n\ 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\ 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, c = add_cmd ("source", class_support, source_command,
source_help_text, &cmdlist); source_help_text, &cmdlist);
set_cmd_completer (c, filename_completer); set_cmd_completer (c, filename_completer);
@ -1364,4 +1415,12 @@ Show the max call depth for user-defined commands."), NULL,
NULL, NULL,
show_max_user_call_depth, show_max_user_call_depth,
&setlist, &showlist); &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);
} }

View file

@ -115,11 +115,16 @@ extern void cd_command (char *, int);
extern void quit_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 /* Used everywhere whenever at least one parameter is required and
none is specified. */ none is specified. */
extern NORETURN void error_no_arg (char *) ATTR_NORETURN; 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) */ #endif /* !defined (CLI_CMDS_H) */

View file

@ -46,9 +46,15 @@ static struct cleanup * setup_user_args (char *p);
static void validate_comname (char *); static void validate_comname (char *);
/* Level of control structure. */ /* Level of control structure when reading. */
static int control_level; 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. */ /* Structure for arguments to user defined functions. */
#define MAXUSERARGS 10 #define MAXUSERARGS 10
struct user_args struct user_args
@ -293,6 +299,46 @@ execute_user_command (struct cmd_list_element *c, char *args)
do_cleanups (old_chain); 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 enum command_control_type
execute_control_command (struct command_line *cmd) execute_control_command (struct command_line *cmd)
{ {
@ -322,7 +368,16 @@ execute_control_command (struct command_line *cmd)
break; break;
case continue_control: 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: case break_control:
print_command_trace ("loop_break");
/* Return for "continue", and "break" so we can either /* Return for "continue", and "break" so we can either
continue the loop at the top, or break out. */ continue the loop at the top, or break out. */
ret = cmd->control_type; ret = cmd->control_type;
@ -330,6 +385,10 @@ execute_control_command (struct command_line *cmd)
case while_control: 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. */ /* Parse the loop control expression for the while statement. */
new_line = insert_args (cmd->line); new_line = insert_args (cmd->line);
if (!new_line) if (!new_line)
@ -362,7 +421,9 @@ execute_control_command (struct command_line *cmd)
current = *cmd->body_list; current = *cmd->body_list;
while (current) while (current)
{ {
command_nest_depth++;
ret = execute_control_command (current); ret = execute_control_command (current);
command_nest_depth--;
/* If we got an error, or a "break" command, then stop /* If we got an error, or a "break" command, then stop
looping. */ looping. */
@ -391,6 +452,10 @@ execute_control_command (struct command_line *cmd)
case if_control: 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); new_line = insert_args (cmd->line);
if (!new_line) if (!new_line)
break; break;
@ -417,7 +482,9 @@ execute_control_command (struct command_line *cmd)
/* Execute commands in the given arm. */ /* Execute commands in the given arm. */
while (current) while (current)
{ {
command_nest_depth++;
ret = execute_control_command (current); ret = execute_control_command (current);
command_nest_depth--;
/* If we got an error, get out. */ /* If we got an error, get out. */
if (ret != simple_control) if (ret != simple_control)
@ -454,6 +521,7 @@ while_command (char *arg, int from_tty)
if (command == NULL) if (command == NULL)
return; return;
suppress_next_print_command_trace = 1;
execute_control_command (command); execute_control_command (command);
free_command_lines (&command); free_command_lines (&command);
} }
@ -472,6 +540,7 @@ if_command (char *arg, int from_tty)
if (command == NULL) if (command == NULL)
return; return;
suppress_next_print_command_trace = 1;
execute_control_command (command); execute_control_command (command);
free_command_lines (&command); free_command_lines (&command);
} }

View file

@ -53,4 +53,12 @@ struct cleanup *make_cleanup_free_command_lines (struct command_line **arg);
extern void execute_user_command (struct cmd_list_element *c, char *args); 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) */ #endif /* !defined (CLI_SCRIPT_H) */

View file

@ -1,3 +1,9 @@
2006-07-21 Andrew Stubbs <andrew.stubbs@st.com>
* gdb.texinfo (Optional warnings and messages): Add
'set/show trace-commands'.
(Command files): Add '-v' to source command.
2006-07-12 Daniel Jacobowitz <dan@codesourcery.com> 2006-07-12 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.texinfo (OS Information): Update qPart reference to * gdb.texinfo (OS Information): Update qPart reference to

View file

@ -15999,6 +15999,23 @@ Displays state of confirmation requests.
@end table @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 @node Debugging Output
@section Optional messages about internal happenings @section Optional messages about internal happenings
@cindex optional debugging messages @cindex optional debugging messages
@ -16347,7 +16364,7 @@ command:
@table @code @table @code
@kindex source @kindex source
@cindex execute commands from a file @cindex execute commands from a file
@item source @var{filename} @item source [@code{-v}] @var{filename}
Execute the command file @var{filename}. Execute the command file @var{filename}.
@end table @end table
@ -16360,6 +16377,10 @@ execution of the command file and control is returned to the console.
@value{GDBN} searches for @var{filename} in the current directory and then @value{GDBN} searches for @var{filename} in the current directory and then
on the search path (specified with the @samp{directory} command). 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 Commands that would ask for confirmation if used interactively proceed
without asking when used in a command file. Many @value{GDBN} commands that 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 normally print messages to say what they are doing omit the messages

View file

@ -32,6 +32,7 @@
#include "interps.h" #include "interps.h"
#include <signal.h> #include <signal.h>
#include "exceptions.h" #include "exceptions.h"
#include "cli/cli-script.h" /* for reset_command_nest_depth */
/* For dont_repeat() */ /* For dont_repeat() */
#include "gdbcmd.h" #include "gdbcmd.h"
@ -260,6 +261,9 @@ display_gdb_prompt (char *new_prompt)
int prompt_length = 0; int prompt_length = 0;
char *gdb_prompt = get_prompt (); 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 /* Each interpreter has its own rules on displaying the command
prompt. */ prompt. */
if (!current_interp_display_prompt_p ()) if (!current_interp_display_prompt_p ())

View file

@ -643,7 +643,7 @@ extern int gdbtk_test (char *);
if (!inhibit_gdbinit) 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 /* 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))) || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
if (!inhibit_gdbinit) 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++) for (i = 0; i < ncmd; i++)
@ -748,12 +748,12 @@ extern int gdbtk_test (char *);
read_command_file (stdin); read_command_file (stdin);
else else
#endif #endif
source_command (cmdarg[i], !batch); source_script (cmdarg[i], !batch);
do_cleanups (ALL_CLEANUPS); do_cleanups (ALL_CLEANUPS);
} }
#endif #endif
if (cmdarg[i].type == CMDARG_FILE) 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); !batch, RETURN_MASK_ALL);
else /* cmdarg[i].type == CMDARG_COMMAND */ else /* cmdarg[i].type == CMDARG_COMMAND */
catch_command_errors (execute_command, cmdarg[i].string, catch_command_errors (execute_command, cmdarg[i].string,

View file

@ -1,3 +1,8 @@
2006-07-21 Andrew Stubbs <andrew.stubbs@st.com>
* gdb.base/default.exp: Update source command error message.
* gdb.base/help.exp: Update 'help source' message.
2006-07-20 Daniel Jacobowitz <dan@codesourcery.com> 2006-07-20 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.cp/bs15503.exp: Update comment for no longer crashing * gdb.cp/bs15503.exp: Update comment for no longer crashing

View file

@ -682,7 +682,7 @@ gdb_test "stepi" "The program is not being run." "stepi"
#test signal #test signal
gdb_test "signal" "The program is not being run." "signal" gdb_test "signal" "The program is not being run." "signal"
#test source #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 #test step "s" abbreviation
gdb_test "s" "The program is not being run." "step \"s\" abbreviation #2" gdb_test "s" "The program is not being run." "step \"s\" abbreviation #2"
#test step #test step

View file

@ -533,7 +533,7 @@ gdb_test "help stepi" "Step one instruction exactly\.\[\r\n\]+Argument N means d
gdb_test "help signal" "Continue program giving it signal.*" "help signal" gdb_test "help signal" "Continue program giving it signal.*" "help signal"
# test help source # test help source
# vxgdb reads .vxgdbinit # 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 # 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" 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 # test help status

View file

@ -400,6 +400,9 @@ execute_command (char *p, int from_tty)
char *arg; char *arg;
line = p; line = p;
/* If trace-commands is set then this will print this command. */
print_command_trace (p);
c = lookup_cmd (&p, cmdlist, "", 0, 1); c = lookup_cmd (&p, cmdlist, "", 0, 1);
/* If the target is running, we allow only a limited set of /* If the target is running, we allow only a limited set of

View file

@ -36,7 +36,7 @@ extern char gdbinit[];
extern void print_gdb_version (struct ui_file *); 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 cd_command (char *, int);
extern void read_command_file (FILE *); extern void read_command_file (FILE *);
extern void init_history (void); extern void init_history (void);