]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.threads/hand-call-in-threads.exp
* infrun.c (prepare_to_proceed): Document. Assert !non_stop.
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.threads / hand-call-in-threads.exp
CommitLineData
5a437975
DE
1# Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16# Test making hand function calls in multiple threads.
17
18set NR_THREADS 4
19
20if $tracelevel then {
21 strace $tracelevel
22}
23
24set testfile "hand-call-in-threads"
25set srcfile ${testfile}.c
26set binfile ${objdir}/${subdir}/${testfile}
27
28if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}" "additional_flags=-DNR_THREADS=$NR_THREADS"]] != "" } {
29 return -1
30}
31
32# Some targets can't do function calls, so don't even bother with this
33# test.
34if [target_info exists gdb,cannot_call_functions] {
35 setup_xfail "*-*-*" 2416
36 fail "This target can not call functions"
37 continue
38}
39
40proc get_dummy_frame_number { } {
41 global gdb_prompt
42
43 send_gdb "bt\n"
44 gdb_expect {
45 -re "#(\[0-9\]*) *<function called from gdb>.*$gdb_prompt $"
46 {
47 return $expect_out(1,string)
48 }
49 -re "$gdb_prompt $"
50 {
51 return ""
52 }
53 timeout
54 {
55 return ""
56 }
57 }
58 return ""
59}
60
61gdb_exit
62gdb_start
63gdb_reinitialize_dir $srcdir/$subdir
64gdb_load ${binfile}
65
66if { ![runto_main] } {
67 fail "Can't run to main"
68 return 0
69}
70
71gdb_test "break all_threads_running" \
72 "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
73 "breakpoint on all_threads_running"
74
75gdb_test "break hand_call" \
76 "Breakpoint 3 at .*: file .*${srcfile}, line .*" \
77 "breakpoint on hand_call"
78
79# Run the program and make sure GDB reports that we stopped after
80# hitting breakpoint 2 in all_threads_running().
81
82gdb_test "continue" \
83 ".*Breakpoint 2, all_threads_running ().*" \
84 "run to all_threads_running"
85
86# Before we start making hand function calls, turn on scheduler locking.
87
88gdb_test "set scheduler-locking on" "" "enable scheduler locking"
89gdb_test "show scheduler-locking" ".* locking scheduler .* is \"on\"." "show scheduler locking on"
90
91# Now hand-call a function in each thread, having the function
92# stop without returning.
93
94# Add one for the main thread.
95set total_nr_threads [expr $NR_THREADS + 1]
96
97# Thread numbering in gdb is origin-1, so begin numbering at 1.
98for { set i 1 } { $i <= $total_nr_threads } { incr i } {
99 set thread_nr $i
100 gdb_test "thread $thread_nr" "" "prepare to make hand call, thread $thread_nr"
101 gdb_test "call hand_call()" "Breakpoint 3, .*" "hand call, thread $thread_nr"
102}
103
104# Now have each hand-called function return.
105
106# Turn confirmation off for the "return" command.
107gdb_test "set confirm off" ""
108
109clear_xfail "*-*-*"
110
111for { set i 1 } { $i <= $total_nr_threads } { incr i } {
112 set thread_nr $i
113 gdb_test "thread $thread_nr" "" "prepare to discard hand call, thread $thread_nr"
114 set frame_number [get_dummy_frame_number]
115 if { "$frame_number" == "" } {
116 fail "dummy stack frame number, thread $thread_nr"
117 # Need something.
118 set frame_number 0
119 } else {
120 pass "dummy stack frame number, thread $thread_nr"
121 }
122 # Pop the dummy frame.
123 gdb_test "frame $frame_number" "" "setting frame, thread $thread_nr"
124 gdb_test "return" "" "discard hand call, thread $thread_nr"
125 # In case getting the dummy frame number failed, re-enable for next iter.
126 clear_xfail "*-*-*"
127}
128
129# Make sure all dummy frames got popped.
130
131gdb_test_multiple "maint print dummy-frames" "all dummies popped" {
132 -re ".*stack=.*$gdb_prompt $" {
133 fail "all dummies popped"
134 }
135 -re ".*$gdb_prompt $" {
136 pass "all dummies popped"
137 }
138}
139
140# Before we resume the full program, turn of scheduler locking.
141gdb_test "set scheduler-locking off" "" "disable scheduler locking"
142gdb_test "show scheduler-locking" ".* locking scheduler .* is \"off\"." "show scheduler locking off"
143
144# Continue one last time, the program should exit normally.
145#
146# ??? This currently doesn't work because gdb doesn't know how to singlestep
147# over reported breakpoints that weren't in the last thread to run.
148# Commented out until then.
149#
150# For reference sake ...
151# An alternative is to manually work around the issue by manually setting
152# the thread back to the first thread: the program is still at the
153# all_threads_running breakpoint, which wasn't the last thread to run,
154# and gdb doesn't know how to singlestep over reported breakpoints that
155# weren't in the last thread to run.
156#gdb_test "thread 1" "" "set thread to 1, prepare to resume"
157#
158#gdb_continue_to_end "hand-call-in-threads"
159
160return 0