# Copyright 2004, 2007, 2008, 2010, 2011 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 . # The program siginfo-obj.c arranges for a signal handler registered # using sigaction's sa_sigaction / SA_SIGINFO to be called with # si_addr filled in. # This test confirms that we can inspect signal info using the # $_siginfo convenience variable. if [target_info exists gdb,nosignals] { verbose "Skipping siginfo-obj.exp because of nosignals." continue } if { ! [istarget "i?86-*-linux*"] && ! [istarget "x86_64-*-linux*"] && ! [istarget "arm*-*-linux*"] } { verbose "Skipping siginfo-obj.exp because of lack of support." return } if $tracelevel then { strace $tracelevel } set testfile siginfo-obj 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} # Advance to main if { ![runto_main] } then { gdb_suppress_tests; } # Run to the signal. gdb_test "continue" ".*Program received signal SIGSEGV.*" "continue to signal" set ssi_addr "" set test "Extract si_addr" gdb_test_multiple "p \$_siginfo" "$test" { -re "si_addr = ($hex).*$gdb_prompt $" { set ssi_addr $expect_out(1,string) pass "$test" } } set test "Extract si_errno" gdb_test_multiple "p \$_siginfo" "$test" { -re "si_errno = (\[0-9\]\+).*$gdb_prompt $" { set ssi_errno $expect_out(1,string) pass "$test" } } set test "Extract si_code" gdb_test_multiple "p \$_siginfo" "$test" { -re "si_code = (\[0-9\]\+).*$gdb_prompt $" { set ssi_code $expect_out(1,string) pass "$test" } } set test "Extract si_signo" gdb_test_multiple "p \$_siginfo" "$test" { -re "si_signo = (\[0-9\]\+).*$gdb_prompt $" { set ssi_signo $expect_out(1,string) pass "$test" } } set bp_location [gdb_get_line_number "set breakpoint here"] gdb_test "break $bp_location" gdb_test "continue" ".* handler .*" "continue to handler" gdb_test "p ssi_addr" " = \\(void \\*\\) $ssi_addr" gdb_test "p ssi_errno" " = $ssi_errno" gdb_test "p ssi_code" " = $ssi_code" gdb_test "p ssi_signo" " = $ssi_signo" # Again, but this time, patch si_addr and check that the inferior sees # the changed value. # Advance to main if { ![runto_main] } then { gdb_suppress_tests; } # Run to the signal. gdb_test "continue" ".*Program received signal SIGSEGV.*" "continue to signal" set test "Set si_addr" gdb_test "p \$_siginfo._sifields._sigfault.si_addr = 0x666" " = \\(void \\*\\) 0x666" gdb_test "p \$_siginfo.si_errno = 666" " = 666" gdb_test "p \$_siginfo.si_code = 999" " = 999" gdb_test "p \$_siginfo.si_signo = 11" " = 11" gdb_test "break $bp_location" gdb_test "continue" ".* handler .*" "continue to handler" gdb_test "p ssi_addr" " = \\(void \\*\\) 0x666" gdb_test "p ssi_errno" " = 666" gdb_test "p ssi_code" " = 999" gdb_test "p ssi_signo" " = 11"