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