1 # This testcase is part of GDB, the GNU debugger.
3 # Copyright 2023 Free Software Foundation, Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # This test case looks at GDB's ability to get correct backtraces for a
19 # crashed inferior, recreating it from a live inferior, a corefile and
24 set have_pthread_kill -1
26 # Use 'thread apply all backtrace' to check if all expected threads
27 # are present, and stopped in the expected locations. Set the global
28 # TEST_LIST to be the a list of regexps expected to match all the
29 # threads. We generate it now so that the list is in the order that
30 # GDB sees the threads.
32 proc thread_apply_all {} {
34 global have_pthread_kill
44 set cmd "thread apply all backtrace"
45 gdb_test_multiple $cmd "Get thread information" {
49 -re "^\r\n#$::decimal\\\?\\\?$hs$eol" {
53 -re "^\r\n${hs}syscall_task .location=SIGNAL_ALT_STACK$hs$eol" {
57 -re "^\r\n${hs}syscall_task .location=SIGNAL_HANDLER$hs$eol" {
61 -re "^\r\n${hs}syscall_task .location=NORMAL$hs$eol" {
65 -re "^\r\n${hs}spin_task .location=SIGNAL_ALT_STACK$hs$eol" {
69 -re "^\r\n${hs}spin_task .location=SIGNAL_HANDLER$hs$eol" {
73 -re "^\r\n${hs}spin_task .location=NORMAL$hs$eol" {
77 -re "^\r\n${hs}in main$hs$eol" {
81 -re "^\r\n${hs} in sleep $hs$eol" {
85 -re "^\r\n${hs} in pthread_kill $hs$eol" {
86 set have_pthread_kill 1
92 -re "^\r\n$::gdb_prompt $" {
97 gdb_assert {$unwind_fail == false}
99 if { $have_sleep == -1 } {
102 if { $have_pthread_kill == -1 } {
103 set have_pthread_kill 0
107 # Perform all the tests we're interested in. They are:
108 # * test if we have 7 threads
109 # * Creating the list of backtraces for all threads seen
110 # * testing if GDB recreated the full backtrace we expect for all threads
112 proc do_full_test {} {
114 global have_pthread_kill
116 set thread_count [get_valueof "" "\$_inferior_thread_count" 0]
117 gdb_assert {$thread_count == 7}
121 gdb_assert {$thread_count == [llength $test_list]}
124 set sleep ".*sleep.*"
129 if { $have_pthread_kill } {
130 set pthread_kill ".*pthread_kill.*"
132 set pthread_kill ".*"
135 for {set i 0} {$i < $thread_count } {incr i} {
136 set thread_num [expr [llength $test_list] - $i]
138 set type [lindex $test_list $i]
143 ".*do_syscall_task .location=SIGNAL_ALT_STACK.*" \
144 ".*signal_handler.*" \
145 ".*signal handler called.*" \
147 ".*thread_function.*"]
148 } elseif { $type == 2 } {
152 ".*do_syscall_task .location=SIGNAL_HANDLER.*" \
153 ".*signal_handler.*" \
154 ".*signal handler called.*" \
156 ".*thread_function.*"]
157 } elseif { $type == 3 } {
161 ".*do_syscall_task .location=NORMAL.*" \
162 ".*thread_function.*"]
163 } elseif { $type == 4 } {
166 ".*do_spin_task .location=SIGNAL_ALT_STACK.*" \
167 ".*signal_handler.*" \
168 ".*signal handler called.*" \
170 ".*thread_function.*"]
171 } elseif { $type == 5 } {
174 ".*do_spin_task .location=SIGNAL_HANDLER.*" \
175 ".*signal_handler.*" \
176 ".*signal handler called.*" \
178 ".*thread_function.*"]
179 } elseif { $type == 6 } {
182 ".*do_spin_task .location=NORMAL..*" \
183 ".*thread_function.*"]
184 } elseif { $type == 7 } {
187 error "invalid type: $type"
190 gdb_test "thread apply $thread_num backtrace" $re
194 # Do all preparation steps for running the corefile tests, then
195 # call do_full_test to actually run the tests.
197 proc_with_prefix test_live_inferior {} {
198 gdb_test "handle SIGUSR1 nostop print pass" \
199 ".*SIGUSR1.*No.*Yes.*Yes.*User defined signal 1" \
201 gdb_test "handle SIGUSR2 nostop print pass" \
202 ".*SIGUSR2.*No.*Yes.*Yes.*User defined signal 2" \
209 gdb_breakpoint "breakpt"
210 gdb_continue_to_breakpoint "running to breakpoint" ".*"
215 # Do all preparation steps for running the corefile tests, then
216 # call do_full_test to actually run the tests.
218 proc_with_prefix test_corefile {} {
219 set corefile [core_find $::binfile]
220 if { $corefile == "" } {
221 untested "couldn't generate corefile"
224 set corefile [gdb_remote_download host $corefile]
226 gdb_test "core-file $corefile" \
229 "A program is being debugged already\\\. Kill it\\\? \\\(y or n\\\) " \
235 # Do all preparation steps for running the gcore tests, then
236 # call do_full_test to actually run the tests.
238 proc_with_prefix test_gcore {} {
240 clean_restart "$::binfile"
242 gdb_test "handle SIGUSR1 nostop print pass" \
243 ".*SIGUSR1.*No.*Yes.*Yes.*User defined signal 1" \
245 gdb_test "handle SIGUSR2 nostop print pass" \
246 ".*SIGUSR2.*No.*Yes.*Yes.*User defined signal 2" \
252 gdb_test "continue" ".*Segmentation fault.*" "continue to crash"
254 set gcore_host [host_standard_output_file $::testfile.gcore]
255 set gcore_supported [gdb_gcore_cmd "$gcore_host" "saving gcore"]
257 if {!$gcore_supported} {
258 unsupported "couldn't generate gcore file"
262 gdb_test "core-file $gcore_host" \
265 "A program is being debugged already\\\. Kill it\\\? \\\(y or n\\\) " \
273 if [prepare_for_testing "failed to prepare" $testfile $srcfile \
278 clean_restart ${binfile}
280 gdb_test_no_output "set backtrace limit unlimited"