1# This testcase is part of GDB, the GNU debugger. 2 3# Copyright 2004, 2007 Free Software Foundation, Inc. 4 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 3 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18# Check that GDB can support multiple watchpoints across threads. 19 20if $tracelevel { 21 strace $tracelevel 22} 23 24set prms_id 0 25set bug_id 0 26 27# This test verifies that a watchpoint is detected in the proper thread 28# so the test is only meaningful on a system with hardware watchpoints. 29if [target_info exists gdb,no_hardware_watchpoints] { 30 return 0; 31} 32 33set testfile "watchthreads" 34set srcfile ${testfile}.c 35set binfile ${objdir}/${subdir}/${testfile} 36if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } { 37 return -1 38} 39 40gdb_exit 41gdb_start 42gdb_reinitialize_dir $srcdir/$subdir 43gdb_load ${binfile} 44 45gdb_test "set can-use-hw-watchpoints 1" "" "" 46 47# 48# Run to `main' where we begin our tests. 49# 50 51if ![runto_main] then { 52 gdb_suppress_tests 53} 54 55set args_0 0 56set args_1 0 57 58# Watch values that will be modified by distinct threads. 59gdb_test "watch args\[0\]" "Hardware watchpoint 2: args\\\[0\\\]" 60gdb_test "watch args\[1\]" "Hardware watchpoint 3: args\\\[1\\\]" 61 62set init_line [expr [gdb_get_line_number "Init value"]+1] 63set inc_line [gdb_get_line_number "Loop increment"] 64 65# Loop and continue to allow both watchpoints to be triggered. 66for {set i 0} {$i < 30} {incr i} { 67 set test_flag 0 68 gdb_test_multiple "continue" "threaded watch loop" { 69 -re "Hardware watchpoint 2: args\\\[0\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*watchthreads.c:$init_line.*$gdb_prompt $" 70 { set args_0 1; set test_flag 1 } 71 -re "Hardware watchpoint 3: args\\\[1\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*watchthreads.c:$init_line.*$gdb_prompt $" 72 { set args_1 1; set test_flag 1 } 73 -re "Hardware watchpoint 2: args\\\[0\\\].*Old value = $args_0.*New value = [expr $args_0+1].*in thread_function \\\(arg=0x0\\\) at .*watchthreads.c:$inc_line.*$gdb_prompt $" 74 { set args_0 [expr $args_0+1]; set test_flag 1 } 75 -re "Hardware watchpoint 3: args\\\[1\\\].*Old value = $args_1.*New value = [expr $args_1+1].*in thread_function \\\(arg=0x1\\\) at .*watchthreads.c:$inc_line.*$gdb_prompt $" 76 { set args_1 [expr $args_1+1]; set test_flag 1 } 77 } 78 # If we fail above, don't bother continuing loop 79 if { $test_flag == 0 } { 80 set i 30; 81 } 82} 83 84# Print success message if loop succeeded. 85if { $test_flag == 1 } { 86 pass "threaded watch loop" 87} 88 89# Verify that we hit first watchpoint in main thread. 90set message "first watchpoint on args\[0\] hit" 91if { $args_0 > 0 } { 92 pass $message 93} else { 94 fail $message 95} 96 97# Verify that we hit second watchpoint in main thread. 98set message "first watchpoint on args\[1\] hit" 99if { $args_1 > 0 } { 100 pass $message 101} else { 102 fail $message 103} 104 105# Verify that we hit first watchpoint in child thread. 106set message "watchpoint on args\[0\] hit in thread" 107if { $args_0 > 1 } { 108 pass $message 109} else { 110 fail $message 111} 112 113# Verify that we hit second watchpoint in child thread. 114set message "watchpoint on args\[1\] hit in thread" 115if { $args_1 > 1 } { 116 pass $message 117} else { 118 fail $message 119} 120 121# Verify that all watchpoint hits are accounted for. 122set message "combination of threaded watchpoints = 30" 123if { [expr $args_0+$args_1] == 30 } { 124 pass $message 125} else { 126 fail $message 127} 128