1# Copyright 2004-2019 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 17# Multi-threaded siginfo test. 18 19if [target_info exists gdb,nosignals] { 20 verbose "Skipping siginfo-thread.exp because of nosignals." 21 continue 22} 23 24if { ![supports_get_siginfo_type] } { 25 verbose "Skipping siginfo-thread.exp because of lack of support." 26 return 27} 28 29standard_testfile .c 30 31if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" \ 32 "${binfile}" executable {debug}] != "" } { 33 return -1 34} 35 36clean_restart $binfile 37 38# Advance to main 39if ![runto_main] then { 40 fail "can't run to main" 41 return 0 42} 43 44# Run to the signal. 45gdb_test "continue" "Thread .* received signal SIGSEGV.*" "continue to signal" 46 47# Try to generate a core file, for a later test. 48set gcorefile [standard_output_file $testfile.gcore] 49set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"] 50 51set ssi_addr "" 52set test "extract si_addr" 53gdb_test_multiple "p \$_siginfo" "$test" { 54 -re "si_addr = ($hex).*$gdb_prompt $" { 55 set ssi_addr $expect_out(1,string) 56 pass "$test" 57 } 58} 59 60set test "extract si_errno" 61gdb_test_multiple "p \$_siginfo" "$test" { 62 -re "si_errno = (\[0-9\]\+).*$gdb_prompt $" { 63 set ssi_errno $expect_out(1,string) 64 pass "$test" 65 } 66} 67 68set test "extract si_code" 69gdb_test_multiple "p \$_siginfo" "$test" { 70 -re "si_code = (\[0-9\]\+).*$gdb_prompt $" { 71 set ssi_code $expect_out(1,string) 72 pass "$test" 73 } 74} 75 76set test "extract si_signo" 77gdb_test_multiple "p \$_siginfo" "$test" { 78 -re "si_signo = (\[0-9\]\+).*$gdb_prompt $" { 79 set ssi_signo $expect_out(1,string) 80 pass "$test" 81 } 82} 83 84set bp_location [gdb_get_line_number "set breakpoint here"] 85 86gdb_test "break $bp_location" 87gdb_test "continue" ".* handler .*" "continue to handler" 88 89gdb_test "p ssi_addr" " = \\(void \\*\\) $ssi_addr" 90gdb_test "p ssi_errno" " = $ssi_errno" 91gdb_test "p ssi_code" " = $ssi_code" 92gdb_test "p ssi_signo" " = $ssi_signo" 93 94gdb_test "thread 1" ".*" 95# siginfo is available here -- it shows SIGSTOP -- so we test to make 96# sure that we have a different signal from the SEGV thread. 97gdb_test "p \$_siginfo.si_signo == $ssi_signo" " = 0" \ 98 "test signal in main thread" 99 100# Test siginfo preservation in core files. 101if {$gcore_created} { 102 clean_restart $binfile 103 104 gdb_test "core $gcorefile" "Core was generated by.*" \ 105 "core [file tail $gcorefile]" 106 107 gdb_test "p \$_siginfo.si_signo" " = $ssi_signo" \ 108 "p \$_siginfo.si_signo from core file" 109 gdb_test "p \$_siginfo.si_errno" " = $ssi_errno" \ 110 "p \$_siginfo.si_errno from core file" 111 gdb_test "p \$_siginfo.si_code" " = $ssi_code" \ 112 "p \$_siginfo.si_code from core file" 113 gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \ 114 " = \\(void \\*\\) $ssi_addr" \ 115 "p \$_siginfo._sifields._sigfault.si_addr from core file" 116 117 # We don't know which thread will be signalled, so we simply 118 # ensure that only one thread got a SEGV. 119 gdb_test_no_output "set variable \$count = 0" 120 foreach thread {1 2} { 121 gdb_test "thread $thread" ".*" "select thread $thread with core file" 122 gdb_test_no_output \ 123 "set variable \$count += (\$_siginfo.si_signo == $ssi_signo)" \ 124 "update counter in thread $thread" 125 } 126 gdb_test "print \$count" " = 1" 127} 128