# Copyright 2004-2013 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 "Couldn't compile ${srcfile}.c"
    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 {
    gdb_suppress_tests
}

# 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/1736 "i?86-*-linux*"
	    setup_kfail gdb/1736 "*-*-openbsd*"
	    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"
