📄 schedlock.exp
字号:
# Copyright (C) 1996, 1997, 2002, 2003, 2007, 2008# 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/>.# Please email any bugs, comments, and/or additions to this file to:# bug-gdb@prep.ai.mit.edu# This file was written by Daniel Jacobowitz <drow@mvista.com># (parts based on pthreads.exp by Fred Fish (fnf@cygnus.com).## This test covers the various forms of "set scheduler-locking".if $tracelevel then { strace $tracelevel}set prms_id 0set bug_id 0set testfile "schedlock"set srcfile ${testfile}.cset binfile ${objdir}/${subdir}/${testfile}# The number of threads, including the main thread.set NUM 2if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } { return -1}# Now we can proceed with the real testing.proc get_args { } { global list_count global gdb_prompt send_gdb "print args\n" gdb_expect { -re "\\\$\[0-9\]+ = {(\[0-9\]+), (\[0-9\]+)}.*$gdb_prompt" { set list_count [expr $list_count + 1] pass "listed args ($list_count)" return [list $expect_out(1,string) $expect_out(2,string)] } -re "$gdb_prompt" { fail "listed args ($list_count) (unknown output)" } timeout { fail "listed args ($list_count) (timeout)" } }}proc stop_process { description } { global gdb_prompt # For this to work we must be sure to consume the "Continuing." # message first, or GDB's signal handler may not be in place. after 1000 {send_gdb "\003"} gdb_expect { -re "Program received signal SIGINT.*$gdb_prompt $" { pass $description } timeout { fail "$description (timeout)" } }}proc get_current_thread { description } { global gdb_prompt send_gdb "bt\n" gdb_expect { -re "thread_function \\(arg=0x(\[0-9\])\\).*$gdb_prompt $" { pass $description return $expect_out(1,string) } -re "$gdb_prompt $" { fail "$description (unknown output)" } timeout { fail "$description (timeout)" } }}proc my_continue { msg } { send_gdb "continue\n" gdb_expect { -re "Continuing" { pass "continue ($msg)" } timeout { fail "continue ($msg) (timeout)" } } stop_process "stop all threads ($msg)" # Make sure we're in one of the non-main looping threads. gdb_breakpoint [concat [gdb_get_line_number "schedlock.exp: main loop"] " if arg != 0"] gdb_continue_to_breakpoint "return to loop ($msg)" delete_breakpoints}proc step_ten_loops { msg } { global gdb_prompt for {set i 0} {[expr $i < 10]} {set i [expr $i + 1]} { send_gdb "step\n" set other_step 0 gdb_expect { -re ".*myp\\) \\+\\+;\[\r\n\]+$gdb_prompt $" { pass "step to increment ($msg $i)" } -re "$gdb_prompt $" { if {$other_step == 0} { set other_step 1 send_gdb "step\n" exp_continue } else { fail "step to increment ($msg $i)" # FIXME cascade? } } timeout { fail "step to increment ($msg $i) (timeout)" } } }}# Start with a fresh gdb.gdb_exitgdb_startgdb_reinitialize_dir $srcdir/$subdir# We'll need this when we send_gdb a ^C to GDB. Need to do it before we# run the program and gdb starts saving and restoring tty states.# On Ultrix, we don't need it and it is really slow (because shell_escape# doesn't use vfork).if ![istarget "*-*-ultrix*"] then { gdb_test "shell stty intr '^C'" ""}gdb_load ${binfile}gdb_test "set print sevenbit-strings" ""gdb_test "set width 0" ""runto_main# See if scheduler locking is available on this target.send_gdb "set scheduler-locking off\n"global gdb_promptgdb_expect { -re "Target .* cannot support this command" { unsupported "target does not support scheduler locking" return } -re "$gdb_prompt $" { pass "scheduler locking set to none" } timeout { unsupported "target does not support scheduler locking (timeout)" return }}gdb_breakpoint [gdb_get_line_number "schedlock.exp: last thread start"]gdb_continue_to_breakpoint "all threads started"global list_countset list_count 0set start_args [get_args]# First make sure that all threads are alive.my_continue "initial"set cont_args [get_args]set ok 1for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} { if {[lindex $start_args $i] == [lindex $cont_args $i]} { set ok 0 }}if { $ok } { pass "all threads alive"} else { fail "all threads alive"}# We can't change threads, unfortunately, in current GDB. Use# whichever we stopped in.set curthread [get_current_thread "find current thread (1)"]# Test stepping without scheduler locking.gdb_test "set scheduler-locking off" ""step_ten_loops "unlocked"# Make sure we're still in the same thread.set newthread [get_current_thread "find current thread (2)"]if {$curthread == $newthread} { pass "step without lock does not change thread"} else { fail "step without lock does not change thread (switched to thread $newthread)"}set start_args $cont_argsset cont_args [get_args]set num_other_threads 0for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} { if {[lindex $start_args $i] == [lindex $cont_args $i]} { if {$i == $curthread} { fail "current thread stepped (didn't run)" } } else { if {$i == $curthread} { if {[lindex $start_args $i] == [expr [lindex $cont_args $i] - 10]} { pass "current thread stepped" } else { fail "current thread stepped (wrong amount)" } } else { set num_other_threads [expr $num_other_threads + 1] } }}if {$num_other_threads > 0} { pass "other threads ran - unlocked"} else { fail "other threads ran - unlocked"}# Test continue with scheduler lockinggdb_test "set scheduler-locking on" ""my_continue "with lock"# Make sure we're still in the same thread.set newthread [get_current_thread "find current thread (3)"]if {$curthread == $newthread} { pass "continue with lock does not change thread"} else { fail "continue with lock does not change thread (switched to thread $newthread)"}set start_args $cont_argsset cont_args [get_args]set num_other_threads 0for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} { if {[lindex $start_args $i] == [lindex $cont_args $i]} { if {$i == $curthread} { fail "current thread ran (didn't run)" } } else { if {$i == $curthread} { pass "current thread ran" } else { incr num_other_threads } }}if {$num_other_threads > 0} { fail "other threads didn't run - locked"} else { pass "other threads didn't run - locked"}# Test stepping with scheduler lockingstep_ten_loops "locked"# Make sure we're still in the same thread.set newthread [get_current_thread "find current thread (2)"]if {$curthread == $newthread} { pass "step with lock does not change thread"} else { fail "step with lock does not change thread (switched to thread $newthread)"}set start_args $cont_argsset cont_args [get_args]set num_other_threads 0for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} { if {[lindex $start_args $i] == [lindex $cont_args $i]} { if {$i == $curthread} { fail "current thread stepped locked (didn't run)" } } else { if {$i == $curthread} { if {[lindex $start_args $i] == [expr [lindex $cont_args $i] - 10]} { pass "current thread stepped locked" } else { fail "current thread stepped locked (wrong amount)" } } else { incr num_other_threads } }}if {$num_other_threads > 0} { fail "other threads didn't run - step locked"} else { pass "other threads didn't run - step locked"}return 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -