| # Copyright 2008-2021 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 <http://www.gnu.org/licenses/>. |
| |
| # Test inferior resumption after discarding a hand-called function. |
| # There are two things to test. |
| # 1) Inferior stops normally. Upon resumption it should continue normally, |
| # regardless of whatever signal the hand-called function got. |
| # 2) Inferior is stopped at a signal. Upon resumption it should continue |
| # with that signal, regardless of whatever the hand-called function did. |
| |
| if [target_info exists gdb,nosignals] { |
| verbose "Skipping call-signal-resume.exp because of nosignals." |
| continue |
| } |
| |
| |
| standard_testfile call-signals.c |
| |
| if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { |
| untested "failed to compile" |
| return -1 |
| } |
| |
| # Some targets can't do function calls, so don't even bother with this |
| # test. |
| if [target_info exists gdb,cannot_call_functions] { |
| unsupported "this target can not call functions" |
| continue |
| } |
| |
| proc get_dummy_frame_number { } { |
| global gdb_prompt |
| |
| gdb_test_multiple "bt" "backtrace" { |
| -re "#(\[0-9\]*) *<function called from gdb>.*$gdb_prompt $" { |
| return $expect_out(1,string) |
| } |
| } |
| return "" |
| } |
| |
| # Start with a fresh gdb. |
| |
| clean_restart ${binfile} |
| |
| if { ![runto_main] } { |
| return 0 |
| } |
| |
| gdb_test "break stop_one" "Breakpoint \[0-9\]* at .*" |
| gdb_test "continue" "Continuing.*Breakpoint \[0-9\]*, stop_one.*" \ |
| "continue to breakpoint at stop_one" |
| |
| # Call function (causing the program to get a signal), and see if gdb handles |
| # it properly. |
| if {[gdb_test "call gen_signal ()" \ |
| "\[\r\n\]*The program being debugged was signaled.*" \ |
| "inferior function call signaled"] != 0} { |
| return 0 |
| } |
| |
| set frame_number [get_dummy_frame_number] |
| if { "$frame_number" == "" } { |
| fail "dummy stack frame number" |
| setup_xfail "*-*-*" |
| } else { |
| pass "dummy stack frame number" |
| } |
| |
| # Pop the dummy frame. |
| gdb_test "frame $frame_number" ".*" |
| gdb_test_no_output "set confirm off" |
| gdb_test "return" "" |
| |
| # Verify there are no remains of the dummy frame. |
| gdb_test_no_output "maintenance print dummy-frames" |
| set test "maintenance info breakpoints" |
| gdb_test_multiple $test $test { |
| -re " call dummy .*\r\n$gdb_prompt $" { |
| fail $test |
| } |
| -re "\r\n$gdb_prompt $" { |
| pass $test |
| } |
| } |
| |
| # Resume execution, the program should continue without any signal. |
| |
| gdb_test "break stop_two" "Breakpoint \[0-9\]* at .*" |
| gdb_test "continue" "Breakpoint \[0-9\]*, stop_two.*" \ |
| "continue to breakpoint at stop_two" |
| |
| # Continue again, we should get a signal. |
| |
| gdb_test "continue" "Program received signal .*" \ |
| "continue to receipt of signal" |
| |
| # Hand call another function that prematurely stops, |
| # then manually pop the dummy stack frame. |
| |
| gdb_test "break null_hand_call" "Breakpoint \[0-9\]* at .*" |
| gdb_test "call null_hand_call ()" "Breakpoint \[0-9\]*, null_hand_call.*" \ |
| "null_hand_call" |
| |
| set frame_number [get_dummy_frame_number] |
| if { "$frame_number" == "" } { |
| fail "dummy stack frame number" |
| setup_xfail "*-*-*" |
| # Need something. |
| set frame_number 0 |
| } else { |
| pass "dummy stack frame number" |
| } |
| |
| # Pop the dummy frame. |
| gdb_test "frame $frame_number" ".*" |
| gdb_test_no_output "set confirm off" |
| gdb_test "return" "" |
| |
| # Continue again, this time we should get to the signal handler. |
| |
| gdb_test "break handle_signal" "Breakpoint \[0-9\]* at .*" |
| gdb_test "continue" "Breakpoint \[0-9\]*, handle_signal.*" \ |
| "continue to breakpoint at handle_signal" |
| |
| # Continue one last time, the program should exit normally. |
| |
| gdb_test "continue" "$inferior_exited_re normally." \ |
| "continue to program exit" |
| |
| return 0 |