Implement -break-commands
* breakpoint.c (get_breakpoint, breakpoint_set_commands): New. (commands_command): Use breakpoint_set_commands. * breakpoint.h (get_breakpoint, breakpoint_set_commands): Declare. * mi/mi-cmds.h (mi_cmd_break_commands): New. * mi/mi-cmds.c: Register -break-commands. * mi/mi-cmd-break.c (mi_cmd_break_commands, mi_read_next_line) (mi_command_line_array, mi_command_line_array_cnt) (mi_command_line_array_ptr): New.
This commit is contained in:
parent
3c1179ff51
commit
48cb2d8581
11 changed files with 173 additions and 11 deletions
|
@ -1,3 +1,18 @@
|
|||
2009-08-03 Jim Ingham <jingham@apple.com>
|
||||
Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
Implement -break-commands
|
||||
|
||||
* breakpoint.c (get_breakpoint, breakpoint_set_commands): New.
|
||||
(commands_command): Use breakpoint_set_commands.
|
||||
* breakpoint.h (get_breakpoint, breakpoint_set_commands): Declare.
|
||||
|
||||
* mi/mi-cmds.h (mi_cmd_break_commands): New.
|
||||
* mi/mi-cmds.c: Register -break-commands.
|
||||
* mi/mi-cmd-break.c (mi_cmd_break_commands, mi_read_next_line)
|
||||
(mi_command_line_array, mi_command_line_array_cnt)
|
||||
(mi_command_line_array_ptr): New.
|
||||
|
||||
2009-08-03 Jim Ingham <jingham@apple.com>
|
||||
Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
|
|
|
@ -562,6 +562,20 @@ get_number_or_range (char **pp)
|
|||
return last_retval;
|
||||
}
|
||||
|
||||
/* Return the breakpoint with the specified number, or NULL
|
||||
if the number does not refer to an existing breakpoint. */
|
||||
|
||||
struct breakpoint *
|
||||
get_breakpoint (int num)
|
||||
{
|
||||
struct breakpoint *b;
|
||||
|
||||
ALL_BREAKPOINTS (b)
|
||||
if (b->number == num)
|
||||
return b;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* condition N EXP -- set break condition of breakpoint N to EXP. */
|
||||
|
@ -626,6 +640,17 @@ condition_command (char *arg, int from_tty)
|
|||
error (_("No breakpoint number %d."), bnum);
|
||||
}
|
||||
|
||||
/* Set the command list of B to COMMANDS. */
|
||||
|
||||
void
|
||||
breakpoint_set_commands (struct breakpoint *b, struct command_line *commands)
|
||||
{
|
||||
free_command_lines (&b->commands);
|
||||
b->commands = commands;
|
||||
breakpoints_changed ();
|
||||
observer_notify_breakpoint_modified (b->number);
|
||||
}
|
||||
|
||||
static void
|
||||
commands_command (char *arg, int from_tty)
|
||||
{
|
||||
|
@ -655,10 +680,7 @@ commands_command (char *arg, int from_tty)
|
|||
struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
|
||||
l = read_command_lines (tmpbuf, from_tty, 1);
|
||||
do_cleanups (cleanups);
|
||||
free_command_lines (&b->commands);
|
||||
b->commands = l;
|
||||
breakpoints_changed ();
|
||||
observer_notify_breakpoint_modified (b->number);
|
||||
breakpoint_set_commands (b, l);
|
||||
return;
|
||||
}
|
||||
error (_("No breakpoint number %d."), bnum);
|
||||
|
|
|
@ -840,6 +840,8 @@ extern int get_number (char **);
|
|||
|
||||
extern int get_number_or_range (char **);
|
||||
|
||||
extern struct breakpoint *get_breakpoint (int num);
|
||||
|
||||
/* The following are for displays, which aren't really breakpoints, but
|
||||
here is as good a place as any for them. */
|
||||
|
||||
|
@ -855,6 +857,9 @@ extern void disable_breakpoint (struct breakpoint *);
|
|||
|
||||
extern void enable_breakpoint (struct breakpoint *);
|
||||
|
||||
extern void breakpoint_set_commands (struct breakpoint *b,
|
||||
struct command_line *commands);
|
||||
|
||||
/* Clear the "inserted" flag in all breakpoints. */
|
||||
extern void mark_breakpoints_out (void);
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2009-08-03 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
* gdb.texinfo (GDB/MI Breakpoint Commands): Document
|
||||
-break-commands.
|
||||
|
||||
2009-07-31 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* gdb.texinfo (Cell Broadband Engine SPU architecture): Document the
|
||||
|
|
|
@ -21492,11 +21492,41 @@ line="5",times="0",ignore="3"@}]@}
|
|||
@ignore
|
||||
@subheading The @code{-break-catch} Command
|
||||
@findex -break-catch
|
||||
@end ignore
|
||||
|
||||
@subheading The @code{-break-commands} Command
|
||||
@findex -break-commands
|
||||
@end ignore
|
||||
|
||||
@subsubheading Synopsis
|
||||
|
||||
@smallexample
|
||||
-break-commands @var{number} [ @var{command1} ... @var{commandN} ]
|
||||
@end smallexample
|
||||
|
||||
Specifies the CLI commands that should be executed when breakpoint
|
||||
@var{number} is hit. The parameters @var{command1} to @var{commandN}
|
||||
are the commands. If no command is specified, any previously-set
|
||||
commands are cleared. @xref{Break Commands}. Typical use of this
|
||||
functionality is tracing a program, that is, printing of values of
|
||||
some variables whenever breakpoint is hit and then continuing.
|
||||
|
||||
@subsubheading @value{GDBN} Command
|
||||
|
||||
The corresponding @value{GDBN} command is @samp{commands}.
|
||||
|
||||
@subsubheading Example
|
||||
|
||||
@smallexample
|
||||
(gdb)
|
||||
-break-insert main
|
||||
^done,bkpt=@{number="1",type="breakpoint",disp="keep",
|
||||
enabled="y",addr="0x000100d0",func="main",file="hello.c",
|
||||
fullname="/home/foo/hello.c",line="5",times="0"@}
|
||||
(gdb)
|
||||
-break-commands 1 "print v" "continue"
|
||||
^done
|
||||
(gdb)
|
||||
@end smallexample
|
||||
|
||||
@subheading The @code{-break-condition} Command
|
||||
@findex -break-condition
|
||||
|
|
|
@ -252,3 +252,53 @@ mi_cmd_break_watch (char *command, char **argv, int argc)
|
|||
error (_("mi_cmd_break_watch: Unknown watchpoint type."));
|
||||
}
|
||||
}
|
||||
|
||||
/* The mi_read_next_line consults these variable to return successive
|
||||
command lines. While it would be clearer to use a closure pointer,
|
||||
it is not expected that any future code will use read_command_lines_1,
|
||||
therefore no point of overengineering. */
|
||||
|
||||
static char **mi_command_line_array;
|
||||
static int mi_command_line_array_cnt;
|
||||
static int mi_command_line_array_ptr;
|
||||
|
||||
static char *
|
||||
mi_read_next_line ()
|
||||
{
|
||||
if (mi_command_line_array_ptr == mi_command_line_array_cnt)
|
||||
return NULL;
|
||||
else
|
||||
return mi_command_line_array[mi_command_line_array_ptr++];
|
||||
}
|
||||
|
||||
void
|
||||
mi_cmd_break_commands (char *command, char **argv, int argc)
|
||||
{
|
||||
struct command_line *break_command;
|
||||
char *endptr;
|
||||
int bnum;
|
||||
struct breakpoint *b;
|
||||
|
||||
if (argc < 1)
|
||||
error ("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]", command);
|
||||
|
||||
bnum = strtol (argv[0], &endptr, 0);
|
||||
if (endptr == argv[0])
|
||||
error ("breakpoint number argument \"%s\" is not a number.",
|
||||
argv[0]);
|
||||
else if (*endptr != '\0')
|
||||
error ("junk at the end of breakpoint number argument \"%s\".",
|
||||
argv[0]);
|
||||
|
||||
b = get_breakpoint (bnum);
|
||||
if (b == NULL)
|
||||
error ("breakpoint %d not found.", bnum);
|
||||
|
||||
mi_command_line_array = argv;
|
||||
mi_command_line_array_ptr = 1;
|
||||
mi_command_line_array_cnt = argc;
|
||||
|
||||
break_command = read_command_lines_1 (mi_read_next_line, 0);
|
||||
breakpoint_set_commands (b, break_command);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ struct mi_cmd mi_cmds[] =
|
|||
{
|
||||
{ "break-after", { "ignore", 1 }, NULL },
|
||||
{ "break-condition", { "cond", 1 }, NULL },
|
||||
{ "break-commands", { NULL, 0 }, mi_cmd_break_commands },
|
||||
{ "break-delete", { "delete breakpoint", 1 }, NULL },
|
||||
{ "break-disable", { "disable breakpoint", 1 }, NULL },
|
||||
{ "break-enable", { "enable breakpoint", 1 }, NULL },
|
||||
|
|
|
@ -37,6 +37,7 @@ typedef void (mi_cmd_argv_ftype) (char *command, char **argv, int argc);
|
|||
|
||||
/* Function implementing each command */
|
||||
extern mi_cmd_argv_ftype mi_cmd_break_insert;
|
||||
extern mi_cmd_argv_ftype mi_cmd_break_commands;
|
||||
extern mi_cmd_argv_ftype mi_cmd_break_watch;
|
||||
extern mi_cmd_argv_ftype mi_cmd_disassemble;
|
||||
extern mi_cmd_argv_ftype mi_cmd_data_evaluate_expression;
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2009-08-03 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
* lib/mi-support.exp (mi_list_breakpoints): Make it work.
|
||||
* gdb.mi/mi-break.exp (test_breakpoint_commands): New.
|
||||
Call it.
|
||||
|
||||
2009-07-31 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
|
||||
|
||||
* configure.ac: Run gdb.cell tests when appropriate.
|
||||
|
|
|
@ -197,6 +197,30 @@ proc test_disabled_creation {} {
|
|||
"test disabled creation: cleanup"
|
||||
}
|
||||
|
||||
proc test_breakpoint_commands {} {
|
||||
global line_callee2_body
|
||||
global hex
|
||||
global fullname
|
||||
|
||||
mi_create_breakpoint "basics.c:callee2" 7 keep callee2 ".*basics.c" $line_callee2_body $hex \
|
||||
"breakpoint commands: insert breakpoint at basics.c:callee2"
|
||||
|
||||
mi_gdb_test "-break-commands 7 \"print 10\" \"continue\"" \
|
||||
"\\^done" \
|
||||
"breakpoint commands: set commands"
|
||||
|
||||
mi_gdb_test "-break-info 7" \
|
||||
"\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\}.*colhdr=\"Type\".*colhdr=\"Disp\".*colhdr=\"Enb\".*colhdr=\"Address\".*colhdr=\"What\".*\\\],body=\\\[bkpt=\{number=\"7\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",${fullname},line=\"$line_callee2_body\",times=\"0\",script=\{\"print 10\",\"continue\"\},original-location=\".*\"\}.*\\\]\}" \
|
||||
"breakpoint commands: check that commands are set"
|
||||
|
||||
mi_gdb_test "-break-commands 7" \
|
||||
"\\^done" \
|
||||
"breakpoint commands: clear commands"
|
||||
|
||||
mi_list_breakpoints [list [list 7 "keep" "callee2" "basics.c" "$line_callee2_body" $hex]] \
|
||||
"breakpoint commands: check that commands are cleared"
|
||||
}
|
||||
|
||||
test_tbreak_creation_and_listing
|
||||
test_rbreak_creation_and_listing
|
||||
|
||||
|
@ -206,5 +230,7 @@ test_error
|
|||
|
||||
test_disabled_creation
|
||||
|
||||
test_breakpoint_commands
|
||||
|
||||
mi_gdb_exit
|
||||
return 0
|
||||
|
|
|
@ -1170,21 +1170,22 @@ proc mi_list_breakpoints { expected test } {
|
|||
set body ""
|
||||
set first 1
|
||||
|
||||
foreach item $children {
|
||||
foreach item $expected {
|
||||
if {$first == 0} {
|
||||
set body "$body,"
|
||||
set first 0
|
||||
}
|
||||
set number disp func file line address
|
||||
set number [lindex $item 0]
|
||||
set disp [lindex $item 1]
|
||||
set func [lindex $item 2]
|
||||
set line [lindex $item 3]
|
||||
set address [lindex $item 4]
|
||||
set body "$body,bkpt=\{number=\"$number\",type=\"breakpoint\",disp=\"$disp\",enabled=\"y\",addr=\"$address\",func=\"$func\",file=\"$file\",${fullname},line=\"$line\",times=\"0\",original-location=\".*\"\}"
|
||||
set file [lindex $item 3]
|
||||
set line [lindex $item 4]
|
||||
set address [lindex $item 5]
|
||||
set body "${body}bkpt=\{number=\"$number\",type=\"breakpoint\",disp=\"$disp\",enabled=\"y\",addr=\"$address\",func=\"$func\",file=\".*$file\",${fullname},line=\"$line\",times=\"0\",original-location=\".*\"\}"
|
||||
set first 0
|
||||
}
|
||||
|
||||
verbose -log "Expecint: 666\\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\}.*colhdr=\"Type\".*colhdr=\"Disp\".*colhdr=\"Enb\".*colhdr=\"Address\".*colhdr=\"What\".*\\\],body=\\\[$body\\\]\}" \
|
||||
verbose -log "Expecting: 666\\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\}.*colhdr=\"Type\".*colhdr=\"Disp\".*colhdr=\"Enb\".*colhdr=\"Address\".*colhdr=\"What\".*\\\],body=\\\[$body\\\]\}"
|
||||
mi_gdb_test "666-break-list" \
|
||||
"666\\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\}.*colhdr=\"Type\".*colhdr=\"Disp\".*colhdr=\"Enb\".*colhdr=\"Address\".*colhdr=\"What\".*\\\],body=\\\[$body\\\]\}" \
|
||||
$test
|
||||
|
|
Loading…
Reference in a new issue