# Copyright 2004 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 2 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  


# The program siginfo.c creates a backtrace containing a signal
# handler registered using sigaction's sa_sigaction / SA_SIGINFO.
# Some OS's (e.g., GNU/Linux) use different signal trampolines for
# sa_sigaction and sa_handler.

# This test first confirms that GDB can backtrace through the
# alternative sa_sigaction signal handler, and second that GDB can
# nexti/stepi out of such a handler.

if [target_info exists gdb,nosignals] {
    verbose "Skipping signals.exp because of nosignals."
    continue
}

if $tracelevel then {
    strace $tracelevel
}

set prms_id 0
set bug_id 0

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

# get things started
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}

gdb_test "display/i \$pc"

# Advance to main
if { ![runto_main] } then {
    gdb_suppress_tests;
}

# 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"

# Run to the signal handler, validate the backtrace.
gdb_test "break handler"
gdb_test "continue" ".* handler .*" "continue to stepi handler"
send_gdb "bt\n"
gdb_expect_list "backtrace for nexti" ".*$gdb_prompt $" {
    "\[\r\n\]+.0 \[^\r\n\]* handler "
    "\[\r\n\]+.1  .signal handler called."
    "\[\r\n\]+.2 \[^\r\n\]* main .*"
}

# Check that GDB can step the inferior back to main
set test "step out of handler"
gdb_test_multiple "step" "${test}" {
    -re "done = 1;.*${gdb_prompt} $" {
	send_gdb "$i\n"
	exp_continue
    }
    -re "\} .. handler .*${gdb_prompt} $" {
	send_gdb "step\n"
	exp_continue
    }
    -re "Program exited normally.*${gdb_prompt} $" {
	kfail gdb/1613 "$test (program exited)"
    }
    -re "(while ..done|return 0).*${gdb_prompt} $" {
	# After stepping out of a function /r signal-handler, GDB will
	# advance the inferior until it is at the first instruction of
	# a code-line.  While typically things return to the middle of
	# the "while..." (and hence GDB advances the inferior to the
	# "return..." line) it is also possible for the return to land
	# on the first instruction of "while...".  Accept both cases.
	pass "$test"
    }
}
