| # This testcase is part of GDB, the GNU debugger. | |
| # Copyright 1998-2018 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\]*\\." \ | |
| "tbreak caller$c" | |
| # 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] | |
| gdb_test "print l$var" " = $expected" \ | |
| "caller$c calls callee$e; return restored l$var to $expected" | |
| } | |
| } | |
| } | |
| gdb_continue_to_end "" continue 1 | |
| } | |
| set prev_timeout $timeout | |
| set timeout 30 | |
| restore_tests | |
| set timeout $prev_timeout |