# Copyright 2004-2020 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 { ![supports_get_siginfo_type] } { verbose "Skipping siginfo-obj.exp because of lack of support." return } standard_testfile if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { return -1 } # Advance to main if ![runto_main] then { fail "can't run to main" return 0 } # Run to the signal. gdb_test "continue" ".*Program received signal SIGSEGV.*" \ "continue to signal, 1st" # Try to generate a core file, for a later test. set gcorefile [standard_output_file $testfile.gcore] set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"] 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"] with_test_prefix "validate siginfo fields" { 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 { fail "can't run to main" return 0 } # Run to the signal. gdb_test "continue" ".*Program received signal SIGSEGV.*" \ "continue to signal, 2nd" 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" with_test_prefix "validate modified siginfo fields" { 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" } # Test siginfo preservation in core files. if {$gcore_created} { clean_restart $binfile gdb_test "core $gcorefile" "Core was generated by.*" \ "core [file tail $gcorefile]" gdb_test "p \$_siginfo.si_signo" " = $ssi_signo" \ "p \$_siginfo.si_signo from core file" gdb_test "p \$_siginfo.si_errno" " = $ssi_errno" \ "p \$_siginfo.si_errno from core file" gdb_test "p \$_siginfo.si_code" " = $ssi_code" \ "p \$_siginfo.si_code from core file" gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \ " = \\(void \\*\\) $ssi_addr" \ "p \$_siginfo._sifields._sigfault.si_addr from core file" }