diff --git a/gdb/testsuite/gdb.base/cfi-without-die-caller.c b/gdb/testsuite/gdb.base/cfi-without-die-caller.c new file mode 100644 --- /dev/null +++ b/gdb/testsuite/gdb.base/cfi-without-die-caller.c @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2005, 2007, 2008, 2009, 2010 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 . */ + +typedef int (*callback_t) (void); + +int +caller (callback_t callback) +{ + /* Ensure some frame content to push away the return address. */ + volatile const long one = 1; + + /* Modify the return value to prevent any tail-call optimization. */ + return (*callback) () - one; +} diff --git a/gdb/testsuite/gdb.base/cfi-without-die-main.c b/gdb/testsuite/gdb.base/cfi-without-die-main.c new file mode 100644 --- /dev/null +++ b/gdb/testsuite/gdb.base/cfi-without-die-main.c @@ -0,0 +1,32 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2005, 2007, 2008, 2009, 2010 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 . */ + +typedef int (*callback_t) (void); + +extern int caller (callback_t callback); + +int +callback (void) +{ + return 1; +} + +int +main (void) +{ + return caller (callback); +} diff --git a/gdb/testsuite/gdb.base/cfi-without-die.exp b/gdb/testsuite/gdb.base/cfi-without-die.exp new file mode 100644 --- /dev/null +++ b/gdb/testsuite/gdb.base/cfi-without-die.exp @@ -0,0 +1,71 @@ +# Copyright 2010 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 . + +# Test CFI is parsed even for range (function) not described by any DIE. + +set testfile cfi-without-die +set srcmainfile ${testfile}-main.c +set srccallerfile ${testfile}-caller.c +set executable ${testfile} +set objmainfile [standard_output_file ${testfile}-main.o] +set objcallerfile [standard_output_file ${testfile}-caller.o] +set binfile [standard_output_file ${executable}] + +if { [gdb_compile "${srcdir}/${subdir}/${srccallerfile}" ${objcallerfile} \ + object [list {additional_flags=-fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables}]] != "" + || [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" ${objmainfile} object {debug}] != "" + || [gdb_compile "${objmainfile} ${objcallerfile}" ${binfile} executable {}] != "" } { + untested ${testfile}.exp + return -1 +} + +clean_restart $executable + +if ![runto callback] then { + fail "verify unwinding: Can't run to callback" + return 0 +} +set test "verify unwinding breaks without CFI" +gdb_test_multiple "bt" $test { + -re " in \[?\]\[?\] .*\r\n$gdb_prompt $" { + # It may backtrace through some random frames even to main(). + pass $test + } + -re " in main .*\r\n$gdb_prompt $" { + fail $test + } + -re "\r\n$gdb_prompt $" { + pass $test + } +} + +if { [gdb_compile "${srcdir}/${subdir}/${srccallerfile}" ${objcallerfile} \ + object [list {additional_flags=-fomit-frame-pointer -funwind-tables -fasynchronous-unwind-tables}]] != "" + || [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" ${objmainfile} object {debug}] != "" + || [gdb_compile "${objmainfile} ${objcallerfile}" ${binfile} executable {}] != "" } { + untested ${testfile}.exp + return -1 +} + +clean_restart $executable + +if ![runto callback] then { + fail "test CFI without DIEs: Can't run to callback" + return 0 +} +# #0 callback () at ... +# #1 0x00000000004004e9 in caller () +# #2 0x00000000004004cd in main () at ... +gdb_test "bt" "#0 +callback \[^\r\n\]+\r\n#1 \[^\r\n\]+ in caller \[^\r\n\]+\r\n#2 \[^\r\n\]+ in main \[^\r\n\]+" "verify unwindin works for CFI without DIEs"