| # Copyright 2010-2025 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 that GDB can generate accurate backtraces even if some of the stack |
| # trace goes through a function with no debug information. |
| |
| standard_testfile -caller.c -main.c |
| set objmainfile [standard_output_file ${testfile}-main.o] |
| set objcallerfile [standard_output_file ${testfile}-caller.o] |
| |
| # Recompile the inferior with or without CFI information, then run the |
| # inferior until the point where the important test starts. |
| # Returns FALSE on an ERROR. |
| proc prepare_test {has_cfi} { |
| global srcdir subdir srcfile srcfile2 objmainfile objcallerfile binfile |
| if {$has_cfi} { |
| set extension "cfi" |
| if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" \ |
| "${objcallerfile}" \ |
| object [list {additional_flags=-fomit-frame-pointer \ |
| -funwind-tables -fasynchronous-unwind-tables}]] != "" } { |
| untested "couldn't compile with cfi" |
| return false |
| } |
| } else { |
| set extension "no-cfi" |
| if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" \ |
| "${objcallerfile}" \ |
| object [list {additional_flags=-fomit-frame-pointer \ |
| -fno-unwind-tables \ |
| -fno-asynchronous-unwind-tables}]] != "" } { |
| untested "couldn't compile without cfi" |
| return false |
| } |
| } |
| if {[gdb_compile [list "${objmainfile}" \ |
| "${objcallerfile}"] \ |
| "${binfile}-${extension}" binfile {}] != ""} { |
| untested "couldn't link object files" |
| return false |
| } |
| |
| clean_restart "$binfile-${extension}" |
| |
| with_test_prefix "${extension}" { |
| |
| if ![runto callback] then { |
| fail "has_cfi=$has_cfi: Can't run to callback" |
| return false |
| } |
| gdb_test_no_output "maint frame-unwinder disable ARCH" |
| return true |
| } |
| } |
| |
| if {[gdb_compile "${srcdir}/${subdir}/${srcfile2}" \ |
| "${objmainfile}" \ |
| object {debug}] != "" } { |
| untested "couldn't compile main file" |
| return |
| } |
| |
| if { [prepare_test false] } { |
| gdb_test "bt" \ |
| [multi_line \ |
| "\[^\r\n\]+Required frame unwinder may have been disabled, \[^\r\n\]+" \ |
| "#0\\s+callback \\(\\) \[^\r\n\]+"] \ |
| "verify unwind fail without CFI" |
| } |
| |
| if { [prepare_test true] } { |
| if { [istarget "arm*-*-*"] } { |
| setup_kfail backtrace/31950 *-*-* |
| } |
| set text {[^\r\n]+} |
| # #0 callback () at ... |
| # #1 0x00000000004004e9 in caller () |
| # #2 0x00000000004004cd in main () at ... |
| gdb_test "bt" \ |
| "#0 +callback $text\r\n#1 $text in caller $text\r\n#2 $text in main $text" \ |
| "Verify unwinding works based only on CFI information" |
| } |