1# Copyright 2004-2017 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 gdb_suppress_tests 41} 42 43# Run to the signal. 44gdb_test "continue" "Thread .* received signal SIGSEGV.*" "continue to signal" 45 46# Try to generate a core file, for a later test. 47set gcorefile [standard_output_file $testfile.gcore] 48set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"] 49 50set ssi_addr "" 51set test "extract si_addr" 52gdb_test_multiple "p \$_siginfo" "$test" { 53 -re "si_addr = ($hex).*$gdb_prompt $" { 54 set ssi_addr $expect_out(1,string) 55 pass "$test" 56 } 57} 58 59set test "extract si_errno" 60gdb_test_multiple "p \$_siginfo" "$test" { 61 -re "si_errno = (\[0-9\]\+).*$gdb_prompt $" { 62 set ssi_errno $expect_out(1,string) 63 pass "$test" 64 } 65} 66 67set test "extract si_code" 68gdb_test_multiple "p \$_siginfo" "$test" { 69 -re "si_code = (\[0-9\]\+).*$gdb_prompt $" { 70 set ssi_code $expect_out(1,string) 71 pass "$test" 72 } 73} 74 75set test "extract si_signo" 76gdb_test_multiple "p \$_siginfo" "$test" { 77 -re "si_signo = (\[0-9\]\+).*$gdb_prompt $" { 78 set ssi_signo $expect_out(1,string) 79 pass "$test" 80 } 81} 82 83set bp_location [gdb_get_line_number "set breakpoint here"] 84 85gdb_test "break $bp_location" 86gdb_test "continue" ".* handler .*" "continue to handler" 87 88gdb_test "p ssi_addr" " = \\(void \\*\\) $ssi_addr" 89gdb_test "p ssi_errno" " = $ssi_errno" 90gdb_test "p ssi_code" " = $ssi_code" 91gdb_test "p ssi_signo" " = $ssi_signo" 92 93gdb_test "thread 1" ".*" 94# siginfo is available here -- it shows SIGSTOP -- so we test to make 95# sure that we have a different signal from the SEGV thread. 96gdb_test "p \$_siginfo.si_signo == $ssi_signo" " = 0" \ 97 "test signal in main thread" 98 99# Test siginfo preservation in core files. 100if {$gcore_created} { 101 clean_restart $binfile 102 103 gdb_test "core $gcorefile" "Core was generated by.*" \ 104 "core [file tail $gcorefile]" 105 106 gdb_test "p \$_siginfo.si_signo" " = $ssi_signo" \ 107 "p \$_siginfo.si_signo from core file" 108 gdb_test "p \$_siginfo.si_errno" " = $ssi_errno" \ 109 "p \$_siginfo.si_errno from core file" 110 gdb_test "p \$_siginfo.si_code" " = $ssi_code" \ 111 "p \$_siginfo.si_code from core file" 112 gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \ 113 " = \\(void \\*\\) $ssi_addr" \ 114 "p \$_siginfo._sifields._sigfault.si_addr from core file" 115 116 # We don't know which thread will be signalled, so we simply 117 # ensure that only one thread got a SEGV. 118 gdb_test_no_output "set variable \$count = 0" 119 foreach thread {1 2} { 120 gdb_test "thread $thread" ".*" "select thread $thread with core file" 121 gdb_test_no_output \ 122 "set variable \$count += (\$_siginfo.si_signo == $ssi_signo)" \ 123 "update counter in thread $thread" 124 } 125 gdb_test "print \$count" " = 1" 126} 127