# Copyright 2004-2023 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 . # Multi-threaded siginfo test. if [target_info exists gdb,nosignals] { verbose "Skipping siginfo-thread.exp because of nosignals." return } require supports_get_siginfo_type standard_testfile .c if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" \ "${binfile}" executable {debug}] != "" } { return -1 } clean_restart $binfile # Advance to main if {![runto_main]} { return 0 } # Run to the signal. gdb_test "continue" "Thread .* received signal SIGSEGV.*" "continue to signal" # 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"] 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" gdb_test "thread 1" ".*" # siginfo is available here -- it shows SIGSTOP -- so we test to make # sure that we have a different signal from the SEGV thread. gdb_test "p \$_siginfo.si_signo == $ssi_signo" " = 0" \ "test signal in main thread" # 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" # We don't know which thread will be signalled, so we simply # ensure that only one thread got a SEGV. gdb_test_no_output "set variable \$count = 0" foreach thread {1 2} { gdb_test "thread $thread" ".*" "select thread $thread with core file" gdb_test_no_output \ "set variable \$count += (\$_siginfo.si_signo == $ssi_signo)" \ "update counter in thread $thread" } gdb_test "print \$count" " = 1" }