#   Copyright 2009-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/>.

if [target_info exists gdb,nosignals] {
    verbose "Skipping sigall-precsave.exp because of nosignals."
    return
}

if ![supports_reverse] {
    return
}


gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir

standard_testfile sigall-reverse.c
set precsave [standard_output_file sigall.precsave]

if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
    return -1
}

proc test_one_sig {nextsig} {
    global sig_supported
    global gdb_prompt
    global thissig

    set this_sig_supported $sig_supported
    gdb_test "handle SIG$thissig stop print" \
	"SIG$thissig\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*"
    gdb_test "b handle_$thissig" "Breakpoint \[0-9\]+ .*"
    gdb_test "b gen_$nextsig" "Breakpoint \[0-9\]+ .*"

    set need_another_continue 1
    set missed_handler 0
    if $this_sig_supported then {
	if { $thissig == "IO" } {
	    setup_xfail "i*86-pc-linuxoldld-gnu" "i*86-pc-linuxaout-gnu"
	}
	set testmsg "get signal $thissig"
	gdb_test_multiple "continue" $testmsg {
	    -re "Program received signal SIG$thissig.*handle_$thissig.*$gdb_prompt $" {
		fail "$testmsg (wrong location)"
	    }
	    -re "Program received signal SIG$thissig.*$gdb_prompt $" {
		pass $testmsg
	    }
	    -re "Breakpoint.* handle_$thissig.*$gdb_prompt $" {
		xfail $testmsg
		set need_another_continue 0
	    }
	}
    }
    if [ istarget "alpha-dec-osf3*" ] then {
	# OSF/1-3.x is unable to continue with a job control stop signal.
	# The inferior remains stopped without an event of interest
	# and GDB waits forever for the inferior to stop on an event
	# of interest. Work around the kernel bug.
	if { $thissig == "TSTP" || $thissig == "TTIN" || $thissig == "TTOU" } {
	    setup_xfail "alpha-dec-osf3*"
	    fail "cannot continue from signal $thissig"
	    set need_another_continue 0
	}
    }

    if $need_another_continue then {
	if { $thissig == "URG" } {
	    setup_xfail "i*86-pc-linuxoldld-gnu" "i*86-pc-linuxaout-gnu"
	}
        # Either Lynx or GDB screws up on SIGPRIO
	if { $thissig == "PRIO" } {
	    setup_xfail "*-*-*lynx*"
	}
	set testmsg "send signal $thissig"
	gdb_test_multiple "continue" $testmsg {
	    -re "Breakpoint.*handle_$thissig.*$gdb_prompt $" {
		pass $testmsg
	    }
	    -re "Breakpoint.*gen_$nextsig.*kill.*$gdb_prompt $" {
		fail "missed breakpoint at handle_$thissig"
		set missed_handler 1
	    }
	}
    }

    if { $missed_handler == "0" } then {
	set testmsg "advance to $nextsig"
        gdb_test_multiple "signal 0" $testmsg {
	    -re "Breakpoint.*gen_$nextsig.*kill.*$gdb_prompt $" {
	        pass $testmsg
	        set sig_supported 1
	    }
	    -re "Breakpoint.*gen_$nextsig.*handle.*$gdb_prompt $" {
	        pass $testmsg
	        set sig_supported 0
	    }
        }
    }
    set thissig $nextsig
}

proc test_one_sig_reverse {prevsig} {
    global gdb_prompt

    gdb_test "reverse-continue" "Breakpoint .* handle_$prevsig.*" \
	"reverse to handler of $prevsig"

    set saw_signal 0
    set testmsg "reverse to gen_$prevsig"
    gdb_test_multiple "reverse-continue" $testmsg {
	-re "Breakpoint.*handle_.*$gdb_prompt " {
	    pass "$testmsg (un-handled)"
	}
	-re "Program received signal SIG$prevsig.*$gdb_prompt " {
	    pass "reverse to signal event, $prevsig"

	    set nested_testmsg "reverse signal delivered"
	    gdb_test_multiple "frame" $nested_testmsg {
		-re ".*handle_$prevsig.*$gdb_prompt " {
		    fail "$nested_testmsg (wrong location)"
		}
		-re ".*$gdb_prompt " {
		    pass $nested_testmsg
		}
	    }

	    set saw_signal 1
	    send_gdb "reverse-continue\n"
	    exp_continue
	}
	-re "Breakpoint.*kill.*$gdb_prompt " {
	    if { $saw_signal } then {
		pass "$testmsg (handled)"
	    } else {
		xfail "$testmsg (handled)"
	    }
	}
	-re "No more reverse-execution history.*kill.*$gdb_prompt " {
	    if { $saw_signal } then {
		pass "$testmsg (handled)"
	    } else {
		xfail "$testmsg (handled)"
	    }
	}	    
    }
}

