This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] command trace / source verbose mode


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
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;
 
 /* 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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]