1# Copyright (C) 2021-2023 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# This test checks for an edge case when unwinding inline frames which 17# occur towards the older end of the stack when the stack ends with a 18# cycle. Consider this well formed stack: 19# 20# main -> normal_frame -> inline_frame 21# 22# Now consider that, for whatever reason, the stack unwinding of 23# "normal_frame" becomes corrupted, such that the stack appears to be 24# this: 25# 26# .-> normal_frame -> inline_frame 27# | | 28# '------' 29# 30# When confronted with such a situation we would expect GDB to detect 31# the stack frame cycle and terminate the backtrace at the first 32# instance of "normal_frame" with a message: 33# 34# Backtrace stopped: previous frame identical to this frame (corrupt stack?) 35# 36# However, at one point there was a bug in GDB's inline frame 37# mechanism such that the fact that "inline_frame" was inlined into 38# "normal_frame" would cause GDB to trigger an assertion. 39# 40# This text makes use of a Python unwinder which can fake the cyclic 41# stack cycle, further the test sets up multiple levels of normal and 42# inline frames. At the point of testing the stack looks like this: 43# 44# main -> normal_func -> inline_func -> normal_func -> inline_func -> normal_func -> inline_func 45# 46# Where "normal_func" is a normal frame, and "inline_func" is an inline frame. 47# 48# The python unwinder is then used to force a stack cycle at each 49# "normal_func" frame in turn, we then check that GDB can successfully unwind 50# the stack. 51 52standard_testfile 53 54if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}]} { 55 return -1 56} 57 58# Skip this test if Python scripting is not enabled. 59if { [skip_python_tests] } { continue } 60 61if {![runto_main]} { 62 return 0 63} 64 65set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] 66 67# Run to the breakpoint where we will carry out the test. 68gdb_breakpoint [gdb_get_line_number "Break here"] 69gdb_continue_to_breakpoint "stop at test breakpoint" 70 71# Load the script containing the unwinder, this must be done at the 72# testing point as the script will examine the stack as it is loaded. 73gdb_test_no_output "source ${pyfile}"\ 74 "import python scripts" 75 76# Check the unbroken stack. 77gdb_test_sequence "bt" "backtrace when the unwind is left unbroken" { 78 "\\r\\n#0 \[^\r\n\]* inline_func \\(\\) at " 79 "\\r\\n#1 \[^\r\n\]* normal_func \\(\\) at " 80 "\\r\\n#2 \[^\r\n\]* inline_func \\(\\) at " 81 "\\r\\n#3 \[^\r\n\]* normal_func \\(\\) at " 82 "\\r\\n#4 \[^\r\n\]* inline_func \\(\\) at " 83 "\\r\\n#5 \[^\r\n\]* normal_func \\(\\) at " 84 "\\r\\n#6 \[^\r\n\]* main \\(\\) at " 85} 86 87with_test_prefix "cycle at level 5" { 88 # Arrange to introduce a stack cycle at frame 5. 89 gdb_test_no_output "python stop_at_level=5" 90 gdb_test "maint flush register-cache" \ 91 "Register cache flushed\\." 92 gdb_test_lines "bt" "backtrace when the unwind is broken at frame 5" \ 93 [multi_line \ 94 "#0 \[^\r\n\]* inline_func \\(\\) at \[^\r\n\]+" \ 95 "#1 \[^\r\n\]* normal_func \\(\\) at \[^\r\n\]+" \ 96 "#2 \[^\r\n\]* inline_func \\(\\) at \[^\r\n\]+" \ 97 "#3 \[^\r\n\]* normal_func \\(\\) at \[^\r\n\]+" \ 98 "#4 \[^\r\n\]* inline_func \\(\\) at \[^\r\n\]+" \ 99 "#5 \[^\r\n\]* normal_func \\(\\) at \[^\r\n\]+" \ 100 "Backtrace stopped: previous frame identical to this frame \\(corrupt stack\\?\\)"] 101} 102 103with_test_prefix "cycle at level 3" { 104 # Arrange to introduce a stack cycle at frame 3. 105 gdb_test_no_output "python stop_at_level=3" 106 gdb_test "maint flush register-cache" \ 107 "Register cache flushed\\." 108 gdb_test_lines "bt" "backtrace when the unwind is broken at frame 3" \ 109 [multi_line \ 110 "#0 \[^\r\n\]* inline_func \\(\\) at \[^\r\n\]+" \ 111 "#1 \[^\r\n\]* normal_func \\(\\) at \[^\r\n\]+" \ 112 "#2 \[^\r\n\]* inline_func \\(\\) at \[^\r\n\]+" \ 113 "#3 \[^\r\n\]* normal_func \\(\\) at \[^\r\n\]+" \ 114 "Backtrace stopped: previous frame identical to this frame \\(corrupt stack\\?\\)"] 115} 116 117with_test_prefix "cycle at level 1" { 118 # Arrange to introduce a stack cycle at frame 1. 119 gdb_test_no_output "python stop_at_level=1" 120 gdb_test "maint flush register-cache" \ 121 "Register cache flushed\\." 122 gdb_test_lines "bt" "backtrace when the unwind is broken at frame 1" \ 123 [multi_line \ 124 "#0 \[^\r\n\]* inline_func \\(\\) at \[^\r\n\]+" \ 125 "#1 \[^\r\n\]* normal_func \\(\\) at \[^\r\n\]+" \ 126 "Backtrace stopped: previous frame identical to this frame \\(corrupt stack\\?\\)"] 127} 128 129# Flush the register cache (which also flushes the frame cache) so we 130# get a full backtrace again, then switch on frame debugging and try 131# to back trace. At one point this triggered an assertion. 132gdb_test "maint flush register-cache" \ 133 "Register cache flushed\\." "" 134gdb_test_no_output "set debug frame 1" 135gdb_test_multiple "bt" "backtrace with debugging on" { 136 -re "^$gdb_prompt $" { 137 pass $gdb_test_name 138 } 139 -re "\[^\r\n\]+\r\n" { 140 exp_continue 141 } 142} 143gdb_test "p 1 + 2 + 3" " = 6" \ 144 "ensure GDB is still alive" 145