diff options
author | Daniel Jacobowitz <drow@false.org> | 2007-10-01 00:17:58 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2007-10-01 00:17:58 +0000 |
commit | d983da9c3dfa91e6840fee2a7479d98ee4759f13 (patch) | |
tree | 9a1c14b44f1a2de2d2c087b00d987deb2fe8274d /gdb/testsuite | |
parent | d830e0e0c9d4b1827385c473cb545e07a72c9b81 (diff) | |
download | gdb-d983da9c3dfa91e6840fee2a7479d98ee4759f13.zip gdb-d983da9c3dfa91e6840fee2a7479d98ee4759f13.tar.gz gdb-d983da9c3dfa91e6840fee2a7479d98ee4759f13.tar.bz2 |
2007-09-16 Daniel Jacobowitz <dan@codesourcery.com>
Jeff Johnston <jjohnstn@redhat.com>
* breakpoint.c (watchpoints_triggered): New.
(bpstat_stop_status): Remove STOPPED_BY_WATCHPOINT argument.
Check watchpoint_triggered instead. Combine handling for software
and hardware watchpoints. Do not use target_stopped_data_address
here. Always check a watchpoint if its scope breakpoint triggers.
Do not stop for thread or overlay events. Improve check for
triggered watchpoints without a value change.
(watch_command_1): Insert the scope breakpoint first. Link the
scope breakpoint to the watchpoint.
* breakpoint.h (enum watchpoint_triggered): New.
(struct breakpoint): Add watchpoint_triggered.
(bpstat_stop_status): Update prototype.
(watchpoints_triggered): Declare.
* infrun.c (enum infwait_status): Add infwait_step_watch_state.
(stepped_after_stopped_by_watchpoint): Delete.
(handle_inferior_event): Make stepped_after_stopped_by_watchpoint
local. Handle infwait_step_watch_state. Update calls to
bpstat_stop_status. Use watchpoints_triggered to check
watchpoints.
* remote.c (stepped_after_stopped_by_watchpoint): Remove extern.
(remote_stopped_data_address): Do not check it.
* gdb.texinfo (Setting Watchpoints): Adjust warning text about
multi-threaded watchpoints.
* gdbint.texinfo (Watchpoints): Describe how watchpoints are
checked. Describe sticky notification. Expand description
of steppable and continuable watchpoints.
(Watchpoints and Threads): New subsection.
* gdb.threads/watchthreads.c (thread_function): Sleep between
iterations.
* gdb.threads/watchthreads.exp: Allow two watchpoints to trigger
at once for S/390. Generate matching fails and passes.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/watchthreads.c | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/watchthreads.exp | 67 |
3 files changed, 66 insertions, 10 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index e5212be..f4882ef 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2007-09-30 Daniel Jacobowitz <dan@codesourcery.com> + + * gdb.threads/watchthreads.c (thread_function): Sleep between + iterations. + * gdb.threads/watchthreads.exp: Allow two watchpoints to trigger + at once for S/390. Generate matching fails and passes. + 2007-09-27 Vladimir Prus <vladimir@codesourcery.com> * gdb.mi/var-cmd.c (do_children_tests): Initialize diff --git a/gdb/testsuite/gdb.threads/watchthreads.c b/gdb/testsuite/gdb.threads/watchthreads.c index c607429..ef391f0 100644 --- a/gdb/testsuite/gdb.threads/watchthreads.c +++ b/gdb/testsuite/gdb.threads/watchthreads.c @@ -56,7 +56,7 @@ void *thread_function(void *arg) { /* Don't run forever. Run just short of it :) */ while (*myp > 0) { - (*myp) ++; /* Loop increment. */ + (*myp) ++; usleep (1); /* Loop increment. */ } pthread_exit(NULL); diff --git a/gdb/testsuite/gdb.threads/watchthreads.exp b/gdb/testsuite/gdb.threads/watchthreads.exp index cdd3edb..11fc2af 100644 --- a/gdb/testsuite/gdb.threads/watchthreads.exp +++ b/gdb/testsuite/gdb.threads/watchthreads.exp @@ -30,6 +30,10 @@ if [target_info exists gdb,no_hardware_watchpoints] { return 0; } +proc target_no_stopped_data { } { + return [istarget s390*-*-*] +} + set testfile "watchthreads" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} @@ -61,20 +65,58 @@ gdb_test "watch args\[1\]" "Hardware watchpoint 3: args\\\[1\\\]" set init_line [expr [gdb_get_line_number "Init value"]+1] set inc_line [gdb_get_line_number "Loop increment"] +set main_loc "main \\\(\\\) at .*watchthreads.c:$init_line" +set thread0_loc "thread_function \\\(arg=0x0\\\) at .*watchthreads.c:$inc_line" +set thread1_loc "thread_function \\\(arg=0x1\\\) at .*watchthreads.c:$inc_line" # Loop and continue to allow both watchpoints to be triggered. for {set i 0} {$i < 30} {incr i} { + set test_flag_0 0 + set test_flag_1 0 set test_flag 0 gdb_test_multiple "continue" "threaded watch loop" { - -re "Hardware watchpoint 2: args\\\[0\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*watchthreads.c:$init_line.*$gdb_prompt $" - { set args_0 1; set test_flag 1 } - -re "Hardware watchpoint 3: args\\\[1\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*watchthreads.c:$init_line.*$gdb_prompt $" - { set args_1 1; set test_flag 1 } - -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 $" - { set args_0 [expr $args_0+1]; set test_flag 1 } - -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 $" - { set args_1 [expr $args_1+1]; set test_flag 1 } + -re "(.*Hardware watchpoint.*)$gdb_prompt $" { + # At least one hardware watchpoint was hit. Check if both were. + set string $expect_out(1,string) + + if [regexp "Hardware watchpoint 2: args\\\[0\\\]\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $args_0\[^\r\]*\r\[^\r\]*New value = [expr $args_0+1]\r" $string] { + incr args_0 + incr test_flag_0 + } + if [regexp "Hardware watchpoint 3: args\\\[1\\\]\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $args_1\[^\r\]*\r\[^\r\]*New value = [expr $args_1+1]\r" $string] { + incr args_1 + incr test_flag_1 + } + + set expected_loc "bogus location" + if { $test_flag_0 == 1 && $test_flag_1 == 0 && $args_0 == 1 } { + set expected_loc $main_loc + } elseif { $test_flag_0 == 0 && $test_flag_1 == 1 && $args_1 == 1 } { + set expected_loc $main_loc + } elseif { $test_flag_0 == 1 && $test_flag_1 == 0 } { + set expected_loc $thread0_loc + } elseif { $test_flag_0 == 0 && $test_flag_1 == 1 } { + set expected_loc $thread1_loc + } elseif { $test_flag_0 + $test_flag_1 == 2 } { + # On S/390, or any other system which can not report the + # stopped data address, it is OK to report two watchpoints + # at once in this test. Make sure the reported location + # corresponds to at least one of the watchpoints (and not, + # e.g., __nptl_create_event). On other systems, we should + # report the two watchpoints serially. + if { [target_no_stopped_data] } { + set expected_loc "($main_loc|$thread0_loc|$thread1_loc)" + } + } + + if [ regexp "$expected_loc" $string ] { + set test_flag 1 + } else { + fail "threaded watch loop" + } + } } + # If we fail above, don't bother continuing loop if { $test_flag == 0 } { set i 30; @@ -120,7 +162,14 @@ if { $args_1 > 1 } { # Verify that all watchpoint hits are accounted for. set message "combination of threaded watchpoints = 30" -if { [expr $args_0+$args_1] == 30 } { +if { [target_no_stopped_data] } { + # See above. If we allow two watchpoints to be hit at once, we + # may have more than 30 hits total. + set result [expr $args_0 + $args_1 >= 30] +} else { + set result [expr $args_0 + $args_1 == 30] +} +if { $result } { pass $message } else { fail $message |