| # This testcase is part of GDB, the GNU debugger. |
| |
| # Copyright 1998-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 GDB's ability to restore saved registers from stack frames |
| # when using the `return' command. |
| # |
| # This file was written by Jim Blandy <jimb@cygnus.com>, with |
| # fragments borrowed from return.exp. |
| |
| standard_testfile |
| set executable $testfile |
| |
| if { [prepare_for_testing "failed to prepare" $executable $srcfile] } { |
| return -1 |
| } |
| |
| proc restore_tests { } { |
| global gdb_prompt |
| |
| if { ! [ runto driver ] } { |
| return 0 |
| } |
| |
| set limit 5 |
| |
| # For each caller function, |
| # call each of the callee functions, |
| # force a return from the callee, and |
| # make sure that the local variables still have the right values. |
| |
| for {set c 1} {$c <= $limit} {incr c} { |
| |
| # Set a breakpoint at the next caller function. |
| gdb_test "tbreak caller$c" "Temporary breakpoint.*\[0-9\]*\\." |
| |
| # Continue to the next caller function. |
| gdb_test "continue" " caller$c prologue .*" "run to caller$c" |
| |
| # Do each callee function. |
| for {set e 1} {$e <= $limit} {incr e} { |
| |
| gdb_test "tbreak callee$e" "Temporary breakpoint.*\[0-9\]*\\." \ |
| "caller$c calls callee$e; tbreak callee" |
| |
| gdb_test "continue" " callee$e prologue .*/" \ |
| "caller$c calls callee$e; continue to callee" |
| |
| # Do a forced return from the callee. |
| set test "caller$c calls callee$e; return callee now" |
| |
| gdb_test "return 0" \ |
| " caller$c .*" \ |
| "$test" \ |
| "Make .* return now.*y or n. $" \ |
| "y" |
| |
| # Check that the values of the local variables are what |
| # they should be. |
| for {set var 1} {$var <= $c} {incr var} { |
| set expected [expr 0x7eeb + $var] |
| set test "caller$c calls callee$e; return restored l$var to $expected" |
| set pass_pattern " = $expected" |
| set unsupported_pattern " = <optimized out>" |
| gdb_test_multiple "print l$var" $test { |
| -re "\[\r\n\]*(?:$pass_pattern)\[\r\n\]+$gdb_prompt $" { |
| pass $test |
| } |
| -re "\[\r\n\]*(?:$unsupported_pattern)\[\r\n\]+$gdb_prompt $" { |
| unsupported $test |
| } |
| } |
| } |
| } |
| } |
| |
| gdb_continue_to_end "" continue 1 |
| } |
| |
| set prev_timeout $timeout |
| set timeout 30 |
| restore_tests |
| set timeout $prev_timeout |
| |
| # Test PR cli/23785 |
| clean_restart $binfile |
| if { ![runto_main] } { |
| return -1 |
| } |
| gdb_test "restore non-existent-file binary" \ |
| "Failed to open non-existent-file: .*" |