810 lines
22 KiB
Plaintext
810 lines
22 KiB
Plaintext
# quicksort.exp -- Expect script to test gdb with quicksort.c
|
|
# Copyright (C) 1992 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
|
|
|
|
# use this to debug:
|
|
#
|
|
#log_user 1
|
|
|
|
if $tracelevel then {
|
|
strace $tracelevel
|
|
}
|
|
|
|
if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
|
|
verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
|
|
return 0
|
|
}
|
|
|
|
set testfile quicksort
|
|
set srcfile ${srcdir}/${subdir}/${testfile}.c
|
|
set binfile ${objdir}/${subdir}/${testfile}
|
|
|
|
if [get_compiler_info ${binfile}] {
|
|
return -1
|
|
}
|
|
|
|
# To build the executable we need to link against the thread library.
|
|
#
|
|
# cc -Ae -g -o quicksort -lpthread quicksort.c
|
|
#
|
|
#compile "${srcfile} -Ae -g -lpthread -o ${binfile}"
|
|
|
|
if {$gcc_compiled == 0} {
|
|
set additional_flags "additional_flags=-Ae"
|
|
} else {
|
|
set additional_flags ""
|
|
}
|
|
|
|
if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}.o" object [list debug $additional_flags]] != "" } {
|
|
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
|
}
|
|
remote_exec build "ld /usr/ccs/lib/crt0.o ${binfile}.o -lcl -lpthread -lc /opt/langtools/lib/end.o -o ${binfile}"
|
|
|
|
|
|
# Thread stuff is _slow_; prepare for long waits.
|
|
#
|
|
set oldtimeout $timeout
|
|
set timeout [expr "$timeout + 300"]
|
|
set oldverbose $verbose
|
|
#set verbose 40
|
|
|
|
# Further, this test has some "null" lines designed
|
|
# to consume output from gdb that was too late to be
|
|
# matched (sequence is "gdb_test" sends; timeout and
|
|
# on to next send; result finally comes in; mismatch).
|
|
#
|
|
# The null command is 'gdb_test "p \$pc" ".*" ""'
|
|
#
|
|
# NOTE: to pass a literal "$", "/" or "*" (etc.) to gdb_test,
|
|
# remember that the pattern will be escaped once and
|
|
# $-evaluated twice:
|
|
#
|
|
# "\\\*" matches "\*"
|
|
# "\$" matches "$"
|
|
#
|
|
proc fix_timeout {} {
|
|
gdb_test "p \$pc" ".*" ""
|
|
}
|
|
|
|
#=========================
|
|
#
|
|
# Simple sanity test first.
|
|
#
|
|
gdb_exit
|
|
gdb_start
|
|
gdb_reinitialize_dir $srcdir/$subdir
|
|
gdb_load ${binfile}
|
|
|
|
gdb_test "tb 122" ".*Breakpoint.*" ""
|
|
gdb_test "r" ".*122.*" ""
|
|
gdb_test "thr 99" ".*Thread ID 99 not known.*" "Check too-big thread number"
|
|
gdb_test "tb 145 thr 3" ".*Breakpoint.*" "set thread-specific bp 145"
|
|
gdb_test "tb 146 thr 4" ".*Breakpoint.*" "set thread-specific bp 146"
|
|
gdb_test "c" ".*Switched to thread.*145.*" "auto switch"
|
|
gdb_test "c" ".*Switched to thread.*146.*" "auto switch 2"
|
|
gdb_test "c" ".*Program exited normally.*" ""
|
|
|
|
#=========================
|
|
#
|
|
# Test that you can't do a thread select after a program runs.
|
|
#
|
|
gdb_test "thread" ".*No stack.*" "No live thread after run"
|
|
gdb_test "thr 2" ".*No stack.*" "Can't set thread after run"
|
|
|
|
#=========================
|
|
#
|
|
# Test thread command changes, look for frame level reset bug.
|
|
#
|
|
gdb_exit
|
|
gdb_start
|
|
gdb_reinitialize_dir $srcdir/$subdir
|
|
gdb_load ${binfile}
|
|
gdb_test "b 122" ".*" ""
|
|
gdb_test "r" ".*122.*" ""
|
|
|
|
# Prep for frame level test--go up/info thread/check frame
|
|
#
|
|
gdb_test "up" ".*quick_sort.*" ""
|
|
gdb_test "up" ".*main.*" ""
|
|
|
|
send_gdb "i th\n"
|
|
gdb_expect {
|
|
-re ".*7 thread.* in .* from .* in .* from .* 6 thread.*$gdb_prompt $" {
|
|
fail "old thread command, says things twice"
|
|
}
|
|
-re ".*7 system thread.*6 system th.*5 sys.*4.*3.*2.*1.*work_init.*$gdb_prompt $" {
|
|
pass "info threads"
|
|
}
|
|
-re ".*$gdb_prompt $" { fail "no info thread command" }
|
|
timeout { fail "timeout" }
|
|
}
|
|
|
|
# We should have been restored two frames up--check.
|
|
#
|
|
send_gdb "up\n"
|
|
gdb_expect {
|
|
-re ".*Initial frame selected.*$gdb_prompt $" {
|
|
pass "Frame correctly reset after 'info threads'"
|
|
}
|
|
-re ".*quick_sort.*$gdb_prompt $" {
|
|
fail "Old gdb bug; should be fixed someday"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "real bug--FIX!"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
|
|
# Do it again, only just go to a middle frame, and use another thread.
|
|
#
|
|
gdb_test "thr 5" ".*" ""
|
|
gdb_test "bt" ".* ___ksleep.*_lwp_cond_timedwait.*pthread_cond_wait.*worker.*__pthread_create_system.*" ""
|
|
gdb_test "up" ".*1.*_lwp_cond_timedwait.*" ""
|
|
gdb_test "up" ".*2.*pthread_cond_wait.*" ""
|
|
gdb_test "up" ".*3.*worker.*" ""
|
|
gdb_test "i th" ".*7.*6.*work_init.*" ""
|
|
gdb_test "f" ".*3.*worker.*" "Frame restored"
|
|
gdb_test "p wp->max_pile" ".*= 128.*" "can see vars in frame"
|
|
|
|
# Thread command changes
|
|
#
|
|
gdb_test "thr" ".*Current thread is 5.*" "threads-no-num"
|
|
gdb_test "thr 6" ".*Switching to thread 6.*" "new switch"
|
|
gdb_test "thr" ".*Current thread is 6.*" "check switch"
|
|
#gdb_test "thr 6" ".*Current thread is already 6.*" "dup, no switch"
|
|
gdb_test "thr app all p x" ".*No symbol.*" ""
|
|
gdb_test "thr" ".*Current thread is 6.*" "restore current thread"
|
|
|
|
#=========================
|
|
#
|
|
# Test new stepping
|
|
#
|
|
|
|
proc get_hit { } {
|
|
global hit2
|
|
global hit3
|
|
global hit4
|
|
global hit5
|
|
global hit6
|
|
global hit7
|
|
global gdb_prompt
|
|
|
|
send_gdb "cont\n"
|
|
gdb_expect {
|
|
-re ".*Breakpoint.*145.*$gdb_prompt $" {
|
|
send_gdb "thr\n"
|
|
gdb_expect {
|
|
-re ".*is 7.*$gdb_prompt $" {
|
|
set hit7 [expr "$hit7 + 1"]
|
|
}
|
|
-re ".*is 6.*$gdb_prompt $" {
|
|
set hit6 [expr "$hit6 + 1"]
|
|
}
|
|
-re ".*is 5.*$gdb_prompt $" {
|
|
set hit5 [expr "$hit5 + 1"]
|
|
}
|
|
-re ".*is 4.*$gdb_prompt $" {
|
|
set hit4 [expr "$hit4 + 1"]
|
|
}
|
|
-re ".*is 3.*$gdb_prompt $" {
|
|
set hit3 [expr "$hit3 + 1"]
|
|
}
|
|
-re ".*is 2.*$gdb_prompt $" {
|
|
set hit2 [expr "$hit2 + 1"]
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "can't see which thread"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "thread command"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
}
|
|
|
|
gdb_exit
|
|
gdb_start
|
|
gdb_reinitialize_dir $srcdir/$subdir
|
|
gdb_load ${binfile}
|
|
gdb_test "break 122" ".*" ""
|
|
gdb_test "run" ".*122.*" ""
|
|
|
|
# Make sure we hit a bp on every thread.
|
|
#
|
|
# Try one, via thread-specific bps
|
|
#
|
|
gdb_test "break 145 thr 2" ".*" "set thread-specific bp thr 2"
|
|
gdb_test "break 145 thr 3" ".*" "set thread-specific bp thr 3"
|
|
gdb_test "break 145 thr 4" ".*" "set thread-specific bp thr 4"
|
|
gdb_test "break 145 thr 5" ".*" "set thread-specific bp thr 5"
|
|
gdb_test "break 145 thr 6" ".*" "set thread-specific bp thr 6"
|
|
gdb_test "break 145 thr 7" ".*" "set thread-specific bp thr 7"
|
|
|
|
set hit2 0
|
|
set hit3 0
|
|
set hit4 0
|
|
set hit5 0
|
|
set hit6 0
|
|
set hit7 0
|
|
|
|
get_hit
|
|
get_hit
|
|
get_hit
|
|
get_hit
|
|
get_hit
|
|
get_hit
|
|
|
|
if { [expr "$hit2 == 1"]
|
|
&& [expr "$hit3 == 1"]
|
|
&& [expr "$hit4 == 1"]
|
|
&& [expr "$hit5 == 1"]
|
|
&& [expr "$hit6 == 1"]
|
|
&& [expr "$hit7 == 1"] } {
|
|
pass "thread-specific bps 1"
|
|
} else {
|
|
fail "thread-specific bps 1"
|
|
}
|
|
|
|
#====================
|
|
#
|
|
# Now use generic bps
|
|
#
|
|
gdb_exit
|
|
gdb_start
|
|
gdb_reinitialize_dir $srcdir/$subdir
|
|
gdb_load ${binfile}
|
|
gdb_test "b 122" ".*" ""
|
|
gdb_test "r" ".*122.*" ""
|
|
|
|
# Make sure we hit a bp on every thread.
|
|
#
|
|
# Try two, via non-thread-specific bp
|
|
#
|
|
gdb_test "b 145" ".*" "b 145"
|
|
|
|
set hit2 0
|
|
set hit3 0
|
|
set hit4 0
|
|
set hit5 0
|
|
set hit6 0
|
|
set hit7 0
|
|
|
|
get_hit
|
|
get_hit
|
|
get_hit
|
|
get_hit
|
|
get_hit
|
|
get_hit
|
|
|
|
if { [expr "$hit2 == 1"]
|
|
&& [expr "$hit3 == 1"]
|
|
&& [expr "$hit4 == 1"]
|
|
&& [expr "$hit5 == 1"]
|
|
&& [expr "$hit6 == 1"]
|
|
&& [expr "$hit7 == 1"] } {
|
|
pass "thread-specific bps 2"
|
|
} else {
|
|
fail "thread-specific bps 2"
|
|
}
|
|
|
|
#====================
|
|
#
|
|
# Complicated (original) test next.
|
|
#
|
|
gdb_exit
|
|
gdb_start
|
|
gdb_reinitialize_dir $srcdir/$subdir
|
|
gdb_load ${binfile}
|
|
|
|
if ![runto_main] then {
|
|
fail "Can't run to main"
|
|
return 0
|
|
}
|
|
|
|
# OK, we're at "main", there should be one thread.
|
|
#
|
|
gdb_test "info thread" ".*\\\* 1 system thread .*main.*" "initial thread"
|
|
|
|
# Try to see the threads being created: set a breakpoint
|
|
# after the creation and go around the loop a few times.
|
|
#
|
|
gdb_test "break 109" "Breakpoint.*109.*" "set bpt"
|
|
|
|
gdb_test "c" ".*New thread.*Breakpoint.*109.*" "first continue"
|
|
fix_timeout
|
|
|
|
# Make sure we don't wait (waiting is for attach test)
|
|
#
|
|
gdb_test "set wait_here = 0" ".*" ""
|
|
|
|
send_gdb "info thr\n"
|
|
gdb_expect {
|
|
-re ".*2 system th.*1 sy.*109.*$gdb_prompt $" { pass "saw thread create" }
|
|
-re ".*1 system thread.*87.*$gdb_prompt $" { fail "didn't see thread create" }
|
|
-re ".*$gdb_prompt $" { fail "no info thread command" }
|
|
timeout { fail "timeout" }
|
|
}
|
|
|
|
gdb_test "c" ".*New thread.*Breakpoint.*109.*" "continue"
|
|
fix_timeout
|
|
|
|
send_gdb "info thr\n"
|
|
gdb_expect {
|
|
-re ".*3 system thread.*2 sys.*\\\* 1 system thread.*109.*$gdb_prompt $" {
|
|
pass "saw thread create" }
|
|
-re ".*2 system thread.*1 sys.*109.*$gdb_prompt $" {
|
|
fail "didn't see thread create"
|
|
}
|
|
-re ".*1 system thread.*109.*$gdb_prompt $" {
|
|
fail "didn't see thread create"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "no info thread command"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
|
|
fix_timeout
|
|
gdb_test "clear" ".*Deleted breakpoint.*" ""
|
|
|
|
# Now go on to the end of thread creation.
|
|
#
|
|
gdb_test "b 122" ".*" "set bpt 122"
|
|
gdb_test "c" ".*New thread.*New thread.*New thread.*122.*" ""
|
|
gdb_test "p \$pc" ".*" ""
|
|
gdb_test "clear" ".*Deleted breakpoint.*" ""
|
|
|
|
send_gdb "info thr\n"
|
|
gdb_expect {
|
|
-re ".*7 system thread.*6 sys.*5.*1 system thread.*122.*$gdb_prompt $"
|
|
{ pass "saw thread creates" }
|
|
-re ".*$gdb_prompt $"
|
|
{ fail "no info thread command" }
|
|
timeout { fail "timeout" }
|
|
}
|
|
|
|
# Try a thread-specific breakpoint; we expect the other threads to
|
|
# be waiting at this point.
|
|
#
|
|
gdb_test "thr 3" ".*Switching to thread.*ksleep.*" "thread switch"
|
|
gdb_test "i th" ".*\\\* 3 system thread.*" "show new current thread"
|
|
|
|
gdb_test "up" ".*lwp_cond_timedwait.*" ""
|
|
gdb_test "up" ".*pthread_cond_wait.*" ""
|
|
gdb_test "up" ".*worker.*144.*" ""
|
|
|
|
gdb_test "b 145 th 3" ".*Breakpoint.*145.*" "set thread-specific bp"
|
|
gdb_test "i b" ".*breakpoint.*breakpoint.*145 thread 3.*" "show thread-specific bp"
|
|
|
|
gdb_test "c" ".*Breakpoint.*145.*145.*" "hit thread-specific bp"
|
|
gdb_test "p \$pc" ".*" ""
|
|
|
|
# Test thread apply command on thread specific data.
|
|
#
|
|
gdb_test "thre app all p \$pc" ".*Thread 7.*Thread 6.*Thread 5.*Thread 4.*Thread 3.*Thread 2.*Thread 1.*" "thread apply all"
|
|
gdb_test "thr ap 1 3 5 p \$pc" ".*Thread 1.*Thread 3.*Thread 5.*" "thr app 1 3 5"
|
|
|
|
# Switch again, and test that others continue on a "next"
|
|
# This test _could_ fail due to timing issues, but that's
|
|
# unlikely.
|
|
#
|
|
gdb_test "thr 7" ".*Switching to thread.*" ""
|
|
|
|
# Make sure that "up" stops at __pthread_exit, or
|
|
# __pthread_create, the pseudo-roots, and that we
|
|
# only see that pseudo-root once.
|
|
#
|
|
send_gdb "bt\n"
|
|
gdb_expect {
|
|
-re ".*Error accessing memory address.*" { fail "bt" }
|
|
-re ".*pthread_create.*pthread_create.*" { fail "bt" }
|
|
-re ".*worker.*pthread_create.*" { pass "bt" }
|
|
-re ".*pthread_exit.*" { pass "bt" }
|
|
timeout { fail "timeout on bt" }
|
|
}
|
|
|
|
gdb_test "up" ".*" ""
|
|
gdb_test "up" ".*" ""
|
|
gdb_test "up" ".*144.*" "Up 3"
|
|
gdb_test "up" ".*pthread_.*" "Up 4"
|
|
gdb_test "up" ".*Initial frame selected; you cannot go up.*" "catch end of thread stack"
|
|
|
|
#=====================
|
|
#
|
|
# Things get iffy here; when we step, sometimes the step
|
|
# completes, sometimes it doesn't. When it doesn't, we
|
|
# hit a bp somewhere else and the step never completes
|
|
# (wait_for_inferior just evaporates it).
|
|
#
|
|
# I think the right answer is that any failures here
|
|
# should stick around to trigger later fixing.
|
|
#
|
|
# Here's the plan:
|
|
#
|
|
# Bps at 148 (5) and 154 (6) on thread 7 (two bps so we
|
|
# see the difference between going around the loop and
|
|
# reporting the same bp hit twice).
|
|
#
|
|
# Bp at 144 on thread 3.
|
|
#
|
|
# Step out of a library routine.
|
|
#
|
|
# Either the step will finish or a bp will hit. Try to
|
|
# handle all the cases.
|
|
#
|
|
gdb_test "b 148 thr 7" ".*Breakpoint.*148.*" ""
|
|
gdb_test "b 154 thr 7" ".*Breakpoint.*154.*" "set bpt 2"
|
|
|
|
set hit_154_bp 0
|
|
set hit_148_bp 0
|
|
set hit_145_bp 0
|
|
set step_completed 0
|
|
|
|
# Expect zero hits
|
|
#
|
|
gdb_test "i b" ".*" ""
|
|
|
|
send_gdb "n\n"
|
|
gdb_expect {
|
|
-re ".*Single stepping.*_lwp_cond_timedwait.*$gdb_prompt $" {
|
|
send_gdb "thr\n"
|
|
gdb_expect {
|
|
-re ".*is 7.*$gdb_prompt $" {
|
|
set step_completed 1
|
|
pass "completed step in library code"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "completed step in library code, but in wrong thread"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
}
|
|
-re ".*Single stepping.*Switched to thread 3.*Breakpoint.*$gdb_prompt $" {
|
|
pass "step cancelled; hit bp due to thread parallelism"
|
|
set hit_145_bp 1
|
|
}
|
|
-re ".*Single stepping.*Switched to thread 7.*Breakpoint.*148.*$gdb_prompt $" {
|
|
pass "step cancelled; hit bp due to thread parallelism"
|
|
set hit_148_bp 1
|
|
}
|
|
-re ".*Single stepping.*Switched to thread 7.*Breakpoint.*154.*$gdb_prompt $" {
|
|
pass "step cancelled; hit bp due to thread parallelism"
|
|
set hit_154_bp 1
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
send_gdb "thr\n"
|
|
gdb_expect {
|
|
-re ".*is 7.*$gdb_prompt $" {
|
|
fail "No event?"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "No event"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
|
|
# Sometimes used to get SIGTRAP here; that should be fixed
|
|
#
|
|
|
|
# Expect appropriate hits of bpt; too much work to parse
|
|
# result and check...
|
|
#
|
|
gdb_test "i b" ".*" ""
|
|
|
|
send_gdb "c\n"
|
|
gdb_expect {
|
|
-re ".*SIGTRAP.*$gdb_prompt $" {
|
|
fail "got SIGTRAP"
|
|
}
|
|
-re ".*Switched to thread 7.*Breakpoint.*154.*$gdb_prompt $" {
|
|
if { $hit_154_bp == 1 } {
|
|
fail "re-hit old bp"
|
|
} else {
|
|
pass "continue; hit parallel event after continue"
|
|
}
|
|
set hit_154_bp 1
|
|
}
|
|
-re ".*Switched to thread 7.*Breakpoint.*148.*$gdb_prompt $" {
|
|
if { $hit_148_bp == 1 } {
|
|
fail "re-hit old bp"
|
|
} else {
|
|
pass "continue; hit parallel event after continue"
|
|
}
|
|
set hit_148_bp 1
|
|
}
|
|
-re ".*Breakpoint.*154.*$gdb_prompt $" {
|
|
if { $hit_154_bp == 1 } {
|
|
fail "re-hit old bp"
|
|
} else {
|
|
send_gdb "thr\n"
|
|
gdb_expect {
|
|
-re ".*is 7.*$gdb_prompt $" {
|
|
pass "continue; hit parallel event after continue"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "hit bp in wrong thread"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
}
|
|
set hit_154_bp 1
|
|
}
|
|
-re ".*Breakpoint.*148.*$gdb_prompt $" {
|
|
if { $hit_148_bp == 1 } {
|
|
fail "re-hit old bp"
|
|
} else {
|
|
send_gdb "thr\n"
|
|
gdb_expect {
|
|
-re ".*is 7.*$gdb_prompt $" {
|
|
pass "continue; hit parallel event after continue"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "hit bp in wrong thread"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
}
|
|
set hit_148_bp 1
|
|
}
|
|
-re ".*Breakpoint.*145.*$gdb_prompt $" {
|
|
if { $hit_145_bp == 1 } {
|
|
fail "re-hit old bp"
|
|
} else {
|
|
send_gdb "thr\n"
|
|
gdb_expect {
|
|
-re ".*is 3.*$gdb_prompt $" {
|
|
pass "continue; hit parallel event after continue"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "hit bp in wrong thread"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
}
|
|
set hit_145_bp 1
|
|
}
|
|
-re ".*_lwp_cond_timedwait.*$gdb_prompt $" {
|
|
pass "continue; hit step completion after continue"
|
|
}
|
|
-re ".*Program exited normally.*" {
|
|
fail "Program ended? HOW?"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "Unexpected event"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
|
|
# There are a number of places we _could_ be now;
|
|
# this is the price of really running in parallel.
|
|
#
|
|
send_gdb "n\n"
|
|
gdb_expect {
|
|
-re ".*Switched to thread 7.*pthread_cond_wait.*$gdb_prompt $" {
|
|
if { $step_completed } {
|
|
fail "step already completed"
|
|
} else {
|
|
pass "finish step"
|
|
}
|
|
}
|
|
-re ".*pthread_cond_wait.*$gdb_prompt $" {
|
|
#
|
|
# Unlikely, but we might finish the range step from inside
|
|
# ksleep, before anything else.
|
|
#
|
|
if { $step_completed } {
|
|
fail "step already completed"
|
|
} else {
|
|
send_gdb "thr\n"
|
|
gdb_expect {
|
|
-re ".*is 7.*$gdb_prompt $" {
|
|
pass "finish step"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "step in wrong thread"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
}
|
|
}
|
|
-re ".*Switched to thread.*Breakpoint.*145.*$gdb_prompt $" {
|
|
pass "auto-switch thread"
|
|
}
|
|
-re ".*Breakpoint.*145.*$gdb_prompt $" {
|
|
pass "auto-switch not needed, ok"
|
|
}
|
|
-re ".*140.*while.*n_pile.*$gdb_prompt $" {
|
|
#
|
|
# This is just going around the loop from the 154 bp.
|
|
#
|
|
send_gdb "thr\n"
|
|
gdb_expect {
|
|
-re ".*is 7.*$gdb_prompt $" {
|
|
pass "finish step"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "step in wrong thread"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
}
|
|
-re ".*149.*ptr = wp.*pile.*$gdb_prompt $" {
|
|
#
|
|
# This is just going around the loop from the 148 bp.
|
|
#
|
|
if { $hit_154_bp } {
|
|
send_gdb "thr\n"
|
|
gdb_expect {
|
|
-re ".*is 7.*$gdb_prompt $" {
|
|
pass "finish step"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "step in wrong thread"
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
} else {
|
|
pass "step from 149 but didn't hit it first"
|
|
}
|
|
}
|
|
-re ".*Breakpoint 5.*154.*$gdb_prompt $" {
|
|
gdb_test "i b" ".*" ""
|
|
if { $hit_154_bp } {
|
|
fail "hit bp again?"
|
|
} else {
|
|
pass "hit bp"
|
|
}
|
|
}
|
|
-re ".*Breakpoint 5.*148.*$gdb_prompt $" {
|
|
gdb_test "i b" ".*" ""
|
|
if { $hit_148_bp } {
|
|
fail "hit bp again?"
|
|
} else {
|
|
pass "hit bp"
|
|
}
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "no step finished"
|
|
}
|
|
timeout { fail "timeout on 'next'" }
|
|
}
|
|
|
|
# Let's get into some kind of known state again.
|
|
#
|
|
gdb_test "thr 7" ".*" ""
|
|
gdb_test "info thread" ".*" ""
|
|
#gdb_test "i b" ".*" ""
|
|
|
|
# Leave breakpoint "154 thr 7" as only live bp.
|
|
#
|
|
gdb_test "d 1" ".*" "del main bp"
|
|
gdb_test "d 4" ".*" "thread-specific bpt delete"
|
|
gdb_test "d 5" ".*" "other bp delete"
|
|
send_gdb "i b\n"
|
|
gdb_expect {
|
|
-re ".*breakpoint.*breakpoint.*$gdb_prompt $" {
|
|
fail "more than one bp left"
|
|
}
|
|
-re ".*breakpoint.*154.*thread.*7.*$gdb_prompt $" {
|
|
pass "Only one bp left"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "Wrong or no bp left"
|
|
}
|
|
timeout { fail "timeout on info b" }
|
|
}
|
|
|
|
send_gdb "c\n"
|
|
gdb_expect {
|
|
-re ".*SIGTRAP.*Switched to thread.*$gdb_prompt $" {
|
|
fail "SIGTRAP error; lost thread-specific bpt"
|
|
}
|
|
-re ".*SIGTRAP.*Switched to thread.*154.*$gdb_prompt $" {
|
|
fail "SIGTRAP, but hit right thread-specific bpt"
|
|
}
|
|
-re ".*Switched to thread.*Breakpoint.*154.*$gdb_prompt $" {
|
|
pass "auto-switch back"
|
|
}
|
|
-re ".*Breakpoint.*154.*$gdb_prompt $" {
|
|
pass "step to bp"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "auto-switch back"
|
|
}
|
|
-re ".*Program exited normally.*$gdb_prompt $" {
|
|
fail "step lost"
|
|
}
|
|
timeout {
|
|
fail "timeout"
|
|
}
|
|
}
|
|
fix_timeout
|
|
|
|
gdb_test "cle" ".*Deleted breakpoint.*" "delete last breakpoint"
|
|
|
|
# Sometimes get SIGTRAP here. Continue sometimes gets another...
|
|
#
|
|
send_gdb "c\n"
|
|
gdb_expect {
|
|
-re ".*SIGTRAP.*154.*154.*$gdb_prompt $" {
|
|
fail "SIGTRAP on deleted bp 154 "
|
|
send_gdb "c\n"
|
|
gdb_expect {
|
|
-re ".*$gdb_prompt $" { pass "fixup"}
|
|
timeout { fail "fixup" }
|
|
}
|
|
}
|
|
-re ".*SIGTRAP.*144.*145.*$gdb_prompt $" {
|
|
fail "SIGTRAP on deleted bp 145 "
|
|
send_gdb "c\n"
|
|
gdb_expect {
|
|
-re ".*$gdb_prompt $" { pass "fixup"}
|
|
timeout { fail "fixup" }
|
|
}
|
|
}
|
|
-re ".*SIGTRAP.*148.*148.*$gdb_prompt $" {
|
|
fail "SIGTRAP on deleted bp 148 "
|
|
send_gdb "c\n"
|
|
gdb_expect {
|
|
-re ".*$gdb_prompt $" { pass "fixup"}
|
|
timeout { fail "fixup" }
|
|
}
|
|
}
|
|
-re ".*SIGTRAP.*$gdb_prompt $" {
|
|
fail "unknown SIGTRAP"
|
|
send_gdb "c\n"
|
|
gdb_expect {
|
|
-re ".*$gdb_prompt $" { pass "fixup"}
|
|
timeout { fail "fixup" }
|
|
}
|
|
}
|
|
-re ".*Program exited.*$gdb_prompt $" {
|
|
pass "run to end"
|
|
}
|
|
-re ".*$gdb_prompt $" {
|
|
fail "run to end"
|
|
send_gdb "c\n"
|
|
gdb_expect {
|
|
-re ".*$gdb_prompt $" { pass "fixup"}
|
|
timeout { fail "fixup" }
|
|
}
|
|
}
|
|
timeout { fail "timeout" }
|
|
}
|
|
|
|
gdb_test "p \$pc" ".*No registers.*" "program done"
|
|
|
|
# Done!
|
|
#
|
|
gdb_exit
|
|
|
|
set timeout $oldtimeout
|
|
set verbose $oldverbose
|
|
|
|
# execute_anywhere "rm -f ${binfile}"
|
|
#
|
|
return 0
|
|
|