2009-06-27 Michael Snyder <msnyder@vmware.com>
* gdb.reverse: New directory. * gdb.reverse/break-reverse.c: New test. * gdb.reverse/break-reverse.exp: New test. * gdb.reverse/consecutive-reverse.c: New test. * gdb.reverse/consecutive-reverse.exp: New test. * gdb.reverse/finish-reverse.c: New test. * gdb.reverse/finish-reverse.exp: New test. * gdb.reverse/machinestate.c: New test. * gdb.reverse/ms1.c: New test. * gdb.reverse/machinestate.exp: New test. * gdb.reverse/Makefile.in: New file. * gdb.reverse/shr2.c: New test. * gdb.reverse/solib-reverse.c: New test. * gdb.reverse/solib-reverse.exp: New test. * gdb.reverse/step-reverse.c: New test. * gdb.reverse/step-reverse.exp: New test. * gdb.reverse/until-reverse.c: New test. * gdb.reverse/ur1.c: New test. * gdb.reverse/until-reverse.exp: New test. * gdb.reverse/watch-reverse.c: New test. * gdb.reverse/watch-reverse.exp: New test. * configure.ac (AC_OUTPUT): Add gdb.reverse/Makefile. * configure: Regenerate.
This commit is contained in:
parent
388a856237
commit
28d41a992f
23 changed files with 2276 additions and 2 deletions
|
@ -1,3 +1,29 @@
|
|||
2009-06-27 Michael Snyder <msnyder@vmware.com>
|
||||
|
||||
* gdb.reverse: New directory.
|
||||
* gdb.reverse/break-reverse.c: New test.
|
||||
* gdb.reverse/break-reverse.exp: New test.
|
||||
* gdb.reverse/consecutive-reverse.c: New test.
|
||||
* gdb.reverse/consecutive-reverse.exp: New test.
|
||||
* gdb.reverse/finish-reverse.c: New test.
|
||||
* gdb.reverse/finish-reverse.exp: New test.
|
||||
* gdb.reverse/machinestate.c: New test.
|
||||
* gdb.reverse/ms1.c: New test.
|
||||
* gdb.reverse/machinestate.exp: New test.
|
||||
* gdb.reverse/Makefile.in: New file.
|
||||
* gdb.reverse/shr2.c: New test.
|
||||
* gdb.reverse/solib-reverse.c: New test.
|
||||
* gdb.reverse/solib-reverse.exp: New test.
|
||||
* gdb.reverse/step-reverse.c: New test.
|
||||
* gdb.reverse/step-reverse.exp: New test.
|
||||
* gdb.reverse/until-reverse.c: New test.
|
||||
* gdb.reverse/ur1.c: New test.
|
||||
* gdb.reverse/until-reverse.exp: New test.
|
||||
* gdb.reverse/watch-reverse.c: New test.
|
||||
* gdb.reverse/watch-reverse.exp: New test.
|
||||
* configure.ac (AC_OUTPUT): Add gdb.reverse/Makefile.
|
||||
* configure: Regenerate.
|
||||
|
||||
2009-06-26 Doug Evans <dje@google.com>
|
||||
|
||||
* gdb.base/psymtab.exp: Turn off pending breakpoints.
|
||||
|
|
3
gdb/testsuite/configure
vendored
3
gdb/testsuite/configure
vendored
|
@ -3131,7 +3131,7 @@ done
|
|||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.server/Makefile gdb.java/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.objc/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
|
||||
ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.server/Makefile gdb.java/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.objc/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
# tests run on this system so they can be shared between configure
|
||||
|
@ -3699,6 +3699,7 @@ do
|
|||
"gdb.opt/Makefile" ) CONFIG_FILES="$CONFIG_FILES gdb.opt/Makefile" ;;
|
||||
"gdb.pascal/Makefile" ) CONFIG_FILES="$CONFIG_FILES gdb.pascal/Makefile" ;;
|
||||
"gdb.python/Makefile" ) CONFIG_FILES="$CONFIG_FILES gdb.python/Makefile" ;;
|
||||
"gdb.reverse/Makefile" ) CONFIG_FILES="$CONFIG_FILES gdb.reverse/Makefile" ;;
|
||||
"gdb.threads/Makefile" ) CONFIG_FILES="$CONFIG_FILES gdb.threads/Makefile" ;;
|
||||
"gdb.trace/Makefile" ) CONFIG_FILES="$CONFIG_FILES gdb.trace/Makefile" ;;
|
||||
"gdb.xml/Makefile" ) CONFIG_FILES="$CONFIG_FILES gdb.xml/Makefile" ;;
|
||||
|
|
|
@ -117,5 +117,5 @@ AC_OUTPUT([Makefile \
|
|||
gdb.fortran/Makefile gdb.server/Makefile \
|
||||
gdb.java/Makefile gdb.mi/Makefile gdb.modula2/Makefile \
|
||||
gdb.objc/Makefile gdb.opt/Makefile gdb.pascal/Makefile \
|
||||
gdb.python/Makefile \
|
||||
gdb.python/Makefile gdb.reverse/Makefile \
|
||||
gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile])
|
||||
|
|
19
gdb/testsuite/gdb.reverse/Makefile.in
Normal file
19
gdb/testsuite/gdb.reverse/Makefile.in
Normal file
|
@ -0,0 +1,19 @@
|
|||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
EXECUTABLES = break-reverse consecutive-reverse finish-reverse \
|
||||
machinestate solib-reverse step-reverse until-reverse \
|
||||
watch-reverse
|
||||
|
||||
MISCELLANEOUS =
|
||||
|
||||
all info install-info dvi install uninstall installcheck check:
|
||||
@echo "Nothing to be done for $@..."
|
||||
|
||||
clean mostlyclean:
|
||||
rm -f *~ *.o *.x *.ci *.sl a.out core
|
||||
rm -f $(EXECUTABLES) $(MISCELLANEOUS)
|
||||
|
||||
distclean maintainer-clean realclean: clean
|
||||
rm -f Makefile config.status config.log site.*
|
||||
|
37
gdb/testsuite/gdb.reverse/break-reverse.c
Normal file
37
gdb/testsuite/gdb.reverse/break-reverse.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2008, 2009 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/>. */
|
||||
|
||||
int xyz;
|
||||
|
||||
int bar ()
|
||||
{
|
||||
xyz = 2; /* break in bar */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int foo ()
|
||||
{
|
||||
xyz = 1; /* break in foo */
|
||||
return bar ();
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
xyz = 0; /* break in main */
|
||||
foo ();
|
||||
return (xyz == 2 ? 0 : 1);
|
||||
} /* end of main */
|
86
gdb/testsuite/gdb.reverse/break-reverse.exp
Normal file
86
gdb/testsuite/gdb.reverse/break-reverse.exp
Normal file
|
@ -0,0 +1,86 @@
|
|||
# Copyright 2008, 2009 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/>.
|
||||
|
||||
# This file is part of the GDB testsuite. It tests reverse debugging
|
||||
# with breakpoints.
|
||||
|
||||
if ![target_info exists gdb,can_reverse] {
|
||||
return
|
||||
}
|
||||
|
||||
set testfile "break-reverse"
|
||||
set srcfile ${testfile}.c
|
||||
|
||||
if { [prepare_for_testing $testfile.exp $testfile $srcfile] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
set foo_location [gdb_get_line_number "break in foo" ]
|
||||
set bar_location [gdb_get_line_number "break in bar" ]
|
||||
set main_location [gdb_get_line_number "break in main"]
|
||||
set end_location [gdb_get_line_number "end of main" ]
|
||||
|
||||
runto main
|
||||
|
||||
if [target_info exists gdb,use_precord] {
|
||||
# Activate process record/replay
|
||||
gdb_test "record" "" "Turn on process record"
|
||||
# FIXME: command ought to acknowledge, so we can test if it succeeded.
|
||||
}
|
||||
|
||||
gdb_test "break foo" \
|
||||
"Breakpoint $decimal at .* line $foo_location\." \
|
||||
"set breakpoint on foo"
|
||||
|
||||
gdb_test "break bar" \
|
||||
"Breakpoint $decimal at .* line $bar_location\." \
|
||||
"set breakpoint on bar"
|
||||
|
||||
gdb_test "break $end_location" \
|
||||
"Breakpoint $decimal at .* line $end_location\." \
|
||||
set breakpoint at end of main"
|
||||
|
||||
gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
|
||||
gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
|
||||
gdb_continue_to_breakpoint "end" ".*/$srcfile:$end_location.*"
|
||||
|
||||
# FIXME 'set exec-dir' command should give some output so we can test.
|
||||
gdb_test "set exec-direction reverse" "" "set reverse"
|
||||
|
||||
gdb_continue_to_breakpoint "bar backward" ".*/$srcfile:$bar_location.*"
|
||||
gdb_continue_to_breakpoint "foo backward" ".*/$srcfile:$foo_location.*"
|
||||
|
||||
gdb_test_multiple "continue" "main backward" {
|
||||
-re ".*Breakpoint $decimal,.*/$srcfile:$main_location.*$gdb_prompt $" {
|
||||
pass "main backward"
|
||||
}
|
||||
-re "No more reverse-execution history.* break in main .*$gdb_prompt $" {
|
||||
pass "main backward"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "set exec-direction forward" "" "set forward"
|
||||
|
||||
gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
|
||||
gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
|
||||
|
||||
gdb_test_multiple "continue" "end of record log" {
|
||||
-re ".*Breakpoint $decimal,.*/$srcfile:$end_location.*$gdb_prompt $" {
|
||||
pass "end of record log"
|
||||
}
|
||||
-re "No more reverse-execution history.* end of main .*$gdb_prompt $" {
|
||||
pass "end of record log"
|
||||
}
|
||||
}
|
37
gdb/testsuite/gdb.reverse/consecutive-reverse.c
Normal file
37
gdb/testsuite/gdb.reverse/consecutive-reverse.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2008, 2009 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/>. */
|
||||
|
||||
/*
|
||||
Purpose of this test: to test breakpoints on consecutive instructions.
|
||||
*/
|
||||
|
||||
int a[7] = {1, 2, 3, 4, 5, 6, 7};
|
||||
|
||||
/* assert: first line of foo has more than one instruction. */
|
||||
int foo ()
|
||||
{
|
||||
return a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6];
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
#ifdef usestubs
|
||||
set_debug_traps ();
|
||||
breakpoint ();
|
||||
#endif
|
||||
foo ();
|
||||
}
|
125
gdb/testsuite/gdb.reverse/consecutive-reverse.exp
Normal file
125
gdb/testsuite/gdb.reverse/consecutive-reverse.exp
Normal file
|
@ -0,0 +1,125 @@
|
|||
# Copyright 2008, 2009 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/>.
|
||||
|
||||
# This file is part of the GDB testsuite. It tests stepping over
|
||||
# consecutive instructions in reverse.
|
||||
|
||||
if ![target_info exists gdb,can_reverse] {
|
||||
return
|
||||
}
|
||||
|
||||
set testfile "consecutive-reverse"
|
||||
set srcfile ${testfile}.c
|
||||
|
||||
if { [prepare_for_testing $testfile.exp $testfile $srcfile] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
runto main
|
||||
|
||||
if [target_info exists gdb,use_precord] {
|
||||
# Activate process record/replay
|
||||
gdb_test "record" "" "Turn on process record"
|
||||
# FIXME: command ought to acknowledge, so we can test if it succeeded.
|
||||
}
|
||||
|
||||
gdb_breakpoint foo
|
||||
gdb_test "continue" "Breakpoint $decimal, foo .*" \
|
||||
"continue to breakpoint in foo"
|
||||
|
||||
set foo1_addr 0
|
||||
set foo2_addr 0
|
||||
set stop_addr 0
|
||||
|
||||
send_gdb "x /2i \$pc\n"
|
||||
gdb_expect {
|
||||
global hex
|
||||
global foo1_addr
|
||||
global foo2_addr
|
||||
global gdb_prompt
|
||||
|
||||
-re "($hex).*\[\r\n\]+($hex).*$gdb_prompt $" {
|
||||
set foo1_addr $expect_out(1,string)
|
||||
set foo2_addr $expect_out(2,string)
|
||||
pass "get breakpoint address for foo"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
fail "get breakpoint address for foo"
|
||||
return 0;
|
||||
}
|
||||
timeout {
|
||||
fail "get breakpoint address for foo (timeout)"
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "break \*$foo2_addr" "Breakpoint $decimal at $foo2_addr: file .*" \
|
||||
"set bp, 2nd instr"
|
||||
|
||||
send_gdb "step\n"
|
||||
gdb_expect {
|
||||
-re "Breakpoint $decimal, ($hex) in foo.*$gdb_prompt $" {
|
||||
set stop_addr $expect_out(1,string)
|
||||
if [eval expr "$foo2_addr == $stop_addr"] then {
|
||||
pass "stopped at bp, 2nd instr"
|
||||
} else {
|
||||
fail "stopped at bp, 2nd instr (wrong address)"
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
fail "stopped at bp, 2nd instr"
|
||||
}
|
||||
timeout {
|
||||
fail "stopped at bp, 2nd instr (timeout)"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
###
|
||||
###
|
||||
###
|
||||
|
||||
# Set reverse execution direction
|
||||
# FIXME: command needs to acknowledge, so we can test if it succeeded.
|
||||
|
||||
gdb_test "set exec-dir reverse" "" "set reverse execution"
|
||||
|
||||
# Now step backward and hope to hit the first breakpoint.
|
||||
|
||||
set test_msg "stopped at bp in reverse, 1st instr"
|
||||
gdb_test_multiple "step" "$test_msg" {
|
||||
-re "Breakpoint $decimal, ($hex) in foo.*$gdb_prompt $" {
|
||||
set stop_addr $expect_out(1,string)
|
||||
if [eval expr "$foo1_addr == $stop_addr"] then {
|
||||
pass "$test_msg"
|
||||
} else {
|
||||
fail "$test_msg (wrong address)"
|
||||
}
|
||||
}
|
||||
-re "Breakpoint $decimal, foo.*$gdb_prompt $" {
|
||||
send_gdb "print \$pc == $foo1_addr\n"
|
||||
gdb_expect {
|
||||
-re "$decimal = 1\[\r\n\]+$gdb_prompt $" {
|
||||
pass "$test_msg"
|
||||
}
|
||||
-re "$decimal = 0\[\r\n\]+$gdb_prompt $" {
|
||||
fail "$test_msg (wrong address)"
|
||||
}
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
fail "$test_msg"
|
||||
}
|
||||
}
|
127
gdb/testsuite/gdb.reverse/finish-reverse.c
Normal file
127
gdb/testsuite/gdb.reverse/finish-reverse.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2008, 2009 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 "return" command in reverse. */
|
||||
|
||||
int void_test = 0;
|
||||
int main_test = 0;
|
||||
|
||||
char char_returnval = '1';
|
||||
short short_returnval = 1;
|
||||
int int_returnval = 1;
|
||||
long long_returnval = 1;
|
||||
long long long_long_returnval = 1;
|
||||
float float_returnval = 1;
|
||||
double double_returnval = 1;
|
||||
|
||||
union {
|
||||
char char_testval;
|
||||
short short_testval;
|
||||
int int_testval;
|
||||
long long_testval;
|
||||
long long long_long_testval;
|
||||
float float_testval;
|
||||
double double_testval;
|
||||
char ffff[80];
|
||||
} testval;
|
||||
|
||||
void void_func ()
|
||||
{
|
||||
void_test = 1; /* VOID FUNC */
|
||||
}
|
||||
|
||||
char char_func ()
|
||||
{
|
||||
return char_returnval; /* CHAR FUNC */
|
||||
}
|
||||
|
||||
short short_func ()
|
||||
{
|
||||
return short_returnval; /* SHORT FUNC */
|
||||
}
|
||||
|
||||
int int_func ()
|
||||
{
|
||||
return int_returnval; /* INT FUNC */
|
||||
}
|
||||
|
||||
long long_func ()
|
||||
{
|
||||
return long_returnval; /* LONG FUNC */
|
||||
}
|
||||
|
||||
long long long_long_func ()
|
||||
{
|
||||
return long_long_returnval; /* LONG LONG FUNC */
|
||||
}
|
||||
|
||||
float float_func ()
|
||||
{
|
||||
return float_returnval; /* FLOAT FUNC */
|
||||
}
|
||||
|
||||
double double_func ()
|
||||
{
|
||||
return double_returnval; /* DOUBLE FUNC */
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
char char_resultval;
|
||||
short short_resultval;
|
||||
int int_resultval;
|
||||
long long_resultval;
|
||||
long long long_long_resultval;
|
||||
float float_resultval;
|
||||
double double_resultval;
|
||||
int i;
|
||||
|
||||
/* A "test load" that will insure that the function really returns
|
||||
a ${type} (as opposed to just a truncated or part of a ${type}). */
|
||||
for (i = 0; i < sizeof (testval.ffff); i++)
|
||||
testval.ffff[i] = 0xff;
|
||||
|
||||
void_func (); /* call to void_func */
|
||||
char_resultval = char_func (); /* void_checkpoint */
|
||||
short_resultval = short_func (); /* char_checkpoint */
|
||||
int_resultval = int_func (); /* short_checkpoint */
|
||||
long_resultval = long_func (); /* int_checkpoint */
|
||||
long_long_resultval = long_long_func (); /* long_checkpoint */
|
||||
|
||||
/* On machines using IEEE floating point, the test pattern of all
|
||||
1-bits established above turns out to be a floating-point NaN
|
||||
("Not a Number"). According to the IEEE rules, NaN's aren't even
|
||||
equal to themselves. This can lead to stupid conversations with
|
||||
GDB like:
|
||||
|
||||
(gdb) p testval.float_testval == testval.float_testval
|
||||
$7 = 0
|
||||
(gdb)
|
||||
|
||||
This is the correct answer, but it's not the sort of thing
|
||||
return2.exp wants to see. So to make things work the way they
|
||||
ought, we'll set aside the `union' cleverness and initialize the
|
||||
test values explicitly here. These values have interesting bits
|
||||
throughout the value, so we'll still detect truncated values. */
|
||||
|
||||
testval.float_testval = 2.7182818284590452354;/* long_long_checkpoint */
|
||||
float_resultval = float_func ();
|
||||
testval.double_testval = 3.14159265358979323846; /* float_checkpoint */
|
||||
double_resultval = double_func ();
|
||||
main_test = 1; /* double_checkpoint */
|
||||
return 0;
|
||||
}
|
260
gdb/testsuite/gdb.reverse/finish-reverse.exp
Normal file
260
gdb/testsuite/gdb.reverse/finish-reverse.exp
Normal file
|
@ -0,0 +1,260 @@
|
|||
# Copyright 2008, 2009 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/>.
|
||||
|
||||
# This file is part of the GDB testsuite. It tests 'finish' with
|
||||
# reverse debugging.
|
||||
|
||||
if ![target_info exists gdb,can_reverse] {
|
||||
return
|
||||
}
|
||||
|
||||
set testfile "finish-reverse"
|
||||
set srcfile ${testfile}.c
|
||||
|
||||
if { [prepare_for_testing $testfile.exp "$testfile" $srcfile] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
proc test_start_of_line { line_text test_msg } {
|
||||
global gdb_prompt
|
||||
global decimal
|
||||
global hex
|
||||
|
||||
send_gdb "info line\n"
|
||||
gdb_expect {
|
||||
-re "Line $decimal of .* starts at address ($hex) .*$gdb_prompt $" {
|
||||
set line_begin $expect_out(1,string)
|
||||
}
|
||||
default {
|
||||
fail "Get line address in test_start_of_line"
|
||||
}
|
||||
}
|
||||
send_gdb "info reg pc\n"
|
||||
gdb_expect {
|
||||
-re ".*: ($hex)\r\n*$gdb_prompt $" {
|
||||
set stop_pc $expect_out(1,string)
|
||||
}
|
||||
default {
|
||||
fail"Get stop pc in test_start_of_line"
|
||||
}
|
||||
}
|
||||
gdb_test "print $line_begin == $stop_pc" \
|
||||
" = 1\[\r\n\]*" \
|
||||
"test_start_of_line, $test_msg"
|
||||
}
|
||||
|
||||
runto main
|
||||
|
||||
if [target_info exists gdb,use_precord] {
|
||||
# Activate process record/replay
|
||||
gdb_test "record" "" "Turn on process record"
|
||||
# FIXME: command ought to acknowledge, so we can test if it succeeded.
|
||||
}
|
||||
|
||||
# Test finish from void func
|
||||
|
||||
set breakloc [gdb_get_line_number "VOID FUNC" "$srcfile"]
|
||||
gdb_test "break void_func" \
|
||||
"Breakpoint $decimal at .*/$srcfile, line $breakloc\." \
|
||||
"set breakpoint on void_func"
|
||||
gdb_continue_to_breakpoint "void_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "finish from void_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re " call to void_func .*$gdb_prompt $" {
|
||||
send_gdb "step\n"
|
||||
exp_continue
|
||||
}
|
||||
-re " void_checkpoint .*$gdb_prompt $" {
|
||||
pass "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test finish from char func
|
||||
|
||||
set breakloc [gdb_get_line_number "CHAR FUNC" "$srcfile"]
|
||||
gdb_test "break char_func" \
|
||||
"Breakpoint $decimal at .*/$srcfile, line $breakloc\." \
|
||||
"set breakpoint on char_func"
|
||||
gdb_continue_to_breakpoint "char_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "finish from char_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re " void_checkpoint .*$gdb_prompt $" {
|
||||
send_gdb "step\n"
|
||||
exp_continue
|
||||
}
|
||||
-re " char_checkpoint .*$gdb_prompt $" {
|
||||
pass "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test finish from short func
|
||||
|
||||
set breakloc [gdb_get_line_number "SHORT FUNC" "$srcfile"]
|
||||
gdb_test "break short_func" \
|
||||
"Breakpoint $decimal at .* line $breakloc\." \
|
||||
"set breakpoint on short_func"
|
||||
gdb_continue_to_breakpoint "short_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "finish from short_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re " char_checkpoint .*$gdb_prompt $" {
|
||||
send_gdb "step\n"
|
||||
exp_continue
|
||||
}
|
||||
-re " short_checkpoint .*$gdb_prompt $" {
|
||||
pass "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test finish from int func
|
||||
|
||||
set breakloc [gdb_get_line_number "INT FUNC" "$srcfile"]
|
||||
gdb_test "break int_func" \
|
||||
"Breakpoint $decimal at .* line $breakloc\." \
|
||||
"set breakpoint on int_func"
|
||||
gdb_continue_to_breakpoint "int_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "finish from int_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re " short_checkpoint .*$gdb_prompt $" {
|
||||
send_gdb "step\n"
|
||||
exp_continue
|
||||
}
|
||||
-re " int_checkpoint .*$gdb_prompt $" {
|
||||
pass "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test finish from long func
|
||||
|
||||
set breakloc [gdb_get_line_number "LONG FUNC" "$srcfile"]
|
||||
gdb_test "break long_func" \
|
||||
"Breakpoint $decimal at .* line $breakloc\." \
|
||||
"set breakpoint on long_func"
|
||||
gdb_continue_to_breakpoint "long_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "finish from long_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re " int_checkpoint .*$gdb_prompt $" {
|
||||
send_gdb "step\n"
|
||||
exp_continue
|
||||
}
|
||||
-re " long_checkpoint .*$gdb_prompt $" {
|
||||
pass "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test finish from long long func
|
||||
|
||||
set breakloc [gdb_get_line_number "LONG LONG FUNC" "$srcfile"]
|
||||
gdb_test "break long_long_func" \
|
||||
"Breakpoint $decimal at .* line $breakloc\." \
|
||||
"set breakpoint on long_long_func"
|
||||
gdb_continue_to_breakpoint "long_long_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "finish from long_long_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re " long_checkpoint .*$gdb_prompt $" {
|
||||
send_gdb "step\n"
|
||||
exp_continue
|
||||
}
|
||||
-re " long_long_checkpoint .*$gdb_prompt $" {
|
||||
pass "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
###
|
||||
###
|
||||
###
|
||||
|
||||
# Now switch to reverse
|
||||
gdb_test "set exec-dir reverse" "" "set reverse execution"
|
||||
|
||||
# Test reverse finish from long long func
|
||||
|
||||
set breakloc [gdb_get_line_number "LONG LONG FUNC" "$srcfile"]
|
||||
gdb_continue_to_breakpoint "long_long_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "reverse finish from long_long_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re ".* long_checkpoint.*$gdb_prompt $" {
|
||||
test_start_of_line "long_checkpoint" "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test reverse finish from long func
|
||||
|
||||
set breakloc [gdb_get_line_number "LONG FUNC" "$srcfile"]
|
||||
gdb_continue_to_breakpoint "long_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "reverse finish from long_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re ".* int_checkpoint.*$gdb_prompt $" {
|
||||
test_start_of_line "int_checkpoint" "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test reverse finish from int func
|
||||
|
||||
set breakloc [gdb_get_line_number "INT FUNC" "$srcfile"]
|
||||
gdb_continue_to_breakpoint "int_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "reverse finish from int_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re ".* short_checkpoint.*$gdb_prompt $" {
|
||||
test_start_of_line "short_checkpoint" "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test reverse finish from short func
|
||||
|
||||
set breakloc [gdb_get_line_number "SHORT FUNC" "$srcfile"]
|
||||
gdb_continue_to_breakpoint "short_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "reverse finish from short_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re ".* char_checkpoint.*$gdb_prompt $" {
|
||||
test_start_of_line "char_checkpoint" "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test reverse finish from char func
|
||||
|
||||
set breakloc [gdb_get_line_number "CHAR FUNC" "$srcfile"]
|
||||
gdb_continue_to_breakpoint "char_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "reverse finish from char_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re ".* void_checkpoint.*$gdb_prompt $" {
|
||||
test_start_of_line "void_checkpoint" "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
# Test reverse finish from void func
|
||||
|
||||
set breakloc [gdb_get_line_number "VOID FUNC" "$srcfile"]
|
||||
gdb_continue_to_breakpoint "void_func" ".*/$srcfile:$breakloc.*"
|
||||
|
||||
set test_msg "reverse finish from void_func"
|
||||
gdb_test_multiple "finish" "$test_msg" {
|
||||
-re ".* call to void_func.*$gdb_prompt $" {
|
||||
test_start_of_line "call to void_func" "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
101
gdb/testsuite/gdb.reverse/machinestate.c
Normal file
101
gdb/testsuite/gdb.reverse/machinestate.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2008, 2009 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 restoration of machine state
|
||||
*/
|
||||
|
||||
extern void hide (int);
|
||||
|
||||
/* Test register variable
|
||||
Requires -- compiler honors 'register'. */
|
||||
|
||||
void
|
||||
register_state (void)
|
||||
{
|
||||
register int a = 0;
|
||||
|
||||
hide (a); /* External function to defeat optimization. */
|
||||
a++; /* register_state: set breakpoint here */
|
||||
hide (a); /* register post-change */
|
||||
}
|
||||
|
||||
/* Test auto variable (whatever that means). */
|
||||
|
||||
void
|
||||
auto_state (void)
|
||||
{
|
||||
auto int a = 0;
|
||||
|
||||
hide (a); /* External function to defeat optimization. */
|
||||
a++; /* auto_state: set breakpoint here */
|
||||
hide (a); /* auto post-change */
|
||||
}
|
||||
|
||||
/* Test function-static variable. */
|
||||
|
||||
void
|
||||
function_static_state (void)
|
||||
{
|
||||
static int a = 0;
|
||||
|
||||
hide (a); /* External function to defeat optimization. */
|
||||
a++; /* function_static_state: set breakpoint here */
|
||||
hide (a); /* function static post-change */
|
||||
}
|
||||
|
||||
/* Test module-static variable. */
|
||||
|
||||
static int astatic;
|
||||
|
||||
void
|
||||
module_static_state (void)
|
||||
{
|
||||
astatic = 0;
|
||||
|
||||
hide (astatic); /* External function to defeat optimization. */
|
||||
astatic++; /* module_static_state: set breakpoint here */
|
||||
hide (astatic); /* module static post-change */
|
||||
}
|
||||
|
||||
/* Test module-global variable. */
|
||||
|
||||
int aglobal;
|
||||
|
||||
void
|
||||
module_global_state (void)
|
||||
{
|
||||
aglobal = 0;
|
||||
|
||||
hide (aglobal); /* External function to defeat optimization. */
|
||||
aglobal++; /* module_global_state: set breakpoint here */
|
||||
hide (aglobal); /* module global post-change */
|
||||
}
|
||||
|
||||
/* main test driver */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
register_state (); /* begin main */
|
||||
auto_state ();
|
||||
function_static_state ();
|
||||
module_static_state ();
|
||||
module_global_state ();
|
||||
|
||||
return 0; /* end main */
|
||||
}
|
230
gdb/testsuite/gdb.reverse/machinestate.exp
Normal file
230
gdb/testsuite/gdb.reverse/machinestate.exp
Normal file
|
@ -0,0 +1,230 @@
|
|||
# Copyright 2008, 2009 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/>.
|
||||
|
||||
# This file is part of the GDB testsuite.
|
||||
# This test tests the restoration of various kinds of machine state
|
||||
# to their original values by reverse execution. We will execute
|
||||
# the program forward while it changes various types of data, and
|
||||
# then execute it backward to see if their values get restored.
|
||||
#
|
||||
# The types of machine state (data) that are tested are:
|
||||
# register variable
|
||||
# auto variable
|
||||
# function static variable
|
||||
# module static variable
|
||||
# module global variable
|
||||
#
|
||||
# TODO:
|
||||
# various, possibly including...
|
||||
# .bss variable, .data variable, ...
|
||||
# shared library variable
|
||||
# heap variable (pointer)...
|
||||
# overlay variables...
|
||||
# Test forward replay
|
||||
#
|
||||
|
||||
if ![target_info exists gdb,can_reverse] {
|
||||
return
|
||||
}
|
||||
|
||||
set testfile "machinestate"
|
||||
set srcfile ${testfile}.c
|
||||
set srcfile1 ms1.c
|
||||
|
||||
if { [prepare_for_testing $testfile.exp $testfile {machinestate.c ms1.c} ] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
set newline "\[\r\n\]+"
|
||||
|
||||
set beginmain [gdb_get_line_number " begin main " $srcfile]
|
||||
set endmain [gdb_get_line_number " end main " $srcfile]
|
||||
|
||||
# Test begins
|
||||
|
||||
runto main
|
||||
|
||||
if [target_info exists gdb,use_precord] {
|
||||
# Activate process record/replay
|
||||
gdb_test "record" "" "Turn on process record"
|
||||
# FIXME: command ought to acknowledge, so we can test if it succeeded.
|
||||
}
|
||||
|
||||
# Proceed to end of main
|
||||
|
||||
gdb_test "break $endmain" \
|
||||
"Breakpoint.* file .*/$srcfile, line $endmain.*" ""
|
||||
gdb_continue_to_breakpoint "end of main" ".*/$srcfile:$endmain.*"
|
||||
|
||||
###
|
||||
###
|
||||
###
|
||||
|
||||
# Now run backward to each of several points where data is changed.
|
||||
#
|
||||
|
||||
# Module global variable, reverse
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"module_global_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "reverse-continue" ".*/$srcfile:$breakloc.*" "reverse to $breakloc"
|
||||
|
||||
gdb_test "print aglobal" ".* = 0$newline" "module global reverse-breakpoint"
|
||||
gdb_test "step" ".* module global post-change .*" ""
|
||||
gdb_test "print aglobal" ".* = 1$newline" "module global forward past bp"
|
||||
gdb_test "reverse-step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print aglobal" ".* = 0$newline" "module global reverse-step to bp"
|
||||
|
||||
|
||||
# Module static variable, reverse
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"module_static_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "reverse-continue" ".*/$srcfile:$breakloc.*" "reverse to $breakloc"
|
||||
|
||||
gdb_test "print astatic" ".* = 0$newline" "module static reverse-breakpoint"
|
||||
gdb_test "step" ".* module static post-change .*" ""
|
||||
gdb_test "print astatic" ".* = 1$newline" "module static forward"
|
||||
gdb_test "reverse-step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print astatic" ".* = 0$newline" "module static reverse-step"
|
||||
|
||||
# Function static variable, reverse
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"function_static_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "reverse-continue" ".*/$srcfile:$breakloc.*" "reverse to $breakloc"
|
||||
|
||||
gdb_test "print a" ".* = 0$newline" "function static reverse-breakpoint"
|
||||
gdb_test "step" ".* function static post-change .*" ""
|
||||
gdb_test "print a" ".* = 1$newline" "function static forward"
|
||||
gdb_test "reverse-step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print a" ".* = 0$newline" "function static reverse-step"
|
||||
|
||||
# Auto variable, reverse
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"auto_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "reverse-continue" ".*/$srcfile:$breakloc.*" "reverse to $breakloc"
|
||||
|
||||
gdb_test "print a" ".* = 0$newline" "auto var reverse-breakpoint"
|
||||
gdb_test "step" ".* auto post-change .*" ""
|
||||
gdb_test "print a" ".* = 1$newline" "auto var forward"
|
||||
gdb_test "reverse-step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print a" ".* = 0$newline" "auto var reverse-step"
|
||||
|
||||
# Register variable, reverse
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"register_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "reverse-continue" ".*/$srcfile:$breakloc.*" "reverse to $breakloc"
|
||||
|
||||
gdb_test "print a" ".* = 0$newline" "register var reverse-breakpoint"
|
||||
gdb_test "step" ".* register post-change .*" ""
|
||||
gdb_test "print a" ".* = 1$newline" "register var step post-change"
|
||||
gdb_test "reverse-step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print a" ".* = 0$newline" "register var reverse step-to"
|
||||
|
||||
# Proceed to beginning of main
|
||||
|
||||
gdb_test "tbreak $beginmain" ".*/$srcfile, line $beginmain.*" ""
|
||||
gdb_test "reverse-continue" ".*/$srcfile:$beginmain.*" "reverse to main"
|
||||
|
||||
# Now repeat tests while replaying forward.
|
||||
|
||||
# Register variable, forward
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"register_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "continue" ".*/$srcfile:$breakloc.*" "forward to $breakloc"
|
||||
|
||||
gdb_test "print a" ".* = 0$newline" "register var forward-breakpoint"
|
||||
gdb_test "reverse-step" ".*hide.*" ""
|
||||
gdb_test "step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print a" ".* = 0$newline" "register var forward step-to"
|
||||
gdb_test "step" ".* register post-change .*" ""
|
||||
gdb_test "print a" ".* = 1$newline" "register var step post-change"
|
||||
|
||||
# Auto variable, forward
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"auto_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "continue" ".*/$srcfile:$breakloc.*" "forward to $breakloc"
|
||||
|
||||
gdb_test "print a" ".* = 0$newline" "auto var forward-breakpoint"
|
||||
gdb_test "reverse-step" ".*hide.*" ""
|
||||
gdb_test "step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print a" ".* = 0$newline" "auto var forward step-to"
|
||||
gdb_test "step" ".* auto post-change .*" ""
|
||||
gdb_test "print a" ".* = 1$newline" "auto var step post-change"
|
||||
|
||||
# Function static variable, forward
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"function_static_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "continue" ".*/$srcfile:$breakloc.*" "forward to $breakloc"
|
||||
|
||||
gdb_test "print a" ".* = 0$newline" "function static forward-breakpoint"
|
||||
gdb_test "reverse-step" ".*hide.*" ""
|
||||
gdb_test "step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print a" ".* = 0$newline" "function static forward step-to"
|
||||
gdb_test "step" ".* function static post-change .*" ""
|
||||
gdb_test "print a" ".* = 1$newline" "function static step post-change"
|
||||
|
||||
# Module static variable, forward
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"module_static_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "continue" ".*/$srcfile:$breakloc.*" "forward to $breakloc"
|
||||
|
||||
gdb_test "print astatic" ".* = 0$newline" "module static forward-breakpoint"
|
||||
gdb_test "reverse-step" ".*hide.*" ""
|
||||
gdb_test "step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print astatic" ".* = 0$newline" "module static forward step-to"
|
||||
gdb_test "step" ".* module static post-change .*" ""
|
||||
gdb_test "print astatic" ".* = 1$newline" "module static step post-change"
|
||||
|
||||
# Module global variable, forward
|
||||
|
||||
set breakloc [gdb_get_line_number \
|
||||
"module_global_state: set breakpoint here" $srcfile]
|
||||
|
||||
gdb_test "tbreak $breakloc" ".*/$srcfile, line $breakloc.*" ""
|
||||
gdb_test "continue" ".*/$srcfile:$breakloc.*" "forward to $breakloc"
|
||||
|
||||
gdb_test "print aglobal" ".* = 0$newline" "module global forward-breakpoint"
|
||||
gdb_test "reverse-step" ".*hide.*" ""
|
||||
gdb_test "step" ".*$newline$breakloc.*" ""
|
||||
gdb_test "print aglobal" ".* = 0$newline" "module global forward step-to"
|
||||
gdb_test "step" ".* module global post-change .*" ""
|
||||
gdb_test "print aglobal" ".* = 1$newline" "module global step post-change"
|
||||
|
25
gdb/testsuite/gdb.reverse/ms1.c
Normal file
25
gdb/testsuite/gdb.reverse/ms1.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* 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/>. */
|
||||
|
||||
/*
|
||||
* Aux function for machine state test.
|
||||
*/
|
||||
|
||||
void
|
||||
hide (int x)
|
||||
{
|
||||
}
|
34
gdb/testsuite/gdb.reverse/shr2.c
Normal file
34
gdb/testsuite/gdb.reverse/shr2.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2009 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/>. */
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int shr2(int x)
|
||||
#else
|
||||
int shr2(x) int x;
|
||||
#endif
|
||||
{
|
||||
return 2*x;
|
||||
}
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int shr2_local(int x)
|
||||
#else
|
||||
int shr2_local(x) int x;
|
||||
#endif
|
||||
{
|
||||
return 2*x;
|
||||
}
|
43
gdb/testsuite/gdb.reverse/solib-reverse.c
Normal file
43
gdb/testsuite/gdb.reverse/solib-reverse.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2009 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 reverse debugging of shared libraries. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Shared library function */
|
||||
extern int shr2(int);
|
||||
|
||||
int main ()
|
||||
{
|
||||
char* cptr = "String 1";
|
||||
int b[2] = {5,8};
|
||||
|
||||
b[0] = shr2(12); /* begin part two */
|
||||
b[1] = shr2(17); /* middle part two */
|
||||
|
||||
b[0] = 6; b[1] = 9; /* generic statement, end part two */
|
||||
printf ("message 1\n"); /* printf one */
|
||||
printf ("message 2\n"); /* printf two */
|
||||
printf ("message 3\n"); /* printf three */
|
||||
sleep (0); /* sleep one */
|
||||
sleep (0); /* sleep two */
|
||||
sleep (0); /* sleep three */
|
||||
|
||||
return 0; /* end part one */
|
||||
}
|
||||
|
124
gdb/testsuite/gdb.reverse/solib-reverse.exp
Normal file
124
gdb/testsuite/gdb.reverse/solib-reverse.exp
Normal file
|
@ -0,0 +1,124 @@
|
|||
# Copyright 2009
|
||||
# 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/>.
|
||||
|
||||
# This file is part of the GDB testsuite. It tests reverse debugging
|
||||
# with shared libraries.
|
||||
|
||||
if ![target_info exists gdb,can_reverse] {
|
||||
return
|
||||
}
|
||||
|
||||
set testfile "solib-reverse"
|
||||
set srcfile ${testfile}.c
|
||||
set libfile "shr2"
|
||||
set libsrc ${libfile}.c
|
||||
set library ${objdir}/${subdir}/${libfile}.sl
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
|
||||
if [get_compiler_info ${binfile}] {
|
||||
return -1
|
||||
}
|
||||
|
||||
if { [gdb_compile_shlib ${srcdir}/${subdir}/${libsrc} ${library} "debug"] != "" } {
|
||||
untested "Could not compile shared library."
|
||||
return -1
|
||||
}
|
||||
|
||||
set exec_opts [list debug shlib=${library}]
|
||||
|
||||
if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable $exec_opts] != "" } {
|
||||
untested "Could not compile $binfile."
|
||||
return -1
|
||||
}
|
||||
|
||||
# Start with a fresh gdb.
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
|
||||
runto main
|
||||
|
||||
if [target_info exists gdb,use_precord] {
|
||||
# Activate process record/replay
|
||||
gdb_test "record" "" "Turn on process record"
|
||||
# FIXME: command ought to acknowledge, so we can test if it succeeded.
|
||||
}
|
||||
|
||||
#
|
||||
# Test reverse-step over undebuggable solib functions.
|
||||
#
|
||||
|
||||
# Run forward past some solib function calls.
|
||||
|
||||
set end_part_one [gdb_get_line_number " end part one" "$srcfile"]
|
||||
set end_part_two [gdb_get_line_number " end part two" "$srcfile"]
|
||||
gdb_test "until $end_part_one" " end part one.*" "run until end part one"
|
||||
|
||||
gdb_test "reverse-step" " sleep three .*" "reverse-step third sleep"
|
||||
gdb_test "reverse-step" " sleep two .*" "reverse-step second sleep"
|
||||
gdb_test "reverse-step" " sleep one .*" \
|
||||
"reverse-step first sleep, dynsym resolve"
|
||||
|
||||
gdb_test "reverse-step" " printf three .*" "reverse-step third printf"
|
||||
gdb_test "reverse-step" " printf two .*" "reverse-step second printf"
|
||||
gdb_test "reverse-step" " printf one .*" \
|
||||
"reverse-step first printf, dynsym resolve"
|
||||
gdb_test "reverse-step" " generic statement.*" "reverse-step generic"
|
||||
|
||||
|
||||
#
|
||||
# Test reverse-next over undebuggable solib functions.
|
||||
#
|
||||
|
||||
# Run forward again...
|
||||
|
||||
gdb_test "until $end_part_one" " end part one.*" "forward to end part one"
|
||||
|
||||
gdb_test "reverse-next" " sleep three .*" "reverse-next third sleep"
|
||||
gdb_test "reverse-next" " sleep two .*" "reverse-next second sleep"
|
||||
gdb_test "reverse-next" " sleep one .*" \
|
||||
"reverse-next first sleep, dynsym resolve"
|
||||
|
||||
gdb_test "reverse-next" " printf three .*" "reverse-next third printf"
|
||||
gdb_test "reverse-next" " printf two .*" "reverse-next second printf"
|
||||
gdb_test "reverse-next" " printf one .*" \
|
||||
"reverse-next first printf, dynsym resolve"
|
||||
gdb_test "reverse-next" " generic statement.*" "reverse-next generic"
|
||||
|
||||
|
||||
#
|
||||
# Test reverse-step into debuggable solib function
|
||||
#
|
||||
|
||||
gdb_test "reverse-step" "${libsrc}.*" "reverse-step into solib function one"
|
||||
gdb_test "reverse-step" "return 2.x.*" "reverse-step within solib function one"
|
||||
gdb_test "reverse-step" " middle part two.*" "reverse-step back to main one"
|
||||
|
||||
gdb_test "reverse-step" "${libsrc}.*" "reverse-step into solib function two"
|
||||
gdb_test "reverse-step" "return 2.x.*" "reverse-step within solib function two"
|
||||
gdb_test "reverse-step" " begin part two.*" "reverse-step back to main two"
|
||||
|
||||
#
|
||||
# Test reverse-next over debuggable solib function
|
||||
#
|
||||
|
||||
gdb_test "until $end_part_two" " end part two.*" "run until end part two"
|
||||
|
||||
gdb_test "reverse-next" " middle part two.*" "reverse-next over solib function one"
|
||||
gdb_test "reverse-next" " begin part two.*" "reverse-next over solib function two"
|
78
gdb/testsuite/gdb.reverse/step-reverse.c
Normal file
78
gdb/testsuite/gdb.reverse/step-reverse.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2008, 2009 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Test various kinds of stepping.
|
||||
*/
|
||||
int myglob = 0;
|
||||
|
||||
int callee() { /* ENTER CALLEE */
|
||||
myglob++; return 0; /* ARRIVED IN CALLEE */
|
||||
} /* RETURN FROM CALLEE */
|
||||
|
||||
/* A structure which, we hope, will need to be passed using memcpy. */
|
||||
struct rhomboidal {
|
||||
int rather_large[100];
|
||||
};
|
||||
|
||||
void
|
||||
large_struct_by_value (struct rhomboidal r)
|
||||
{
|
||||
myglob += r.rather_large[42]; /* step-test.exp: arrive here 1 */
|
||||
}
|
||||
|
||||
int main () {
|
||||
int w,x,y,z;
|
||||
int a[10], b[10];
|
||||
|
||||
/* Test "next" and "step" */
|
||||
w = 0; /* BREAK AT MAIN */
|
||||
x = 1; /* NEXT TEST 1 */
|
||||
y = 2; /* STEP TEST 1 */
|
||||
z = 3; /* REVERSE NEXT TEST 1 */
|
||||
w = w + 2; /* NEXT TEST 2 */
|
||||
x = x + 3; /* REVERSE STEP TEST 1 */
|
||||
y = y + 4;
|
||||
z = z + 5; /* STEP TEST 2 */
|
||||
|
||||
/* Test that "next" goes over a call */
|
||||
callee(); /* NEXT OVER THIS CALL */
|
||||
|
||||
/* Test that "step" doesn't */
|
||||
callee(); /* STEP INTO THIS CALL */
|
||||
|
||||
/* Test "stepi" */
|
||||
a[5] = a[3] - a[4]; /* FINISH TEST */
|
||||
callee(); /* STEPI TEST */
|
||||
|
||||
/* Test "nexti" */
|
||||
callee(); /* NEXTI TEST */
|
||||
|
||||
y = w + z;
|
||||
|
||||
{
|
||||
struct rhomboidal r;
|
||||
memset (r.rather_large, 0, sizeof (r.rather_large));
|
||||
r.rather_large[42] = 10;
|
||||
large_struct_by_value (r); /* step-test.exp: large struct by value */
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
251
gdb/testsuite/gdb.reverse/step-reverse.exp
Normal file
251
gdb/testsuite/gdb.reverse/step-reverse.exp
Normal file
|
@ -0,0 +1,251 @@
|
|||
# Copyright 2008, 2009 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/>. */
|
||||
|
||||
# This file is part of the GDB testsuite. It tests reverse stepping.
|
||||
# Lots of code borrowed from "step-test.exp".
|
||||
|
||||
#
|
||||
# Test step and next in reverse
|
||||
#
|
||||
|
||||
if ![target_info exists gdb,can_reverse] {
|
||||
return
|
||||
}
|
||||
|
||||
set testfile "step-reverse"
|
||||
set srcfile ${testfile}.c
|
||||
|
||||
if { [prepare_for_testing $testfile.exp $testfile $srcfile] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
runto main
|
||||
|
||||
if [target_info exists gdb,use_precord] {
|
||||
# Activate process record/replay
|
||||
gdb_test "record" "" "Turn on process record"
|
||||
# FIXME: command ought to acknowledge, so we can test if it succeeded.
|
||||
}
|
||||
|
||||
# plain vanilla step/next (no count)
|
||||
|
||||
gdb_test "next" ".*NEXT TEST 1.*" "next test 1"
|
||||
gdb_test "step" ".*STEP TEST 1.*" "step test 1"
|
||||
|
||||
# step/next with count
|
||||
|
||||
gdb_test "next 2" ".*NEXT TEST 2.*" "next test 2"
|
||||
gdb_test "step 3" ".*STEP TEST 2.*" "step test 2"
|
||||
|
||||
# step over call
|
||||
|
||||
gdb_test "step" ".*NEXT OVER THIS CALL.*" "step up to call"
|
||||
gdb_test "next" ".*STEP INTO THIS CALL.*" "next over call"
|
||||
|
||||
# step into call
|
||||
|
||||
gdb_test "step" ".*ARRIVED IN CALLEE.*" "step into call"
|
||||
|
||||
# finish out of call
|
||||
|
||||
set test_message "finish out of fn call"
|
||||
gdb_test_multiple "finish" "$test_message" {
|
||||
-re "FINISH TEST.*$gdb_prompt $" {
|
||||
pass "$test_message"
|
||||
}
|
||||
-re "STEP INTO THIS CALL.*$gdb_prompt $" {
|
||||
send_gdb "step\n"
|
||||
exp_continue
|
||||
}
|
||||
}
|
||||
|
||||
# stepi over flat code (no calls)
|
||||
|
||||
set test_message "simple stepi"
|
||||
gdb_test_multiple "stepi" "$test_message" {
|
||||
-re "STEPI TEST.*$gdb_prompt $" {
|
||||
pass "$test_message"
|
||||
}
|
||||
-re "FINISH TEST.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "NEXTI TEST.*$gdb_prompt $" {
|
||||
fail "$test_message (too far)"
|
||||
}
|
||||
}
|
||||
|
||||
# stepi into a function call
|
||||
|
||||
set test_message "stepi into function call"
|
||||
gdb_test_multiple "stepi" "$test_message" {
|
||||
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
||||
pass "$test_message"
|
||||
}
|
||||
-re "NEXTI TEST.*$gdb_prompt $" {
|
||||
fail "$test_message (too far)"
|
||||
}
|
||||
-re "RETURN FROM CALLEE.*$gdb_prompt $" {
|
||||
fail "$test_message (too far)"
|
||||
}
|
||||
-re "ENTER CALLEE.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
}
|
||||
|
||||
# stepi thru return of a function call
|
||||
|
||||
set test_message "stepi back from function call"
|
||||
gdb_test_multiple "stepi" "$test_message" {
|
||||
-re "NEXTI TEST.*$gdb_prompt $" {
|
||||
pass "$test_message"
|
||||
}
|
||||
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "RETURN FROM CALLEE.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "STEPI TEST.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "ENTER CALLEE.*$gdb_prompt $" {
|
||||
fail "$test_message (too far)"
|
||||
}
|
||||
}
|
||||
|
||||
###
|
||||
###
|
||||
###
|
||||
|
||||
# Set reverse execution direction
|
||||
# FIXME: command needs to acknowledge, so we can test if it succeeded.
|
||||
|
||||
gdb_test "set exec-dir reverse" "" "set reverse execution"
|
||||
|
||||
# stepi backward thru return and into a function
|
||||
|
||||
set stepi_location [gdb_get_line_number "ARRIVED IN CALLEE" "$srcfile"]
|
||||
set test_message "reverse stepi thru function return"
|
||||
gdb_test_multiple "stepi" "$test_message" {
|
||||
-re "NEXTI TEST.*$gdb_prompt $" {
|
||||
fail "$test_message (start statement)"
|
||||
}
|
||||
-re "RETURN FROM CALLEE.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "$hex\[ \t\]*$stepi_location.*ARRIVED IN CALLEE.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
||||
pass "$test_message"
|
||||
}
|
||||
-re "ENTER CALLEE.*$gdb_prompt $" {
|
||||
fail "$test_message (too far)"
|
||||
}
|
||||
-re "STEPI TEST.*$gdb_prompt $" {
|
||||
fail "$test_message (too far)"
|
||||
}
|
||||
}
|
||||
|
||||
# stepi backward out of a function call
|
||||
|
||||
set stepi_location [gdb_get_line_number "FINISH TEST" "$srcfile"]
|
||||
set test_message "reverse stepi from a function call"
|
||||
gdb_test_multiple "stepi" "$test_message" {
|
||||
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
||||
fail "$test_message (start statement)"
|
||||
}
|
||||
-re "ENTER CALLEE.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "${hex}\[ \t\]*$stepi_location.*STEPI TEST.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "STEPI TEST.*$gdb_prompt $" {
|
||||
pass "$test_message"
|
||||
}
|
||||
-re "STEP INTO THIS CALL.*$gdb_prompt $" {
|
||||
fail "$test_message (too far)"
|
||||
}
|
||||
}
|
||||
|
||||
# stepi backward over flat code (no calls)
|
||||
|
||||
set stepi_location [gdb_get_line_number "FINISH TEST" "$srcfile"]
|
||||
set test_message "simple reverse stepi"
|
||||
gdb_test_multiple "stepi" "$test_message" {
|
||||
-re "STEPI TEST.*$gdb_prompt $" {
|
||||
fail "$test_message (start statement)"
|
||||
}
|
||||
-re "$hex\[ \t\]*$stepi_location.* FINISH TEST.*$gdb_prompt $" {
|
||||
send_gdb "stepi\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "$stepi_location.* FINISH TEST.*$gdb_prompt $" {
|
||||
pass "$test_message"
|
||||
}
|
||||
-re "STEP INTO THIS CALL.*$gdb_prompt $" {
|
||||
fail "$test_message (too far)"
|
||||
}
|
||||
}
|
||||
|
||||
# step backward into function (thru return)
|
||||
|
||||
set test_message "reverse step into fn call"
|
||||
gdb_test_multiple "step" "$test_message" {
|
||||
-re "RETURN FROM CALLEE.*$gdb_prompt $" {
|
||||
send_gdb "step\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
||||
pass "$test_message"
|
||||
}
|
||||
}
|
||||
|
||||
# step backward out of called function (thru call)
|
||||
|
||||
gdb_test "step" ".*STEP INTO THIS CALL.*" "reverse step out of called fn"
|
||||
|
||||
# next backward over call
|
||||
|
||||
gdb_test "next" ".*NEXT OVER THIS CALL.*" "reverse next over call"
|
||||
|
||||
# step/next backward with count
|
||||
|
||||
gdb_test "step 3" ".*REVERSE STEP TEST 1.*" "reverse step test 1"
|
||||
gdb_test "next 2" ".*REVERSE NEXT TEST 1.*" "reverse next test 1"
|
||||
|
||||
# step/next backward without count
|
||||
|
||||
gdb_test "step" ".*STEP TEST 1.*" "reverse step test 2"
|
||||
gdb_test "next" ".*NEXT TEST 1.*" "reverse next test 2"
|
||||
|
||||
|
||||
|
||||
# Finish test by running forward to the end.
|
||||
# FIXME return to this later...
|
||||
# gdb_test "set exec-dir forward" "" "set forward execution"
|
||||
# gdb_continue_to_end "step-reverse.exp"
|
||||
|
||||
return 0
|
146
gdb/testsuite/gdb.reverse/until-reverse.c
Normal file
146
gdb/testsuite/gdb.reverse/until-reverse.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2008, 2009
|
||||
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/>. */
|
||||
|
||||
#ifdef vxworks
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
/* VxWorks does not supply atoi. */
|
||||
static int
|
||||
atoi (z)
|
||||
char *z;
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (*z >= '0' && *z <= '9')
|
||||
i = i * 10 + (*z++ - '0');
|
||||
return i;
|
||||
}
|
||||
|
||||
/* I don't know of any way to pass an array to VxWorks. This function
|
||||
can be called directly from gdb. */
|
||||
|
||||
vxmain (arg)
|
||||
char *arg;
|
||||
{
|
||||
char *argv[2];
|
||||
|
||||
argv[0] = "";
|
||||
argv[1] = arg;
|
||||
main (2, argv, (char **) 0);
|
||||
}
|
||||
|
||||
#else /* ! vxworks */
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
#endif /* ! vxworks */
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
extern int marker1 (void);
|
||||
extern int marker2 (int a);
|
||||
extern void marker3 (char *a, char *b);
|
||||
extern void marker4 (long d);
|
||||
#else
|
||||
extern int marker1 ();
|
||||
extern int marker2 ();
|
||||
extern void marker3 ();
|
||||
extern void marker4 ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This simple classical example of recursion is useful for
|
||||
* testing stack backtraces and such.
|
||||
*/
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int factorial(int);
|
||||
|
||||
int
|
||||
main (int argc, char **argv, char **envp)
|
||||
#else
|
||||
int
|
||||
main (argc, argv, envp)
|
||||
int argc;
|
||||
char *argv[], **envp;
|
||||
#endif
|
||||
{
|
||||
#ifdef usestubs
|
||||
set_debug_traps(); /* set breakpoint 5 here */
|
||||
breakpoint();
|
||||
#endif
|
||||
if (argc == 12345) { /* an unlikely value < 2^16, in case uninited */ /* set breakpoint 6 here */
|
||||
fprintf (stderr, "usage: factorial <number>\n");
|
||||
return 1;
|
||||
}
|
||||
printf ("%d\n", factorial (atoi ("6"))); /* set breakpoint 1 here */
|
||||
/* set breakpoint 12 here */
|
||||
marker1 (); /* set breakpoint 11 here */
|
||||
marker2 (43); /* set breakpoint 20 here */
|
||||
marker3 ("stack", "trace"); /* set breakpoint 21 here */
|
||||
marker4 (177601976L);
|
||||
/* We're used by a test that requires malloc, so make sure it is
|
||||
in the executable. */
|
||||
(void)malloc (1);
|
||||
|
||||
argc = (argc == 12345); /* This is silly, but we can step off of it */ /* set breakpoint 2 here */
|
||||
return argc; /* set breakpoint 10 here */
|
||||
} /* set breakpoint 10a here */
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int factorial (int value)
|
||||
#else
|
||||
int factorial (value)
|
||||
int value;
|
||||
#endif
|
||||
{
|
||||
if (value > 1) { /* set breakpoint 7 here */
|
||||
value *= factorial (value - 1);
|
||||
}
|
||||
return (value); /* set breakpoint 19 here */
|
||||
}
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int multi_line_if_conditional (int a, int b, int c)
|
||||
#else
|
||||
int multi_line_if_conditional (a, b, c)
|
||||
int a, b, c;
|
||||
#endif
|
||||
{
|
||||
if (a /* set breakpoint 3 here */
|
||||
&& b
|
||||
&& c)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int multi_line_while_conditional (int a, int b, int c)
|
||||
#else
|
||||
int multi_line_while_conditional (a, b, c)
|
||||
int a, b, c;
|
||||
#endif
|
||||
{
|
||||
while (a /* set breakpoint 4 here */
|
||||
&& b
|
||||
&& c)
|
||||
{
|
||||
a--, b--, c--;
|
||||
}
|
||||
return 0;
|
||||
}
|
129
gdb/testsuite/gdb.reverse/until-reverse.exp
Normal file
129
gdb/testsuite/gdb.reverse/until-reverse.exp
Normal file
|
@ -0,0 +1,129 @@
|
|||
# Copyright 2008, 2009 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/>. */
|
||||
|
||||
# This file is part of the GDB testsuite. It tests 'until' and
|
||||
# 'advance' in reverse debugging.
|
||||
|
||||
if ![target_info exists gdb,can_reverse] {
|
||||
return
|
||||
}
|
||||
|
||||
set testfile "until-reverse"
|
||||
set srcfile ${testfile}.c
|
||||
set srcfile1 ur1.c
|
||||
|
||||
if { [prepare_for_testing $testfile.exp $testfile {until-reverse.c ur1.c} ] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]
|
||||
set bp_location7 [gdb_get_line_number "set breakpoint 7 here"]
|
||||
set bp_location9 [gdb_get_line_number "set breakpoint 9 here" "$srcfile1"]
|
||||
set bp_location19 [gdb_get_line_number "set breakpoint 19 here"]
|
||||
set bp_location20 [gdb_get_line_number "set breakpoint 20 here"]
|
||||
set bp_location21 [gdb_get_line_number "set breakpoint 21 here"]
|
||||
|
||||
runto main
|
||||
|
||||
if [target_info exists gdb,use_precord] {
|
||||
# Activate process record/replay
|
||||
gdb_test "record" "" "Turn on process record"
|
||||
# FIXME: command ought to acknowledge, so we can test if it succeeded.
|
||||
}
|
||||
|
||||
# Verify that plain vanilla "until <location>" works.
|
||||
#
|
||||
gdb_test "until $bp_location1" \
|
||||
"main .* at .*:$bp_location1.*" \
|
||||
"until line number"
|
||||
|
||||
# Advance up to factorial, outer invocation
|
||||
#
|
||||
gdb_test "advance factorial" \
|
||||
"factorial .value=6..*$srcfile:$bp_location7.*" \
|
||||
"advance to factorial"
|
||||
|
||||
# At this point, 'until' should continue the inferior up to when all the
|
||||
# inner invocations of factorial() are completed and we are back at this
|
||||
# frame.
|
||||
#
|
||||
gdb_test "until $bp_location19" \
|
||||
"factorial .value=720.*${srcfile}:$bp_location19.*" \
|
||||
"until factorial, recursive function"
|
||||
|
||||
# Finish out to main scope
|
||||
#
|
||||
gdb_test "finish" \
|
||||
" in main .*$srcfile:$bp_location1.*" \
|
||||
"finish to main"
|
||||
|
||||
# Advance to a function called by main (marker2)
|
||||
#
|
||||
gdb_test "advance marker2" \
|
||||
"marker2 .a=43.*$srcfile1:$bp_location9.*" \
|
||||
"advance to marker2"
|
||||
|
||||
# Now issue an until with another function, not called by the current
|
||||
# frame, as argument. This should not work, i.e. the program should
|
||||
# stop at main, the caller, where we put the 'guard' breakpoint.
|
||||
#
|
||||
set test_msg "until func, not called by current frame"
|
||||
gdb_test_multiple "until marker3" "$test_msg" {
|
||||
-re "main .*at .*${srcfile}:$bp_location20.*$gdb_prompt $" {
|
||||
pass "$test_msg"
|
||||
}
|
||||
-re "main .*at .*${srcfile}:$bp_location21.*$gdb_prompt $" {
|
||||
pass "$test_msg"
|
||||
}
|
||||
}
|
||||
|
||||
###
|
||||
###
|
||||
###
|
||||
|
||||
# Set reverse execution direction
|
||||
# FIXME: command needs to acknowledge, so we can test if it succeeded.
|
||||
|
||||
gdb_test "set exec-dir reverse" "" "set reverse execution"
|
||||
|
||||
#
|
||||
# We should now be at main, after the return from marker2.
|
||||
# "Advance" backward into marker2.
|
||||
#
|
||||
|
||||
gdb_test "advance marker2" \
|
||||
"marker2 .a=43.*$srcfile1:$bp_location9.*" \
|
||||
"reverse-advance to marker2"
|
||||
|
||||
# Finish out to main scope (backward)
|
||||
|
||||
gdb_test "finish" \
|
||||
" in main .*$srcfile:$bp_location20.*" \
|
||||
"reverse-finish from marker2"
|
||||
|
||||
# Advance backward to last line of factorial (outer invocation)
|
||||
|
||||
gdb_test "advance $bp_location19" \
|
||||
"factorial .value=720.*${srcfile}:$bp_location19.*" \
|
||||
"reverse-advance to final return of factorial"
|
||||
|
||||
# Now do "until" across the recursive calls,
|
||||
# ending up in the same frame where we are now.
|
||||
|
||||
gdb_test "until $bp_location7" \
|
||||
"factorial .value=6..*$srcfile:$bp_location7.*" \
|
||||
"reverse-until to entry of factorial"
|
||||
|
||||
|
49
gdb/testsuite/gdb.reverse/ur1.c
Normal file
49
gdb/testsuite/gdb.reverse/ur1.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 1992, 1993, 1994, 1995, 1999, 2002, 2003, 2007, 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/>. */
|
||||
|
||||
/* The code for this file was extracted from the gdb testsuite
|
||||
testcase "break.c". */
|
||||
|
||||
/* The following functions do nothing useful. They are included
|
||||
simply as places to try setting breakpoints at. They are
|
||||
explicitly "one-line functions" to verify that this case works
|
||||
(some versions of gcc have or have had problems with this).
|
||||
|
||||
These functions are in a separate source file to prevent an
|
||||
optimizing compiler from inlining them and optimizing them away. */
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int marker1 (void) { return (0); } /* set breakpoint 15 here */
|
||||
int marker2 (int a) { return (1); } /* set breakpoint 8 here */
|
||||
void marker3 (char *a, char *b) {} /* set breakpoint 17 here */
|
||||
void marker4 (long d) {} /* set breakpoint 14 here */
|
||||
#else
|
||||
int marker1 () { return (0); } /* set breakpoint 16 here */
|
||||
int marker2 (a) int a; { return (1); } /* set breakpoint 9 here */
|
||||
void marker3 (a, b) char *a, *b; {} /* set breakpoint 18 here */
|
||||
void marker4 (d) long d; {} /* set breakpoint 13 here */
|
||||
#endif
|
||||
|
||||
/* A structure we use for field name completion tests. */
|
||||
struct some_struct
|
||||
{
|
||||
int a_field;
|
||||
int b_field;
|
||||
};
|
||||
|
||||
struct some_struct values[50];
|
219
gdb/testsuite/gdb.reverse/watch-reverse.c
Normal file
219
gdb/testsuite/gdb.reverse/watch-reverse.c
Normal file
|
@ -0,0 +1,219 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2008, 2009
|
||||
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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
/*
|
||||
* Since using watchpoints can be very slow, we have to take some pains to
|
||||
* ensure that we don't run too long with them enabled or we run the risk
|
||||
* of having the test timeout. To help avoid this, we insert some marker
|
||||
* functions in the execution stream so we can set breakpoints at known
|
||||
* locations, without worrying about invalidating line numbers by changing
|
||||
* this file. We use null bodied functions are markers since gdb does
|
||||
* not support breakpoints at labeled text points at this time.
|
||||
*
|
||||
* One place we need is a marker for when we start executing our tests
|
||||
* instructions rather than any process startup code, so we insert one
|
||||
* right after entering main(). Another is right before we finish, before
|
||||
* we start executing any process termination code.
|
||||
*
|
||||
* Another problem we have to guard against, at least for the test
|
||||
* suite, is that we need to ensure that the line that causes the
|
||||
* watchpoint to be hit is still the current line when gdb notices
|
||||
* the hit. Depending upon the specific code generated by the compiler,
|
||||
* the instruction after the one that triggers the hit may be part of
|
||||
* the same line or part of the next line. Thus we ensure that there
|
||||
* are always some instructions to execute on the same line after the
|
||||
* code that should trigger the hit.
|
||||
*/
|
||||
|
||||
int count = -1;
|
||||
int ival1 = -1;
|
||||
int ival2 = -1;
|
||||
int ival3 = -1;
|
||||
int ival4 = -1;
|
||||
int ival5 = -1;
|
||||
char buf[10];
|
||||
struct foo
|
||||
{
|
||||
int val;
|
||||
};
|
||||
struct foo struct1, struct2, *ptr1, *ptr2;
|
||||
|
||||
int doread = 0;
|
||||
|
||||
char *global_ptr;
|
||||
|
||||
void marker1 ()
|
||||
{
|
||||
}
|
||||
|
||||
void marker2 ()
|
||||
{
|
||||
}
|
||||
|
||||
void marker4 ()
|
||||
{
|
||||
}
|
||||
|
||||
void marker5 ()
|
||||
{
|
||||
}
|
||||
|
||||
void marker6 ()
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
void recurser (int x)
|
||||
#else
|
||||
void recurser (x) int x;
|
||||
#endif
|
||||
{
|
||||
int local_x;
|
||||
|
||||
if (x > 0)
|
||||
recurser (x-1);
|
||||
local_x = x;
|
||||
}
|
||||
|
||||
void
|
||||
func2 ()
|
||||
{
|
||||
int local_a;
|
||||
static int static_b;
|
||||
|
||||
ival5++;
|
||||
local_a = ival5;
|
||||
static_b = local_a;
|
||||
}
|
||||
|
||||
void
|
||||
func3 ()
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
x = 0;
|
||||
x = 1; /* second x assignment */
|
||||
y = 1;
|
||||
y = 2;
|
||||
}
|
||||
|
||||
int
|
||||
func1 ()
|
||||
{
|
||||
/* The point of this is that we will set a breakpoint at this call.
|
||||
|
||||
Then, if DECR_PC_AFTER_BREAK equals the size of a function call
|
||||
instruction (true on a sun3 if this is gcc-compiled--FIXME we
|
||||
should use asm() to make it work for any compiler, present or
|
||||
future), then we will end up branching to the location just after
|
||||
the breakpoint. And we better not confuse that with hitting the
|
||||
breakpoint. */
|
||||
func2 ();
|
||||
return 73;
|
||||
}
|
||||
|
||||
void
|
||||
func4 ()
|
||||
{
|
||||
buf[0] = 3;
|
||||
global_ptr = buf;
|
||||
buf[0] = 7;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
struct1.val = 1;
|
||||
struct2.val = 2;
|
||||
ptr1 = &struct1;
|
||||
ptr2 = &struct2;
|
||||
marker1 ();
|
||||
func1 ();
|
||||
for (count = 0; count < 4; count++) {
|
||||
ival1 = count;
|
||||
ival3 = count; ival4 = count;
|
||||
}
|
||||
ival1 = count; /* Outside loop */
|
||||
ival2 = count;
|
||||
ival3 = count; ival4 = count;
|
||||
marker2 ();
|
||||
if (doread)
|
||||
{
|
||||
static char msg[] = "type stuff for buf now:";
|
||||
write (1, msg, sizeof (msg) - 1);
|
||||
read (0, &buf[0], 5);
|
||||
}
|
||||
marker4 ();
|
||||
|
||||
/* We have a watchpoint on ptr1->val. It should be triggered if
|
||||
ptr1's value changes. */
|
||||
ptr1 = ptr2;
|
||||
|
||||
/* This should not trigger the watchpoint. If it does, then we
|
||||
used the wrong value chain to re-insert the watchpoints or we
|
||||
are not evaluating the watchpoint expression correctly. */
|
||||
struct1.val = 5;
|
||||
marker5 ();
|
||||
|
||||
/* We have a watchpoint on ptr1->val. It should be triggered if
|
||||
ptr1's value changes. */
|
||||
ptr1 = ptr2;
|
||||
|
||||
/* This should not trigger the watchpoint. If it does, then we
|
||||
used the wrong value chain to re-insert the watchpoints or we
|
||||
are not evaluating the watchpoint expression correctly. */
|
||||
struct1.val = 5;
|
||||
marker5 ();
|
||||
|
||||
/* We're going to watch locals of func2, to see that out-of-scope
|
||||
watchpoints are detected and properly deleted.
|
||||
*/
|
||||
marker6 ();
|
||||
|
||||
/* This invocation is used for watches of a single
|
||||
local variable. */
|
||||
func2 ();
|
||||
|
||||
/* This invocation is used for watches of an expression
|
||||
involving a local variable. */
|
||||
func2 ();
|
||||
|
||||
/* This invocation is used for watches of a static
|
||||
(non-stack-based) local variable. */
|
||||
func2 ();
|
||||
|
||||
/* This invocation is used for watches of a local variable
|
||||
when recursion happens.
|
||||
*/
|
||||
marker6 ();
|
||||
recurser (2);
|
||||
|
||||
marker6 ();
|
||||
|
||||
func3 ();
|
||||
|
||||
func4 ();
|
||||
|
||||
return 0;
|
||||
}
|
127
gdb/testsuite/gdb.reverse/watch-reverse.exp
Normal file
127
gdb/testsuite/gdb.reverse/watch-reverse.exp
Normal file
|
@ -0,0 +1,127 @@
|
|||
# Copyright 2008, 2009 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/>.
|
||||
|
||||
# Based on a file written by Fred Fish. (fnf@cygnus.com)
|
||||
# This file is part of the GDB testsuite. It tests reverse debugging
|
||||
# with watchpoints.
|
||||
|
||||
|
||||
if ![target_info exists gdb,can_reverse] {
|
||||
return
|
||||
}
|
||||
|
||||
set testfile "watch-reverse"
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
|
||||
if { [prepare_for_testing $testfile.exp $testfile $srcfile] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
runto main
|
||||
|
||||
if [target_info exists gdb,use_precord] {
|
||||
# Activate process record/replay
|
||||
gdb_test "record" "" "Turn on process record"
|
||||
# FIXME: command ought to acknowledge, so we can test if it succeeded.
|
||||
}
|
||||
|
||||
# Only software watchpoints can be used in reverse
|
||||
gdb_test "set can-use-hw-watchpoints 0" "" ""
|
||||
|
||||
gdb_test "break marker1" \
|
||||
"Breakpoint $decimal at $hex: file .*$srcfile, line $decimal.*" \
|
||||
"set breakpoint at marker1"
|
||||
|
||||
gdb_test "break marker2" \
|
||||
"Breakpoint $decimal at $hex: file .*$srcfile, line $decimal.*" \
|
||||
"set breakpoint at marker2"
|
||||
|
||||
gdb_continue_to_breakpoint "marker1" ".*/$srcfile:.*"
|
||||
|
||||
gdb_test "watch ival3" \
|
||||
".*\[Ww\]atchpoint $decimal: ival3.*" \
|
||||
"set watchpoint on ival3"
|
||||
|
||||
# Continue until first change, from -1 to 0
|
||||
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = -1.*New value = 0.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit, first time"
|
||||
|
||||
# Continue until the next change, from 0 to 1.
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = 0.*New value = 1.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit, second time"
|
||||
|
||||
# Continue until the next change, from 1 to 2.
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = 1.*New value = 2.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit, third time"
|
||||
|
||||
# Continue until the next change, from 2 to 3.
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = 2.*New value = 3.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit, fourth time"
|
||||
|
||||
# Continue until the next change, from 3 to 4.
|
||||
# Note that this one is outside the loop.
|
||||
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = 3.*New value = 4.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit, fifth time"
|
||||
|
||||
# Continue until we hit the finishing marker function.
|
||||
# Make sure we hit no more watchpoints.
|
||||
|
||||
gdb_continue_to_breakpoint "marker2" ".*/$srcfile:.*"
|
||||
|
||||
###
|
||||
###
|
||||
###
|
||||
|
||||
# FIXME 'set exec-dir' command should give some output so we can test.
|
||||
gdb_test "set exec-direction reverse" "" "set reverse"
|
||||
|
||||
# Reverse until the previous change, from 4 to 3
|
||||
# Note that this one is outside the loop
|
||||
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = 4.*New value = 3.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit in reverse, first time"
|
||||
|
||||
# Reverse until the previous change, from 3 to 2.
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = 3.*New value = 2.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit in reverse, second time"
|
||||
|
||||
# Reverse until the previous change, from 2 to 1.
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = 2.*New value = 1.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit in reverse, third time"
|
||||
|
||||
# Reverse until the previous change, from 1 to 0.
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = 1.*New value = 0.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit in reverse, fourth time"
|
||||
|
||||
# Reverse until first change, from 0 to -1
|
||||
|
||||
gdb_test "continue" \
|
||||
".*\[Ww\]atchpoint.*ival3.*Old value = 0.*New value = -1.*ival3 = count; ival4 = count;.*" \
|
||||
"watchpoint hit in reverse, fifth time"
|
||||
|
||||
|
||||
return 0
|
Loading…
Add table
Add a link
Reference in a new issue