diff options
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/longjmp.c | 81 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/longjmp.exp | 130 |
3 files changed, 215 insertions, 0 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 1e93035..e25a200 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2008-05-04 Pedro Alves <pedro@codesourcery.com> + * gdb.base/longjmp.c, gdb.base/longjmp.exp: New files. + +2008-05-04 Pedro Alves <pedro@codesourcery.com> + * gdb.cp/annota2.exp: Adjust to breakpoints invalidations at different times. diff --git a/gdb/testsuite/gdb.base/longjmp.c b/gdb/testsuite/gdb.base/longjmp.c new file mode 100644 index 0000000..4d69d6d --- /dev/null +++ b/gdb/testsuite/gdb.base/longjmp.c @@ -0,0 +1,81 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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/>. +*/ + +#include <setjmp.h> + +jmp_buf env; + +volatile int longjmps = 0; +volatile int resumes = 0; + +int +call_longjmp (jmp_buf *buf) +{ + longjmps++; + longjmp (*buf, 1); +} + +void +hidden_longjmp (void) +{ + if (setjmp (env) == 0) /* longjmp caught */ + { + call_longjmp (&env); + } + else + resumes++; +} + +int +main () +{ + volatile int i = 0; + + /* Pattern 1 - simple longjmp. */ + if (setjmp (env) == 0) /* patt1 */ + { + longjmps++; + longjmp (env, 1); + } + else + { + resumes++; + } + + i = 1; /* miss_step_1 */ + + + /* Pattern 2 - longjmp from an inner function. */ + if (setjmp (env) == 0) /* patt2 */ + { + call_longjmp (&env); + } + else + { + resumes++; + } + + i = 2; /* miss_step_2 */ + + /* Pattern 3 - setjmp/longjmp inside stepped-over function. */ + hidden_longjmp (); /* patt3 */ + + i = 3; /* patt_end3. */ + + return 0; +} diff --git a/gdb/testsuite/gdb.base/longjmp.exp b/gdb/testsuite/gdb.base/longjmp.exp new file mode 100644 index 0000000..da8f484 --- /dev/null +++ b/gdb/testsuite/gdb.base/longjmp.exp @@ -0,0 +1,130 @@ +# Copyright 2008 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 support for stepping over longjmp. +# + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +set testfile "longjmp" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug nowarnings}] != "" } { + untested longjmp.exp + return -1 +} + +if [get_compiler_info ${binfile}] { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +set bp_miss_step_1 [gdb_get_line_number "miss_step_1"] +set bp_miss_step_2 [gdb_get_line_number "miss_step_2"] + +set bp_start_test_1 [gdb_get_line_number "patt1"] +set bp_start_test_2 [gdb_get_line_number "patt2"] +set bp_start_test_3 [gdb_get_line_number "patt3"] + +# +# Pattern 1 - simple longjmp. +# + +delete_breakpoints + +gdb_test "break $bp_start_test_1" \ + "Breakpoint.*at.* file .*$srcfile, line.*$bp_start_test_1.*" \ + "breakpoint at pattern 1 start" +gdb_test "continue" "patt1.*" "continue to breakpoint at pattern 1 start" + +# set safe-net break +gdb_test "break $bp_miss_step_1" \ + "Breakpoint.*at.* file .*$srcfile, line.*$bp_miss_step_1.*" \ + "breakpoint at miss_step_1" + +gdb_test "next" "longjmps\\+\\+;.*" "next over setjmp (1)" +gdb_test "next" "longjmp \\(env, 1\\);.*" "next to longjmp (1)" + +set msg "next over longjmp(1)" +gdb_test_multiple "next" $msg { + -re ".*patt1.*" { + pass $msg + gdb_test "next" "resumes\\+\\+.*" "next into else block (1)" + gdb_test "next" "miss_step_1.*" "next into safety net (1)" + } + -re "miss_step_1.*" { + fail $msg + } +} + +# +# Pattern 2 - longjmp from an inner function. +# + +delete_breakpoints + +gdb_test "break $bp_start_test_2" \ + "Breakpoint.*at.* file .*$srcfile, line.*$bp_start_test_2.*" \ + "breakpoint at pattern 2 start" +gdb_test "continue" "patt2.*" "continue to breakpoint at pattern 2 start" + +# set safe-net break +gdb_test "break $bp_miss_step_2" \ + "Breakpoint.*at.* file .*$srcfile, line.*$bp_miss_step_2.*" \ + "breakpoint at miss_step_2" + +gdb_test "next" "call_longjmp.*" "next over setjmp (2)" + +set msg "next over call_longjmp (2)" +gdb_test_multiple "next" $msg { + -re ".*patt2.*" { + pass $msg + + gdb_test "next" "resumes\\+\\+.*" "next into else block (2)" + gdb_test "next" "miss_step_2.*" "next into safety net (2)" + } + -re "miss_step_2.*" { + fail $msg + } +} + +# +# Pattern 3 - setjmp/longjmp inside stepped-over function. +# + +delete_breakpoints + +gdb_test "break $bp_start_test_3" \ + "Breakpoint.*at.* file .*$srcfile, line.*$bp_start_test_3.*" \ + "breakpoint at pattern 3 start" +gdb_test "continue" "patt3.*" "continue to breakpoint at pattern 3 start" + +gdb_test "next" "longjmp caught.*" "next over patt3" |