1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
# Copyright (C) 2014-2015 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 that when a step-over trips on a watchpoint, that watchpoint is
# reported.
standard_testfile
set executable ${testfile}
# This test verifies that a watchpoint is detected in a multithreaded
# program so the test is only meaningful on a system with hardware
# watchpoints.
if {[skip_hw_watchpoint_tests]} {
return 0
}
if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
executable [list debug "incdir=${objdir}"]] != "" } {
return -1
}
# The test proper. DISPLACED is true if we should try with displaced
# stepping. WITH_BP is true if we should try with a thread-specific
# breakpoint (for the wrong thread) right after the instruction that
# triggers the watchpoint.
proc do_test { displaced with_bp } {
global executable
global gdb_prompt
global hex
if ${with_bp} {
set prefix "with thread-specific bp"
} else {
set prefix "no thread-specific bp"
}
with_test_prefix "displaced=$displaced: $prefix" {
# Cover both stepping and non-stepping execution commands.
foreach command {"step" "next" "continue" } {
with_test_prefix $command {
clean_restart $executable
if ![runto_main] {
continue
}
gdb_test_no_output "set displaced-stepping $displaced"
gdb_breakpoint [gdb_get_line_number "set wait-thread breakpoint here"]
gdb_continue_to_breakpoint "run to wait-thread breakpoint"
gdb_test "info threads" "2 .*\\\* 1.*" "info threads shows all threads"
gdb_test_no_output "set scheduler-locking on"
delete_breakpoints
gdb_breakpoint [gdb_get_line_number "set breakpoint child here"]
gdb_test "thread 2" "Switching to .*"
gdb_continue_to_breakpoint "run to breakpoint in thread 2"
set address_triggers_watch "<invalid>"
set after_address_triggers_watch "<invalid>"
# Let the watchpoint trigger once (with the other
# thread locked), in order to find both the address of
# the instruction that triggers the watchpoint and the
# address of the instruction immediately after.
with_test_prefix "find addresses" {
gdb_test "p watch_me = 0" " = 0" "clear watch_me"
gdb_test "watch watch_me" "Hardware watchpoint .*"
gdb_test "continue" \
"Hardware watchpoint.*: watch_me.*New value = 1.*" \
"continue to watchpoint"
set msg "find addresses"
gdb_test_multiple "disassemble" $msg {
-re " ($hex) \[^\r\n\]*\r\n=> ($hex) .*$gdb_prompt $" {
set address_triggers_watch $expect_out(1,string)
set after_address_triggers_watch $expect_out(2,string)
pass $msg
}
}
delete_breakpoints
}
gdb_test "break *$address_triggers_watch" "Breakpoint .*" \
"set breakpoint at address that triggers watch"
gdb_continue_to_breakpoint \
"run to instruction that triggers watch in thread 2"
gdb_test "p counter = 0" " = 0" "unbreak loop in thread 2"
gdb_test "p watch_me = 0" " = 0" "clear watch_me"
gdb_test "watch watch_me" "Hardware watchpoint .*"
if ${with_bp} {
gdb_test "b *$after_address_triggers_watch thread 1" \
"Breakpoint .*" \
"set breakpoint specific to thread 1"
}
# Switch back to thread 1 and disable scheduler locking.
gdb_test "thread 1" "Switching to .*"
gdb_test_no_output "set scheduler-locking off"
# Thread 2 is still stopped at a breakpoint that needs
# to be stepped over. However, the instruction that
# is under the breakpoint triggers a watchpoint, which
# should trap and be reported to the user.
gdb_test "$command" "Hardware watchpoint.*: watch_me.*New value = 1.*"
}
}
}
}
foreach displaced { "off" "on" } {
if { $displaced != "off" && ![support_displaced_stepping] } {
continue
}
foreach with_bp { 0 1 } {
do_test $displaced $with_bp
}
}
|