Home | History | Annotate | Line # | Download | only in gdb.threads
      1  1.9  christos # Copyright (C) 2014-2024 Free Software Foundation, Inc.
      2  1.1  christos 
      3  1.1  christos # This program is free software; you can redistribute it and/or modify
      4  1.1  christos # it under the terms of the GNU General Public License as published by
      5  1.1  christos # the Free Software Foundation; either version 3 of the License, or
      6  1.1  christos # (at your option) any later version.
      7  1.1  christos #
      8  1.1  christos # This program is distributed in the hope that it will be useful,
      9  1.1  christos # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  1.1  christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  1.1  christos # GNU General Public License for more details.
     12  1.1  christos #
     13  1.1  christos # You should have received a copy of the GNU General Public License
     14  1.1  christos # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15  1.1  christos 
     16  1.1  christos # Test that when a step-over trips on a watchpoint, that watchpoint is
     17  1.1  christos # reported.
     18  1.1  christos 
     19  1.1  christos standard_testfile
     20  1.1  christos set executable ${testfile}
     21  1.1  christos 
     22  1.1  christos # This test verifies that a watchpoint is detected in a multithreaded
     23  1.1  christos # program so the test is only meaningful on a system with hardware
     24  1.1  christos # watchpoints.
     25  1.9  christos require allow_hw_watchpoint_tests
     26  1.1  christos 
     27  1.1  christos if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
     28  1.1  christos 	 executable [list debug "incdir=${objdir}"]] != "" } {
     29  1.1  christos     return -1
     30  1.1  christos }
     31  1.1  christos 
     32  1.3  christos # The test proper.  DISPLACED is true if we should try with displaced
     33  1.3  christos # stepping.  WITH_BP is true if we should try with a thread-specific
     34  1.3  christos # breakpoint (for the wrong thread) right after the instruction that
     35  1.3  christos # triggers the watchpoint.
     36  1.3  christos proc do_test { displaced with_bp } {
     37  1.1  christos     global executable
     38  1.3  christos     global gdb_prompt
     39  1.3  christos     global hex
     40  1.1  christos 
     41  1.1  christos     if ${with_bp} {
     42  1.1  christos 	set prefix "with thread-specific bp"
     43  1.1  christos     } else {
     44  1.1  christos 	set prefix "no thread-specific bp"
     45  1.1  christos     }
     46  1.3  christos     with_test_prefix "displaced=$displaced: $prefix" {
     47  1.1  christos 	# Cover both stepping and non-stepping execution commands.
     48  1.1  christos 	foreach command {"step" "next" "continue" } {
     49  1.1  christos 	    with_test_prefix $command {
     50  1.1  christos 		clean_restart $executable
     51  1.1  christos 
     52  1.1  christos 		if ![runto_main] {
     53  1.1  christos 		    continue
     54  1.1  christos 		}
     55  1.1  christos 
     56  1.3  christos 		gdb_test_no_output "set displaced-stepping $displaced"
     57  1.3  christos 
     58  1.7  christos 		set line [gdb_get_line_number "set wait-thread breakpoint here"]
     59  1.7  christos 		if { ![gdb_breakpoint $line] } {
     60  1.7  christos 		    return
     61  1.7  christos 		}
     62  1.1  christos 		gdb_continue_to_breakpoint "run to wait-thread breakpoint"
     63  1.4  christos 		gdb_test "info threads" "\\\* 1 .*  2 .*" "info threads shows all threads"
     64  1.1  christos 
     65  1.1  christos 		gdb_test_no_output "set scheduler-locking on"
     66  1.1  christos 
     67  1.1  christos 		delete_breakpoints
     68  1.1  christos 
     69  1.1  christos 		gdb_breakpoint [gdb_get_line_number "set breakpoint child here"]
     70  1.1  christos 		gdb_test "thread 2" "Switching to .*"
     71  1.1  christos 		gdb_continue_to_breakpoint "run to breakpoint in thread 2"
     72  1.3  christos 
     73  1.3  christos 		set address_triggers_watch "<invalid>"
     74  1.3  christos 		set after_address_triggers_watch "<invalid>"
     75  1.3  christos 
     76  1.3  christos 		# Let the watchpoint trigger once (with the other
     77  1.3  christos 		# thread locked), in order to find both the address of
     78  1.3  christos 		# the instruction that triggers the watchpoint and the
     79  1.3  christos 		# address of the instruction immediately after.
     80  1.3  christos 		with_test_prefix "find addresses" {
     81  1.3  christos 		    gdb_test "p watch_me = 0" " = 0" "clear watch_me"
     82  1.3  christos 		    gdb_test "watch watch_me" "Hardware watchpoint .*"
     83  1.3  christos 
     84  1.3  christos 		    gdb_test "continue" \
     85  1.3  christos 			"Hardware watchpoint.*: watch_me.*New value = 1.*" \
     86  1.3  christos 			"continue to watchpoint"
     87  1.3  christos 
     88  1.3  christos 		    set msg "find addresses"
     89  1.3  christos 		    gdb_test_multiple "disassemble" $msg {
     90  1.3  christos 			-re " ($hex) \[^\r\n\]*\r\n=> ($hex) .*$gdb_prompt $" {
     91  1.3  christos 			    set address_triggers_watch $expect_out(1,string)
     92  1.3  christos 			    set after_address_triggers_watch $expect_out(2,string)
     93  1.3  christos 			    pass $msg
     94  1.3  christos 			}
     95  1.3  christos 		    }
     96  1.3  christos 
     97  1.3  christos 		    delete_breakpoints
     98  1.3  christos 		}
     99  1.3  christos 
    100  1.3  christos 		gdb_test "break *$address_triggers_watch" "Breakpoint .*" \
    101  1.3  christos 		    "set breakpoint at address that triggers watch"
    102  1.3  christos 		gdb_continue_to_breakpoint \
    103  1.3  christos 		    "run to instruction that triggers watch in thread 2"
    104  1.3  christos 
    105  1.1  christos 		gdb_test "p counter = 0" " = 0" "unbreak loop in thread 2"
    106  1.1  christos 		gdb_test "p watch_me = 0" " = 0" "clear watch_me"
    107  1.1  christos 		gdb_test "watch watch_me" "Hardware watchpoint .*"
    108  1.1  christos 
    109  1.1  christos 		if ${with_bp} {
    110  1.3  christos 		    gdb_test "b *$after_address_triggers_watch thread 1" \
    111  1.3  christos 			"Breakpoint .*" \
    112  1.3  christos 			"set breakpoint specific to thread 1"
    113  1.1  christos 		}
    114  1.1  christos 
    115  1.1  christos 		# Switch back to thread 1 and disable scheduler locking.
    116  1.1  christos 		gdb_test "thread 1" "Switching to .*"
    117  1.1  christos 		gdb_test_no_output "set scheduler-locking off"
    118  1.1  christos 
    119  1.4  christos 		# Thread 2 is still stopped at a breakpoint that needs
    120  1.4  christos 		# to be stepped over.  However, the instruction that
    121  1.4  christos 		# is under the breakpoint triggers a watchpoint, which
    122  1.4  christos 		# should trap and be reported to the user.
    123  1.1  christos 		gdb_test "$command" "Hardware watchpoint.*: watch_me.*New value = 1.*"
    124  1.1  christos 	    }
    125  1.1  christos 	}
    126  1.1  christos     }
    127  1.1  christos }
    128  1.1  christos 
    129  1.3  christos foreach displaced { "off" "on" } {
    130  1.3  christos     if { $displaced != "off" && ![support_displaced_stepping] } {
    131  1.3  christos 	continue
    132  1.3  christos     }
    133  1.3  christos 
    134  1.3  christos     foreach with_bp { 0 1 } {
    135  1.3  christos 	do_test $displaced $with_bp
    136  1.3  christos     }
    137  1.3  christos }
    138