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