mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 13:56:22 +08:00
Explicit locations: MI support for explicit locations
This patch adds support for explicit locations to MI's -break-insert command. The new options, documented in the User Manual, are --source, --line, --function, and --label. gdb/ChangeLog: * mi/mi-cmd-break.c (mi_cmd_break_insert_1): Add support for explicit locations, options "--source", "--function", "--label", and "--line". gdb/testsuite/ChangeLog: * gdb.mi/mi-break.exp (test_explicit_breakpoints): New proc. (at toplevel): Call test_explicit_breakpoints. * gdb.mi/mi-dprintf.exp: Add tests for explicit dprintf breakpoints. * lib/mi-support.exp (mi_make_breakpoint): Add support for breakpoint conditions, "-cond".
This commit is contained in:
@ -1,3 +1,9 @@
|
||||
2015-08-11 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* mi/mi-cmd-break.c (mi_cmd_break_insert_1): Add support for
|
||||
explicit locations, options "--source", "--function",
|
||||
"--label", and "--line".
|
||||
|
||||
2015-08-11 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* completer.c: Include location.h.
|
||||
|
@ -182,6 +182,8 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
|
||||
enum bptype type_wanted;
|
||||
struct event_location *location;
|
||||
struct breakpoint_ops *ops;
|
||||
int is_explicit = 0;
|
||||
struct explicit_location explicit;
|
||||
char *extra_string = NULL;
|
||||
|
||||
enum opt
|
||||
@ -189,6 +191,8 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
|
||||
HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
|
||||
IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
|
||||
TRACEPOINT_OPT,
|
||||
EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT,
|
||||
EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT
|
||||
};
|
||||
static const struct mi_opt opts[] =
|
||||
{
|
||||
@ -200,6 +204,10 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
|
||||
{"f", PENDING_OPT, 0},
|
||||
{"d", DISABLE_OPT, 0},
|
||||
{"a", TRACEPOINT_OPT, 0},
|
||||
{"-source" , EXPLICIT_SOURCE_OPT, 1},
|
||||
{"-function", EXPLICIT_FUNC_OPT, 1},
|
||||
{"-label", EXPLICIT_LABEL_OPT, 1},
|
||||
{"-line", EXPLICIT_LINE_OPT, 1},
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
@ -208,6 +216,8 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
|
||||
int oind = 0;
|
||||
char *oarg;
|
||||
|
||||
initialize_explicit_location (&explicit);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int opt = mi_getopt ("-break-insert", argc, argv,
|
||||
@ -240,16 +250,31 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
|
||||
case TRACEPOINT_OPT:
|
||||
tracepoint = 1;
|
||||
break;
|
||||
case EXPLICIT_SOURCE_OPT:
|
||||
is_explicit = 1;
|
||||
explicit.source_filename = oarg;
|
||||
break;
|
||||
case EXPLICIT_FUNC_OPT:
|
||||
is_explicit = 1;
|
||||
explicit.function_name = oarg;
|
||||
break;
|
||||
case EXPLICIT_LABEL_OPT:
|
||||
is_explicit = 1;
|
||||
explicit.label_name = oarg;
|
||||
break;
|
||||
case EXPLICIT_LINE_OPT:
|
||||
is_explicit = 1;
|
||||
explicit.line_offset = linespec_parse_line_offset (oarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (oind >= argc)
|
||||
if (oind >= argc && !is_explicit)
|
||||
error (_("-%s-insert: Missing <location>"),
|
||||
dprintf ? "dprintf" : "break");
|
||||
address = argv[oind];
|
||||
if (dprintf)
|
||||
{
|
||||
int format_num = oind + 1;
|
||||
int format_num = is_explicit ? oind : oind + 1;
|
||||
|
||||
if (hardware || tracepoint)
|
||||
error (_("-dprintf-insert: does not support -h or -a"));
|
||||
@ -258,11 +283,21 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
|
||||
|
||||
extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
|
||||
make_cleanup (xfree, extra_string);
|
||||
address = argv[oind];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (oind < argc - 1)
|
||||
error (_("-break-insert: Garbage following <location>"));
|
||||
if (is_explicit)
|
||||
{
|
||||
if (oind < argc)
|
||||
error (_("-break-insert: Garbage following explicit location"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (oind < argc - 1)
|
||||
error (_("-break-insert: Garbage following <location>"));
|
||||
address = argv[oind];
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we have what we need, let's insert the breakpoint! */
|
||||
@ -291,11 +326,30 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
|
||||
ops = &bkpt_breakpoint_ops;
|
||||
}
|
||||
|
||||
location = string_to_event_location (&address, current_language);
|
||||
make_cleanup_delete_event_location (location);
|
||||
if (is_explicit)
|
||||
{
|
||||
/* Error check -- we must have one of the other
|
||||
parameters specified. */
|
||||
if (explicit.source_filename != NULL
|
||||
&& explicit.function_name == NULL
|
||||
&& explicit.label_name == NULL
|
||||
&& explicit.line_offset.sign == LINE_OFFSET_UNKNOWN)
|
||||
error (_("-%s-insert: --source option requires --function, --label,"
|
||||
" or --line"), dprintf ? "dprintf" : "break");
|
||||
|
||||
if (*address)
|
||||
error (_("Garbage '%s' at end of location"), address);
|
||||
location = new_explicit_location (&explicit);
|
||||
}
|
||||
else
|
||||
{
|
||||
location = string_to_event_location (&address, current_language);
|
||||
if (*address)
|
||||
{
|
||||
delete_event_location (location);
|
||||
error (_("Garbage '%s' at end of location"), address);
|
||||
}
|
||||
}
|
||||
|
||||
make_cleanup_delete_event_location (location);
|
||||
|
||||
create_breakpoint (get_current_arch (), location, condition, thread,
|
||||
extra_string,
|
||||
|
@ -1,3 +1,12 @@
|
||||
2015-08-11 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* gdb.mi/mi-break.exp (test_explicit_breakpoints): New proc.
|
||||
(at toplevel): Call test_explicit_breakpoints.
|
||||
* gdb.mi/mi-dprintf.exp: Add tests for explicit dprintf
|
||||
breakpoints.
|
||||
* lib/mi-support.exp (mi_make_breakpoint): Add support for
|
||||
breakpoint conditions, "-cond".
|
||||
|
||||
2015-08-11 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* gdb.linespec/3explicit.c: New file.
|
||||
|
@ -305,6 +305,86 @@ proc test_breakpoint_commands {} {
|
||||
mi_expect_stop "exited-normally" "" "" "" "" "" "test hitting breakpoint with commands"
|
||||
}
|
||||
|
||||
# Test explicit breakpoints. These tests only test the MI portion of the
|
||||
# code. In-depth testing of explicit breakpoints is accomplished in
|
||||
# gdb.linespec tests.
|
||||
|
||||
proc test_explicit_breakpoints {} {
|
||||
global srcfile
|
||||
global line_callee3_head line_callee4_head
|
||||
global line_callee2_body line_main_body
|
||||
|
||||
mi_delete_breakpoints
|
||||
|
||||
# First check mixed explicit/parsed linespecs.
|
||||
mi_gdb_test "-break-insert --function main $srcfile:$line_callee3_head" \
|
||||
".*Garbage following explicit linespec"
|
||||
|
||||
# Insert some breakpoints and list them
|
||||
# Also, disable some so they do not interfere with other tests
|
||||
# Tests:
|
||||
# -break-insert -t --function main
|
||||
# -break-insert -t --source basics.c --function callee2
|
||||
# -break-insert -t --source basics.c --line $line_callee3_head
|
||||
# -break-insert -t --source srcfile --line $line_callee4_head
|
||||
# -break-list
|
||||
|
||||
set bps {}
|
||||
lappend bps [mi_create_breakpoint "-t --function main" \
|
||||
"insert temp explicit breakpoint in main" \
|
||||
-func main -file ".*$srcfile" -line $line_main_body]
|
||||
|
||||
lappend bps \
|
||||
[mi_create_breakpoint "-t --source $srcfile --function callee2" \
|
||||
"insert temp explicit breakpoint at $srcfile:callee2" \
|
||||
-func callee2 -file ".*$srcfile" -line $line_callee2_body]
|
||||
|
||||
lappend bps \
|
||||
[mi_create_breakpoint "-t --source $srcfile --line $line_callee3_head" \
|
||||
"insert temp explicit breakpoint at $srcfile:$line_callee3_head" \
|
||||
-func callee3 -file ".*$srcfile" -line $line_callee3_head]
|
||||
|
||||
lappend bps \
|
||||
[mi_create_breakpoint \
|
||||
"-t --source \"$srcfile\" --line $line_callee4_head" \
|
||||
"insert temp explicit breakpoint at \"$srcfile\":$line_callee4_head" \
|
||||
-func callee4 -file ".*$srcfile" -line $line_callee4_head]
|
||||
|
||||
mi_gdb_test "-break-list" "\\^done,[mi_make_breakpoint_table $bps]" \
|
||||
"list of explicit breakpoints"
|
||||
|
||||
mi_gdb_test "-break-delete" \
|
||||
"\\^done" \
|
||||
"delete temp breakpoints"
|
||||
|
||||
mi_create_breakpoint "-c \"intarg == 3\" --function callee2" \
|
||||
"insert explicit conditional breakpoint in callee2" \
|
||||
-func callee2 ".*$srcfile" -line $line_callee2_body \
|
||||
-cond "intarg == 3"
|
||||
|
||||
# mi_create_breakpoint cannot deal with displaying canonical
|
||||
# linespecs.
|
||||
mi_gdb_test \
|
||||
"-break-insert -c \"foo == 3\" --source $srcfile --function main --label label" \
|
||||
".*No symbol \"foo\" in current context.*"
|
||||
|
||||
mi_gdb_test \
|
||||
"-break-insert --source foobar.c --line 3" \
|
||||
".*No source file named foobar.c.*"
|
||||
|
||||
mi_gdb_test \
|
||||
"-break-insert --source $srcfile --function foobar" \
|
||||
".*Function \"foobar\" not defined in \"$srcfile\".*"
|
||||
|
||||
mi_gdb_test \
|
||||
"-break-insert --source $srcfile --function main --label foobar" \
|
||||
".*No label \"foobar\" defined in function \"main\".*"
|
||||
|
||||
mi_gdb_test \
|
||||
"-break-insert --source $srcfile" \
|
||||
".*Source filename requires function, label, or line offset.*"
|
||||
}
|
||||
|
||||
test_tbreak_creation_and_listing
|
||||
test_rbreak_creation_and_listing
|
||||
|
||||
@ -318,5 +398,7 @@ test_breakpoint_commands
|
||||
|
||||
test_abreak_creation
|
||||
|
||||
test_explicit_breakpoints
|
||||
|
||||
mi_gdb_exit
|
||||
return 0
|
||||
|
@ -47,6 +47,16 @@ mi_gdb_test "[incr i]-dprintf-insert 29" \
|
||||
"$i\\^error,msg=\"-dprintf-insert: Missing <format>\"" "mi insert second breakpoint without format string"
|
||||
|
||||
mi_gdb_test "-break-insert main" ".*" "mi insert breakpoint main"
|
||||
|
||||
mi_gdb_test "-dprintf-insert --function main \"hello\"" \
|
||||
"\\^done,bkpt={.*}" "explicit dprintf at main"
|
||||
|
||||
mi_gdb_test "-dprintf-insert --source $srcfile --line $dp_location1 \"hello\"" \
|
||||
"\\^done,bkpt={.*}" "explicit breakpoint at $srcfile:$dp_location1"
|
||||
|
||||
mi_gdb_test "-dprintf-insert --source $srcfile \"hello\"" \
|
||||
"\\^error,msg=\"-dprintf-insert: --source option requires --function, --label, or --line\"" "invalid explicit dprintf"
|
||||
|
||||
mi_delete_breakpoints
|
||||
|
||||
set bps [mi_make_breakpoint -type dprintf -func foo -file ".*mi-dprintf.c" \
|
||||
@ -61,7 +71,7 @@ mi_gdb_test "[incr i]-dprintf-insert $dp_location1 \"arg=%d, g=%d\\n\" arg g" \
|
||||
"$i\\^done,$bps" "mi insert dprintf dp_location1"
|
||||
|
||||
set bps {}
|
||||
lappend bps [mi_make_breakpoint -number 3 -type dprintf -func foo \
|
||||
lappend bps [mi_make_breakpoint -type dprintf -func foo \
|
||||
-file ".*mi-dprintf.c" -fullname ".*mi-dprintf.c"]
|
||||
lappend bps [mi_make_breakpoint -type dprintf -func foo \
|
||||
-file ".*mi-dprintf.c" -fullname ".*mi-dprintf.c" \
|
||||
|
@ -2395,7 +2395,7 @@ proc mi_build_kv_pairs {attr_list {joiner ,}} {
|
||||
#
|
||||
# All arguments for the breakpoint may be specified using the options
|
||||
# number, type, disp, enabled, addr, func, file, fullanme, line,
|
||||
# thread-groups, times, ignore, script, and original-location.
|
||||
# thread-groups, cond, times, ignore, script, and original-location.
|
||||
#
|
||||
# Only if -script and -ignore are given will they appear in the output.
|
||||
# Otherwise, this procedure will skip them using ".*".
|
||||
@ -2410,17 +2410,27 @@ proc mi_make_breakpoint {args} {
|
||||
parse_args {{number .*} {type .*} {disp .*} {enabled .*} {addr .*}
|
||||
{func .*} {file .*} {fullname .*} {line .*}
|
||||
{thread-groups \\\[.*\\\]} {times .*} {ignore 0}
|
||||
{script ""} {original-location .*}}
|
||||
{script ""} {original-location .*} {cond ""}}
|
||||
|
||||
set attr_list {}
|
||||
foreach attr [list number type disp enabled addr func file \
|
||||
fullname line thread-groups times] {
|
||||
fullname line thread-groups] {
|
||||
lappend attr_list $attr [set $attr]
|
||||
}
|
||||
|
||||
set result "bkpt={[mi_build_kv_pairs $attr_list]"
|
||||
|
||||
# There are always exceptions.
|
||||
|
||||
# If COND is not preset, do not output it.
|
||||
if {[string length $cond] > 0} {
|
||||
append result ","
|
||||
append result [mi_build_kv_pairs [list "cond" $cond]]
|
||||
}
|
||||
|
||||
append result ","
|
||||
append result [mi_build_kv_pairs [list "times" $times]]
|
||||
|
||||
# If SCRIPT and IGNORE are not present, do not output them.
|
||||
if {$ignore != 0} {
|
||||
append result ","
|
||||
|
Reference in New Issue
Block a user