| # Copyright 2004-2021 Free Software Foundation, Inc. | 
 |  | 
 | # This program is free software; you can redistribute it and/or modify | 
 | # it under the terms of the GNU General Public License as published by | 
 | # the Free Software Foundation; either version 3 of the License, or | 
 | # (at your option) any later version. | 
 | # | 
 | # This program is distributed in the hope that it will be useful, | 
 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | # GNU General Public License for more details. | 
 | # | 
 | # You should have received a copy of the GNU General Public License | 
 | # along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
 |  | 
 |  | 
 | # The program sigaltstack.c creates a backtrace containing nested | 
 | # signal handlers on an alternative stack.  This in turn leads to a | 
 | # non-contiguous (and possibly non-monotonic) backtrace - stack | 
 | # address jump at the normal-alt stack boundary. | 
 |  | 
 | # This test confirms that GDB can both backtrace through and finish | 
 | # such a stack. | 
 |  | 
 | if [target_info exists gdb,nosignals] { | 
 |     verbose "Skipping sigaltstack.exp because of nosignals." | 
 |     continue | 
 | } | 
 |  | 
 |  | 
 | standard_testfile .c | 
 |  | 
 | if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | 
 |     untested "failed to compile" | 
 |     return -1 | 
 | } | 
 |  | 
 | # get things started | 
 | clean_restart ${binfile} | 
 |  | 
 | # Pass all the alarms straight through (but verbosely) | 
 | gdb_test "handle SIGALRM print pass nostop" | 
 | gdb_test "handle SIGVTALRM print pass nostop" | 
 | gdb_test "handle SIGPROF print pass nostop" | 
 |  | 
 | # Advance to main | 
 | if ![runto_main] then { | 
 |     fail "can't run to main" | 
 |     return 0 | 
 | } | 
 |  | 
 | # Stop in handle, when at the inner most level | 
 | gdb_test "break catcher if level == INNER" | 
 | gdb_test "continue" ".* catcher .*" "continue to catch" | 
 | # step off the assignment | 
 | gdb_test "next" | 
 |  | 
 | # Full backtrace? | 
 | gdb_test_sequence "bt" "backtrace" { | 
 |     "\[\r\n\]+.0 \[^\r\n\]* catcher " | 
 |     "\[\r\n\]+.1  .signal handler called." | 
 |     "\[\r\n\]+.2 \[^\r\n\]* thrower .next_level=INNER" | 
 |     "\[\r\n\]+.3 \[^\r\n\]* catcher " | 
 |     "\[\r\n\]+.4  .signal handler called." | 
 |     "\[\r\n\]+.5 \[^\r\n\]* thrower .next_level=OUTER" | 
 |     "\[\r\n\]+.6 \[^\r\n\]* catcher " | 
 |     "\[\r\n\]+.7 \[^\r\n\]* main " | 
 | } | 
 |  | 
 | proc finish_test { pattern msg } { | 
 |     global gdb_prompt | 
 |  | 
 |     gdb_test_multiple "finish" $msg { | 
 | 	-re "Cannot insert breakpoint 0.*${gdb_prompt} $" { | 
 | 	    # Some platforms use a special read-only page for signal | 
 | 	    # trampolines.  We can't set a breakpoint there, and we | 
 | 	    # don't gracefully fall back to single-stepping. | 
 | 	    setup_kfail gdb/8841 "i?86-*-linux*" | 
 | 	    setup_kfail gdb/8841 "*-*-openbsd*" | 
 | 	    setup_kfail gdb/8841 "nios2-*-linux*" | 
 | 	    fail "$msg (could not set breakpoint)" | 
 | 	} | 
 | 	-re "$pattern.*${gdb_prompt} $" { | 
 | 	    pass $msg | 
 | 	} | 
 |     } | 
 | } | 
 |  | 
 | # Finish? | 
 | finish_test "signal handler called." "finish from catch LEAF" | 
 | finish_test "thrower .next_level=INNER, .*" "finish to throw INNER" | 
 | finish_test "catcher .*" "finish to catch INNER" | 
 | finish_test "signal handler called.*" "finish from catch INNER" | 
 | finish_test "thrower .next_level=OUTER, .*" "finish to OUTER" | 
 | finish_test "catcher .*" "finish to catch MAIN" | 
 | finish_test "main .*" "finish to MAIN" |