mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 12:39:59 +00:00
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:
parent
3e4cf9243a
commit
16026cd75d
@ -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>
|
||||
|
||||
* eval.c (evaluate_struct_tuple): Skip static fields.
|
||||
|
@ -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;
|
||||
|
||||
/* 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)
|
||||
}
|
||||
|
||||
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 to ten arguments."));
|
||||
|
||||
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 commands."), NULL,
|
||||
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);
|
||||
}
|
||||
|
@ -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) */
|
||||
|
@ -46,9 +46,15 @@ static struct cleanup * setup_user_args (char *p);
|
||||
|
||||
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_element *c, char *args)
|
||||
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_line *cmd)
|
||||
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_line *cmd)
|
||||
|
||||
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_line *cmd)
|
||||
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_line *cmd)
|
||||
|
||||
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_line *cmd)
|
||||
/* 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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
/* 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) */
|
||||
|
@ -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>
|
||||
|
||||
* gdb.texinfo (OS Information): Update qPart reference to
|
||||
|
@ -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 control is returned to the console.
|
||||
@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
|
||||
|
@ -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 ())
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
||||
* gdb.cp/bs15503.exp: Update comment for no longer crashing
|
||||
|
@ -682,7 +682,7 @@ gdb_test "stepi" "The program is not being run." "stepi"
|
||||
#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
|
||||
|
@ -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"
|
||||
# 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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user