d708bcd102
While trying to fix hbreak2.exp against GDBserver I noticed this... (gdb) hbreak main if 1 Sending packet: $m400580,40#2e...Packet received: e8d2ffffff5dc3554889e54883ec10c745fc00000000eb0eb800000000e8c1ffffff8345fc01817dfce70300007ee9b800000000c9c3662e0f1f840000000000 Sending packet: $m40058f,1#31...Packet received: c7 Hardware assisted breakpoint 1 at 0x40058f: file ../../../src/gdb/testsuite/gdb.base/break-idempotent.c, line 46. Sending packet: $Z1,40058f,1;X3,220127#9b... *hangs forever* The issue is that nothing advances the packet pointer if add_breakpoint_condition either fails to parse the agent expression, or fails to find the breakpoint, resulting in an infinite loop in process_point_options. The latter case should really be fixed by GDBserver tracking GDB Z1 breakpoints in its breakpoint structures like Z0 breakpoints are, but the latter case still needs handling. add_breakpoint_commands has the same issue, though at present I don't know any way to trigger it other than sending a manually cooked packet. Unbelievably, it doesn't look like we have any test that tries setting a conditional hardware breakpoint. Looking at cond-eval-mode.exp, it looks like the file was meant to actually test something, but it's mostly empty today. This patch adds tests that tries all sorts of conditional breakpoints and watchpoints. The test hangs/fails without the GDBserver fix. Tested on x86_64 Fedora 17. gdb/gdbserver/ 2014-04-10 Pedro Alves <palves@redhat.com> * mem-break.c (add_breakpoint_condition, add_breakpoint_commands): Check if the condition or command is NULL before checking if the breakpoint is known. On success, return true. * mem-break.h (add_breakpoint_condition): Document return. (add_breakpoint_commands): Add describing comment. * server.c (skip_to_semicolon): New function. (process_point_options): Use it. gdb/testsuite/ 2014-04-10 Pedro Alves <palves@redhat.com> * gdb.base/cond-eval-mode.c: New file. * gdb.base/cond-eval-mode.exp: Use standard_testfile. Adjust prepare_for_testing to build the new file. Check result of runto_main. (test_break, test_watch): New procedures. (top level): Use them.
152 lines
3.6 KiB
Text
152 lines
3.6 KiB
Text
# Copyright 2012-2014 Free Software Foundation, Inc.
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# Test 'set breakpoint condition-evaluation' settings
|
|
|
|
standard_testfile
|
|
|
|
if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
|
|
return -1
|
|
}
|
|
|
|
if ![runto_main] then {
|
|
fail "Can't run to main"
|
|
return 0
|
|
}
|
|
|
|
set test_host "set breakpoint condition-evaluation host"
|
|
set test_auto "set breakpoint condition-evaluation auto"
|
|
set test_target "set breakpoint condition-evaluation target"
|
|
|
|
gdb_test_no_output $test_host
|
|
gdb_test_no_output $test_auto
|
|
|
|
# If target-side condition evaluation is not supported, this warning will be
|
|
# displayed.
|
|
set warning "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n"
|
|
|
|
gdb_test_multiple $test_target $test_target {
|
|
-re "$warning$gdb_prompt $" {
|
|
unsupported $test_target
|
|
return -1
|
|
}
|
|
|
|
-re "^$test_target\r\n$gdb_prompt $" {
|
|
pass $test_target
|
|
}
|
|
}
|
|
|
|
# Test setting a condition in a breakpoint. BREAK_COMMAND is the
|
|
# break/hwatch command to test.
|
|
#
|
|
proc test_break { break_command } {
|
|
global gdb_prompt
|
|
|
|
with_test_prefix "$break_command" {
|
|
delete_breakpoints
|
|
|
|
gdb_test "$break_command foo" "reakpoint.* at .*"
|
|
|
|
# A condition that evals true.
|
|
gdb_test "condition \$bpnum cond_global==0" ".*"
|
|
|
|
set can_do_cmd 0
|
|
|
|
set test "continue"
|
|
gdb_test_multiple $test $test {
|
|
-re "You may have requested too many.*$gdb_prompt $" {
|
|
pass $test
|
|
}
|
|
-re "Breakpoint .*, foo .*$gdb_prompt $" {
|
|
pass $test
|
|
set can_do_cmd 1
|
|
}
|
|
}
|
|
|
|
if { !$can_do_cmd } {
|
|
unsupported "no target support"
|
|
return
|
|
}
|
|
|
|
delete_breakpoints
|
|
|
|
gdb_test "$break_command foo" ".*reakpoint .* at .*"
|
|
|
|
# A condition that evals false.
|
|
gdb_test "condition \$bpnum cond_global==1" ".*"
|
|
|
|
gdb_test "b bar" "Breakpoint .* at .*"
|
|
|
|
gdb_test "continue" "Breakpoint .*, bar .*"
|
|
}
|
|
}
|
|
|
|
# Test setting conditions in watchpoints. WATCH_COMMAND is the watch
|
|
# command to test.
|
|
#
|
|
proc test_watch { watch_command } {
|
|
global gdb_prompt
|
|
|
|
with_test_prefix "$watch_command" {
|
|
if [target_info exists gdb,no_hardware_watchpoints] {
|
|
unsupported "no target support"
|
|
return
|
|
}
|
|
|
|
delete_breakpoints
|
|
|
|
gdb_test "$watch_command global" ".*atchpoint .*: global.*"
|
|
|
|
# A condition that evals true.
|
|
gdb_test "condition \$bpnum cond_global==0" ".*"
|
|
|
|
set can_do_cmd 0
|
|
|
|
set test "continue"
|
|
gdb_test_multiple $test $test {
|
|
-re "You may have requested too many.*$gdb_prompt $" {
|
|
pass $test
|
|
}
|
|
-re "atchpoint .*: global.*$gdb_prompt $" {
|
|
pass $test
|
|
set can_do_cmd 1
|
|
}
|
|
}
|
|
|
|
if { !$can_do_cmd } {
|
|
unsupported "no target support"
|
|
return
|
|
}
|
|
|
|
delete_breakpoints
|
|
|
|
gdb_test "$watch_command global" ".*atchpoint .*: global.*"
|
|
|
|
# A condition that evals false.
|
|
gdb_test "condition \$bpnum cond_global==1" ".*"
|
|
|
|
gdb_test "b bar" "Breakpoint .* at .*"
|
|
|
|
gdb_test "continue" "Breakpoint .*, bar .*"
|
|
}
|
|
}
|
|
|
|
foreach break_command { "break" "hbreak" } {
|
|
test_break $break_command
|
|
}
|
|
|
|
foreach watch_command { "watch" "rwatch" "awatch" } {
|
|
test_watch $watch_command
|
|
}
|