Update copyright year in most headers.
[external/binutils.git] / gdb / testsuite / gdb.threads / hand-call-in-threads.exp
1 # Copyright (C) 2004, 2007, 2008, 2010 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
18 set NR_THREADS 4
19
20 if $tracelevel then {
21         strace $tracelevel
22 }
23
24 set testfile "hand-call-in-threads"
25 set srcfile ${testfile}.c
26 set binfile ${objdir}/${subdir}/${testfile}
27
28 if {[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.
34 if [target_info exists gdb,cannot_call_functions] {
35     setup_xfail "*-*-*" 2416
36     fail "This target can not call functions"
37     continue
38 }
39
40 proc 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
61 gdb_exit
62 gdb_start
63 gdb_reinitialize_dir $srcdir/$subdir
64 gdb_load ${binfile}
65
66 if { ![runto_main] } {
67     fail "Can't run to main"
68     return 0
69 }
70
71 gdb_test "break all_threads_running" \
72          "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
73          "breakpoint on all_threads_running"
74
75 gdb_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
82 gdb_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
88 gdb_test "set scheduler-locking on" "" "enable scheduler locking"
89 gdb_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.
95 set total_nr_threads [expr $NR_THREADS + 1]
96
97 # Thread numbering in gdb is origin-1, so begin numbering at 1.
98 for { 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.
107 gdb_test "set confirm off" ""
108
109 clear_xfail "*-*-*"
110
111 for { 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
131 gdb_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.
141 gdb_test "set scheduler-locking off" "" "disable scheduler locking"
142 gdb_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
160 return 0