gdb_load $binfile

runto gen_ABRT

if [supports_process_record] {
    # Activate process record/replay
    gdb_test_no_output "record" "Turn on process record"
}

# Run until end, then save execution log. 

set breakloc [gdb_get_line_number "end of main" "$srcfile"]
gdb_test "break $breakloc" \
    "Breakpoint $decimal at .*/$srcfile, line $breakloc\." \
    "BP at end of main"

# Signal handlers must be disabled
gdb_test "handle all nostop noprint"

# The list of signals that the program generates, in the order they
# are generated.
set signals {
    ABRT
    HUP
    QUIT
    ILL
    EMT
    FPE
    BUS
    SEGV
    SYS
    PIPE
    ALRM
    URG
    TSTP
    CONT
    CHLD
    TTIN
    TTOU
    IO
    XCPU
    XFSZ
    VTALRM
    PROF
    WINCH
    LOST
    USR1
    USR2
    PWR
    POLL
    WIND
    PHONE
    WAITING
    LWP
    DANGER
    GRANT
    RETRACT
    MSG
    SOUND
    SAK
    PRIO
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    TERM
}

# Software single-step targets can't step into signal handlers.  Since
# later, when replaying the execution log, the test wants to set
# breakpoints on handlers, we need to make sure that while recording,
# GDB steps through the handlers too, so that the execution log covers
# them.  Setting breakpoints in all handlers takes care of it.  This
# is harmless for hardware-step targets.
foreach sig $signals {
    set test "break *handle_$sig"
    gdb_test_multiple $test $test {
	-re "Breakpoint .*$gdb_prompt $" {
	    # No need to record a pass for each breakpoint.
	}
    }
}

gdb_test_multiple "continue" "continue" {
    -re "Breakpoint .* end of main .*$gdb_prompt $" {
	pass "run to end of main"
    }
    -re "Breakpoint .* handle_.*$gdb_prompt $" {
	send_gdb "continue\n"
	exp_continue
    }
}

delete_breakpoints

gdb_test "record save $precsave" \
    "Saved core file $precsave with execution log\."  \
    "save process recfile"

gdb_test "kill" "" "Kill process, prepare to debug log file" \
    "Kill the program being debugged\\? \\(y or n\\) " "y"

gdb_test "record restore $precsave" \
    "Program terminated with signal .*" \
    "reload precord save file"

# Signal handlers must be re-enabled
gdb_test "handle all stop print"

# Make the first signal SIGABRT because it is always supported.
set sig_supported 1
set thissig "ABRT"

# test signal handling
foreach sig [lrange $signals 1 end] {
    test_one_sig $sig
}

# The last signal (SIGTERM) gets handled slightly differently because
# we are not setting up for another test.
gdb_test "handle SIGTERM stop print" \
    "SIGTERM\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*"
gdb_test "b handle_TERM" "Breakpoint \[0-9\]+ .*"
gdb_test "continue" \
    "Continuing.*Program received signal SIGTERM.*" \
    "get signal TERM"
gdb_test "continue" "Breakpoint.*handle_TERM.*" "send signal TERM"

gdb_test "continue" " end of main .*" "continue to sigall exit" 

foreach sig [lreverse $signals] {
    test_one_sig_reverse $sig
}

# Make the first signal SIGABRT because it is always supported.
set sig_supported 1
set thissig "ABRT"

foreach sig [lrange $signals 1 end] {
    test_one_sig $sig
}
