📄 watchpoint.exp
字号:
# Copyright 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000# 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 2 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, write to the Free Software# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Please email any bugs, comments, and/or additions to this file to:# bug-gdb@prep.ai.mit.edu# This file was written by Fred Fish. (fnf@cygnus.com)if $tracelevel then { strace $tracelevel}set prms_id 0set bug_id 0set testfile "watchpoint"set srcfile ${testfile}.cset binfile ${objdir}/${subdir}/${testfile}set wp_set 1if [get_compiler_info ${binfile}] { return -1}if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."}# Prepare for watchpoint tests by setting up two breakpoints and one# watchpoint.## We use breakpoints at marker functions to get past all the startup code,# so we can get to the watchpoints in a reasonable amount of time from a# known starting point.## For simplicity, so we always know how to reference specific breakpoints or# watchpoints by number, we expect a particular ordering and numbering of# each in the combined breakpoint/watchpoint table, as follows:## Number What Where# 1 Breakpoint marker1()# 2 Breakpoint marker2()# 3 Watchpoint ival3proc initialize {} { global gdb_prompt global hex global decimal global srcfile global wp_set # Disable hardware watchpoints if necessary. if [target_info exists gdb,no_hardware_watchpoints] { gdb_test "set can-use-hw-watchpoints 0" "" "" } if [gdb_test "break marker1" "Breakpoint 1 at $hex: file .*$srcfile, line $decimal.*" "set breakpoint at marker1" ] { return 0; } if [gdb_test "break marker2" "Breakpoint 2 at $hex: file .*$srcfile, line $decimal.*" "set breakpoint at marker2" ] { return 0; } if [gdb_test "info break" "1\[ \]*breakpoint.*marker1.*\r\n2\[ \]*breakpoint.*marker2.*" "info break in watchpoint.exp" ] { return 0; } # ??rehrauer: To fix DTS #CHFts23014, in which setting a watchpoint # before running can cause the inferior to croak on HP-UX 11.0 for # reasons yet unknown, we've disabled the ability to set watches # without a running inferior. Verify the restriction. # send_gdb "watch ival3\n" gdb_expect { -re ".*\[Ww\]atchpoint 3: ival3.*$gdb_prompt $" { pass "set watchpoint on ival3" } -re "warning: can't do that without a running program; try \"break main\", \"run\" first.*$gdb_prompt $" { pass "set watchpoint on ival3" set wp_set 0 return 1 } timeout { fail "(timeout) set watchpoint on ival3" return 0 } } # "info watch" is the same as "info break" if [gdb_test "info watch" "1\[ \]*breakpoint.*marker1.*\r\n2\[ \]*breakpoint.*marker2.*\r\n3\[ \]*.*watchpoint.*ival3" "watchpoint found in watchpoint/breakpoint table" ] { return 0; } # After installing the watchpoint, we disable it until we are ready # to use it. This allows the test program to run at full speed until # we get to the first marker function. if [gdb_test "disable 3" "disable 3\[\r\n\]+" "disable watchpoint" ] { return 0; } return 1}## Test simple watchpoint.#proc test_simple_watchpoint {} { global gdb_prompt global hex global decimal global wp_set # Ensure that the watchpoint is disabled when we startup. if { $wp_set } { if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "disable watchpoint in test_simple_watchpoint" ] { return 0; } } # Run until we get to the first marker function. gdb_run_cmd set timeout 600 gdb_expect { -re "Breakpoint 1, marker1 .*$gdb_prompt $" { pass "run to marker1 in test_simple_watchpoint" } -re ".*$gdb_prompt $" { fail "run to marker1 in test_simple_watchpoint" return } timeout { fail "run to marker1 in test_simple_watchpoint (timeout)" return } } if { !$wp_set } { # ??rehrauer: To fix DTS #CHFts23014, in which setting a watchpoint # before running can cause the inferior to croak on HP-UX 11.0 # for reasons yet unknown, we've disabled the ability to set # watches without a running inferior. The following testpoints used # to be in [initialize]. # send_gdb "watch ival3\n" gdb_expect { -re ".*\[Ww\]atchpoint 3: ival3\r\n$gdb_prompt $" { pass "set watchpoint on ival3" } -re ".*$gdb_prompt $" { fail "set watchpoint on ival3" } timeout { fail "set watchpoint on ival3 (timeout)" } } set wp_set 1 # "info watch" is the same as "info break" send_gdb "info watch\n" gdb_expect { -re "1\[ \]*breakpoint.*marker1.*\r\n2\[ \]*breakpoint.*marker2.*\r\n3\[ \]*.*watchpoint.*ival3\r\n$gdb_prompt $" { pass "watchpoint found in watchpoint/breakpoint table" } -re ".*$gdb_prompt $" { fail "watchpoint found in watchpoint/breakpoint table" } timeout { fail "watchpoint found in watchpoint/breakpoint table" } } # After installing the watchpoint, we disable it until we are ready # to use it. This allows the test program to run at full speed until # we get to the first marker function. send_gdb "disable 3\n" gdb_expect { -re "disable 3\[\r\n\]+$gdb_prompt $" { pass "disable watchpoint" } -re ".*$gdb_prompt $" { fail "disable watchpoint" } timeout { fail "disable watchpoint (timeout)" } } } # After reaching the marker function, enable the watchpoint. if [gdb_test "enable 3" "^enable 3\[\r\n\]+" "enable watchpoint" ] { return ; } gdb_test "break func1" "Breakpoint.*at.*" gdb_test "set \$func1_breakpoint_number = \$bpnum" "" gdb_test "continue" "Continuing.*Breakpoint \[0-9\]*, func1.*" \ "continue to breakpoint at func1" # Continue until the first change, from -1 to 0 send_gdb "cont\n" gdb_expect { -re "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = -1.*New value = 0.*ival3 = count; ival4 = count;.*$gdb_prompt $" { pass "watchpoint hit, first time" } -re "Continuing.*Breakpoint.*func1.*$gdb_prompt $" { setup_xfail "m68*-*-*" 2597 fail "thought it hit breakpoint at func1 twice" gdb_test "delete \$func1_breakpoint_number" "" gdb_test "continue" "\Continuing.*\[Ww\]atchpoint.*ival3.*Old value = -1.*New value = 0.*ival3 = count;" \ "watchpoint hit, first time" } -re ".*$gdb_prompt $" { fail "watchpoint hit, first time" ; return } timeout { fail "watchpoint hit, first time (timeout)" ; return } eof { fail "watchpoint hit, first time (eof)" ; return } } # Check that the hit count is reported correctly gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 1 time.*" "Watchpoint hit count is 1" gdb_test "delete \$func1_breakpoint_number" "" # Continue until the next change, from 0 to 1. gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 0.*New value = 1.*ival3 = count; ival4 = count;.*" "watchpoint hit, second time" # Check that the hit count is reported correctly gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 2 times.*" "Watchpoint hit count is 2" # Continue until the next change, from 1 to 2. gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 1.*New value = 2.*ival3 = count; ival4 = count;.*" "watchpoint hit, third time" # Check that the hit count is reported correctly gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 3 times.*" "Watchpoint hit count is 3" # Continue until the next change, from 2 to 3. gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 2.*New value = 3.*ival3 = count; ival4 = count;.*" "watchpoint hit, fourth time" # Check that the hit count is reported correctly gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 4 times.*" "Watchpoint hit count is 4" # Continue until the next change, from 3 to 4. # Note that this one is outside the loop. gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 3.*New value = 4.*ival3 = count; ival4 = count;.*" "watchpoint hit, fifth time" # Check that the hit count is reported correctly gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 5 times.*" "Watchpoint hit count is 5" # Continue until we hit the finishing marker function. # Make sure we hit no more watchpoints. gdb_test "cont" "Continuing.*Breakpoint.*marker2 \(\).*" \ "continue to marker2" # Disable the watchpoint so we run at full speed until we exit. if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "watchpoint disabled" ] { return ; } # Run until process exits. if [target_info exists gdb,noresults] { return } gdb_continue_to_end "continue to exit in test_simple_watchpoint"}# Test disabling watchpoints.proc test_disabling_watchpoints {} { global gdb_prompt global binfile global srcfile global decimal global hex # "info watch" is the same as "info break" gdb_test "info watch" "\[0-9\]+\[ \]*breakpoint.*marker1.*\r\n\[0-9\]+\[ \]*breakpoint.*marker2.*\r\n\[0-9]+\[ \]*.*watchpoint.*ival3\r\n\.*\[0-9\]+ times.*" "watchpoints found in watchpoint/breakpoint table" # Ensure that the watchpoint is disabled when we startup. if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "disable watchpoint in test_disabling_watchpoints" ] { return 0; } # Run until we get to the first marker function. gdb_run_cmd set timeout 600 gdb_expect { -re "Breakpoint 1, marker1 .*$gdb_prompt $" { pass "run to marker1 in test_disabling_watchpoints" } -re ".*$gdb_prompt $" { fail "run to marker1 in test_disabling_watchpoints" return } timeout { fail "run to marker1 in test_disabling_watchpoints (timeout)" return } } # After reaching the marker function, enable the watchpoint. if [gdb_test "enable 3" "^enable 3\[\r\n\]+" "watchpoint enabled" ] { return ; } # Continue until the first change, from -1 to 0 # Don't check the old value, because on VxWorks the variable value # will not have been reinitialized. gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = .*New value = 0.*ival3 = count; ival4 = count;.*" "watchpoint hit in test_disabling_watchpoints, first time" # Continue until the next change, from 0 to 1. gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 0.*New value = 1.*ival3 = count; ival4 = count;.*" "watchpoint hit in test_disabling_watchpoints, second time" # Disable the watchpoint but leave breakpoints if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "disable watchpoint #2 in test_disabling_watchpoints" ] { return 0; } # Check watchpoint list, looking for the entry that confirms the # watchpoint is disabled. gdb_test "info watchpoints" "\[0-9]+\[ \]*.*watchpoint\[ \]*keep\[ \]*n\[ \]*ival3\r\n.*" "watchpoint disabled in table" # Continue until we hit the finishing marker function. # Make sure we hit no more watchpoints. gdb_test "cont" "Continuing.*Breakpoint.*marker2 \\(\\).*" \ "disabled watchpoint skipped" if [target_info exists gdb,noresults] { return } gdb_continue_to_end "continue to exit in test_disabling_watchpoints"}# Test stepping and other mundane operations with watchpoints enabledproc test_stepping {} { global gdb_prompt if [runto marker1] then { gdb_test "watch ival2" ".*\[Ww\]atchpoint \[0-9\]*: ival2" # Well, let's not be too mundane. It should be a *bit* of a challenge gdb_test "break func2 if 0" "Breakpoint.*at.*" gdb_test "p \$func2_breakpoint_number = \$bpnum" " = .*" gdb_test "p func1 ()" "= 73" \ "calling function with watchpoint enabled" # # "finish" brings us back to main. # On some targets (e.g. alpha) gdb will stop from the finish in midline # of the marker1 call. This is due to register restoring code on # the alpha and might be caused by stack adjustment instructions # on other targets. In this case we will step once more. # send_gdb "finish\n" gdb_expect { -re "Run.*exit from.*marker1.* at" { pass "finish from marker1" } default { fail "finish from marker1 (timeout)" ; return } } gdb_expect { -re "marker1 \\(\\);.*$gdb_prompt $" { send_gdb "step\n" exp_continue } -re "func1 \\(\\);.*$gdb_prompt $" { pass "back at main from marker1" } -re ".*$gdb_prompt $" { fail "back at main from marker1" } default { fail "back at main from marker1 (timeout)" ; return } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -