# Copyright 2004, 2007-2012 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 signals.exp because of nosignals."
    continue
}


set testfile sigaltstack
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
    untested "Couldn't compile ${srcfile}.c"
    return -1
}

# get things started
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${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"
