1# Copyright 2004 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 2 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, write to the Free Software 15# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 17 18# The program sigaltstack.c creates a backtrace containing nested 19# signal handlers on an alternative stack. This in turn leads to a 20# non-contiguous (and possibly non-monotonic) backtrace - stack 21# address jump at the normal-alt stack boundary. 22 23# This test confirms that GDB can both backtrace through and finish 24# such a stack. 25 26if [target_info exists gdb,nosignals] { 27 verbose "Skipping signals.exp because of nosignals." 28 continue 29} 30 31if $tracelevel then { 32 strace $tracelevel 33} 34 35set prms_id 0 36set bug_id 0 37 38set testfile sigaltstack 39set srcfile ${testfile}.c 40set binfile ${objdir}/${subdir}/${testfile} 41if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { 42 untested "Couldn't compile ${module}.c" 43 return -1 44} 45 46# get things started 47gdb_exit 48gdb_start 49gdb_reinitialize_dir $srcdir/$subdir 50gdb_load ${binfile} 51 52# Pass all the alarms straight through (but verbosely) 53gdb_test "handle SIGALRM print pass nostop" 54gdb_test "handle SIGVTALRM print pass nostop" 55gdb_test "handle SIGPROF print pass nostop" 56 57# Advance to main 58if { ![runto_main] } then { 59 gdb_suppress_tests; 60} 61 62# Stop in handle, when at the inner most level 63gdb_test "break catcher if level == INNER" 64gdb_test "continue" ".* catcher .*" "continue to catch" 65# step off the assignment 66gdb_test "next" 67 68# Full backtrace? 69send_gdb "bt\n" 70gdb_expect_list "backtrace" ".*$gdb_prompt $" { 71 "\[\r\n\]+.0 \[^\r\n\]* catcher " 72 "\[\r\n\]+.1 .signal handler called." 73 "\[\r\n\]+.2 \[^\r\n\]* thrower .next_level=INNER" 74 "\[\r\n\]+.3 \[^\r\n\]* catcher " 75 "\[\r\n\]+.4 .signal handler called." 76 "\[\r\n\]+.5 \[^\r\n\]* thrower .next_level=OUTER" 77 "\[\r\n\]+.6 \[^\r\n\]* catcher " 78 "\[\r\n\]+.7 \[^\r\n\]* main .*" 79} 80 81proc finish_test { pattern msg } { 82 global gdb_prompt 83 84 gdb_test_multiple "finish" $msg { 85 -re "Cannot insert breakpoint 0.*${gdb_prompt} $" { 86 # Some platforms use a special read-only page for signal 87 # trampolines. We can't set a breakpoint there, and we 88 # don't gracefully fall back to single-stepping. 89 setup_kfail "i?86-*-linux*" gdb/1736 90 fail "$msg (could not set breakpoint)" 91 } 92 -re "$pattern.*${gdb_prompt} $" { 93 pass $msg 94 } 95 } 96} 97 98# Finish? 99finish_test "signal handler called." "finish from catch LEAF" 100finish_test "thrower .next_level=INNER, .*" "finish to throw INNER" 101finish_test "catcher .*" "finish to catch INNER" 102finish_test "signal handler called.*" "finish from catch INNER" 103finish_test "thrower .next_level=OUTER, .*" "finish to OUTER" 104finish_test "catcher .*" "finish to catch MAIN" 105finish_test "main .*" "finish to MAIN" 106