This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 6/7] range stepping: test case


This test case is used to verify range stepping is used by means of
checking the internalvar '$range_stepping_counter'.

In V2, the test cases check the value of '$range_stepping_counter'
instead of parsing RSP packets.

gdb/testsuite:

2013-04-10  Yao Qi  <yao@codesourcery.com>

	* gdb.base/range-stepping.c: New.
	* gdb.base/range-stepping.exp: New.
	* gdb.trace/range-stepping.c: New.
	* gdb.trace/range-stepping.exp: New.
---
 gdb/testsuite/gdb.base/range-stepping.c    |   69 +++++++++
 gdb/testsuite/gdb.base/range-stepping.exp  |  222 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.trace/range-stepping.c   |   61 ++++++++
 gdb/testsuite/gdb.trace/range-stepping.exp |   89 +++++++++++
 4 files changed, 441 insertions(+), 0 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/range-stepping.c
 create mode 100644 gdb/testsuite/gdb.base/range-stepping.exp
 create mode 100644 gdb/testsuite/gdb.trace/range-stepping.c
 create mode 100644 gdb/testsuite/gdb.trace/range-stepping.exp

diff --git a/gdb/testsuite/gdb.base/range-stepping.c b/gdb/testsuite/gdb.base/range-stepping.c
new file mode 100644
index 0000000..930cb8d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/range-stepping.c
@@ -0,0 +1,69 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2013 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/>.  */
+
+static int
+func1 (int a, int b)
+{
+  int r = a * b;
+
+  r =+ (a | b);
+  r =+ (a - b);
+
+  return r;
+}
+
+int
+main(void)
+{
+  int a = 0;
+  int b = 1;
+  int c = 2;
+  int d = 3;
+  int e = 4;
+  double d1 = 1.0;
+  double d2 = 2.0;
+
+  /* A line of source will be generated to a number of
+     instructions by compiler.  */
+  a = b + c + d * e - a; /* location 1 */
+
+  /* To compose multiple instructions before and after
+     'function call' or 'branch' instruction.  This line
+     of source will be generated to the following instructions,
+
+addr1:
+     insn1;
+     insn2;
+     ...
+     call func1;
+     ...
+     insn3;
+addr2:
+     insn4;  */
+  e = 10 + func1 (a + b, c * d); /* location 2 */
+
+  e = 10 + func1 (a + b, c * d);
+  /* Generate a range that includes a loop in it.  */
+  for (a = 0, e = 0; a < 15; a++) { e += a;}
+  /* Generate a range that includes a loop in it.  */
+  for (a = 0, e = 0; a < 15; a++) { e += a;}
+  /* Generate a range that includes a loop, which is time consuming.
+     Variable C is used to terminate the loop earlier when GDB
+     wants.  */
+  for (c = 1, a = 0; a < 65535 && c; a++) {for (b = 0; b < 65535 && c; b++) { d1 = d2 * a / b; d2 = d1 * a;}}
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/range-stepping.exp b/gdb/testsuite/gdb.base/range-stepping.exp
new file mode 100644
index 0000000..0f2a2dd
--- /dev/null
+++ b/gdb/testsuite/gdb.base/range-stepping.exp
@@ -0,0 +1,222 @@
+# Copyright 2013 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/>.
+
+standard_testfile .c
+set executable $testfile
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+	   executable {debug nowarnings}] != "" } {
+     untested ${testfile}.exp
+     return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] {
+    fail "Can't run to main"
+    return -1
+}
+
+# Check range stepping is supported by target or not.
+set test "range-stepping is supported"
+gdb_test_multiple "maintenance show range-stepping" "show range-stepping" {
+    -re "Debugger's willingness to do range-stepping is off.*\r\n$gdb_prompt $" {
+	unsupported $test
+	return -1
+    }
+    -re "Debugger's willingness to do range-stepping is on.*\r\n$gdb_prompt $" {
+	pass $test
+    }
+}
+
+# Check range stepping can step a range of multiple instructions.
+
+with_test_prefix "multi insns" {
+    global executable
+    global hex decimal
+    global gdb_prompt
+
+    gdb_breakpoint [gdb_get_line_number "location 1"]
+    gdb_continue_to_breakpoint "location 1"
+
+    set pc_before_stepping ""
+    set test "pc before stepping"
+    gdb_test_multiple "print/x \$pc" $test {
+	-re "\\\$$decimal = (\[^\r\n\]*)\r\n$gdb_prompt $" {
+	    set pc_before_stepping $expect_out(1,string)
+	    pass $test
+	}
+    }
+
+    # When execute command "next", GDB should send one vCont;s and
+    # vCont;r and receive two stop replies.
+    # --> vCont;s  (step over breakpoint)
+    # <-- T0505:XXX
+    # --> vCont;rSTART,END  (do range stepping)
+    # <-- T0505:XXX
+    gdb_test_no_output "set \$range_stepping_counter = 0" ""
+    gdb_test "next"
+    gdb_test "p \$range_stepping_counter" " = 1"
+
+    set pc_after_stepping ""
+    set msg "pc before stepping"
+    gdb_test_multiple "print/x \$pc" $msg {
+	-re "\\\$$decimal = (\[^\r\n\]*)\r\n$gdb_prompt $" {
+	    set pc_after_stepping $expect_out(1,string)
+	    pass $msg
+	}
+    }
+
+    # At least, there are two instructions between
+    # PC_BEFORE_STEPPING and PC_AFTER_STEPPING.
+    gdb_test "disassemble ${pc_before_stepping},${pc_after_stepping}" \
+	"${hex} <main\\+${decimal}>:.*${hex} <main\\+${decimal}>:.*" \
+	"stepped multiple insns"
+}
+
+# Check range stepping can step over a function.
+
+with_test_prefix "step over func" {
+    global srcfile
+
+    set line_num [gdb_get_line_number "location 2"]
+    gdb_test "where" "main \\(\\) at .*${srcfile}:${line_num}.*"
+
+    # It is expected to get three stops and two 'vCont;r'.  In the C
+    # code, the line of C source produces the following instructions,
+    #
+    # addr1:
+    #  insn1;
+    #  insn2;
+    #  ...
+    #  call func1;
+    # addr2:
+    #  ...
+    #  insn3;
+    # addr3:
+    #  insn4;
+    #
+    # Something like this will happen:
+    # --> vCont;rADDR1,ADDR3 (do range stepping from ADDR1 to ADDR3)
+    # <-- T0505:XXXX
+    # (inferior is single-stepping to func, which is out of the range)
+    # --> $Z0,ADDR2
+    # --> vCont;c (set step-resume breakpoint on ADDR2, and resume)
+    # <-- T0505:XXXX  (inferior stops at ADD2)
+    # --> vCont;rADDR1,ADDR3  (continues to do range stepping)
+    # <-- T0505:XXXX
+    gdb_test_no_output "set \$range_stepping_counter = 0" ""
+    gdb_test "next"
+    gdb_test "p \$range_stepping_counter" " = 2"
+}
+
+# Check range stepping works well with breakpoint.
+
+with_test_prefix "breakpoint" {
+    gdb_breakpoint "func1"
+    # Something like this will happen:
+    # --> vCont;rADDR1,ADDR3
+    # <-- T0505:XXXX
+    # (inferior is single-stepping to func1, which is out of the range)
+    # --> $Z0,ADDR2
+    # --> vCont;c (set step-resume breakpoint on ADDR2, and resume)
+    # <-- T0505:XXXX  (inferior hits the breakpoint on fun1)
+    gdb_test_no_output "set \$range_stepping_counter = 0" ""
+    gdb_test "next" "." ""
+    gdb_test "p \$range_stepping_counter" " = 1" \
+       "range-stepping-counter is 1"
+
+    gdb_test "backtrace" "#0 .* func1 .*#1 .* main .*" \
+	"backtrace from func1"
+    # The range stepping was interrupted by a breakpoint, but the
+    # state related to range stepping should be cleared.
+    gdb_test_no_output "set \$range_stepping_counter = 0" ""
+    gdb_test "stepi"
+    gdb_test "p \$range_stepping_counter" " = 0" \
+       "range-stepping-counter is 0"
+    gdb_test "finish" ".*"
+
+    gdb_test "next" ".*"
+    delete_breakpoints
+}
+
+# Check range stepping works well with a loop in the range.
+
+with_test_prefix "loop" {
+
+    # GDB should send one vCont;r and receive one stop reply.
+    # --> vCont;rSTART,END  (do range stepping)
+    # <-- T0505:XXX
+    gdb_test_no_output "set \$range_stepping_counter = 0" ""
+    gdb_test "next"
+    gdb_test "p \$range_stepping_counter" " = 1"
+
+    # Check loop is done.
+    gdb_test "print a" "\\$${decimal} = 15\[\r\n\].*"
+    gdb_test "print e" "\\$${decimal} = 105\[\r\n\].*"
+}
+
+# Check range stepping works well when PC has already within the loop
+# body.
+
+with_test_prefix "loop" {
+    # Stepi into the loop body.  15 is large enough to make sure
+    # program goes to loop body.
+    gdb_test "stepi 15" ".*"
+    # GDB should send one vCont;r and receive one stop reply.
+    # --> vCont;rSTART,END  (do range stepping)
+    # <-- T0505:XXX
+    gdb_test_no_output "set \$range_stepping_counter = 0" ""
+    gdb_test "next"
+    gdb_test "p \$range_stepping_counter" " = 1"
+
+    # Check loop is done.
+    gdb_test "print a" "\\$${decimal} = 15\[\r\n\].*"
+    gdb_test "print e" "\\$${decimal} = 105\[\r\n\].*"
+}
+
+# Check range stepping works well when it is interrupted by ctrl-c.
+
+with_test_prefix "interrupt" {
+    gdb_test_no_output "set \$range_stepping_counter = 0" ""
+
+    send_gdb "next\n"
+    sleep 1
+    send_gdb "\003"
+
+    # GDB should send one vCont;r and receive one stop reply about
+    # SIGINT.
+    # --> vCont;rSTART,END  (do range stepping)
+    # <-- T0205:XXX
+
+    set test "send gdb ctrl-c"
+    gdb_expect {
+	-re "Program received signal SIGINT.*$gdb_prompt $" {
+	    pass $test
+	}
+	timeout { fail "${test} (timeout)" }
+	eof { fail "${test} (eof)" }
+    }
+    gdb_test "p \$range_stepping_counter" " = 1" \
+	"range-stepping-counter is 1"
+
+    # Terminate the loop earlier and continue to do range stepping.
+    gdb_test "set variable c = 0"
+    gdb_test "next"
+    gdb_test "p \$range_stepping_counter" " = 2" \
+	"range-stepping-counter is 2"
+}
+
+return 0
diff --git a/gdb/testsuite/gdb.trace/range-stepping.c b/gdb/testsuite/gdb.trace/range-stepping.c
new file mode 100644
index 0000000..50db5a0
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/range-stepping.c
@@ -0,0 +1,61 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2013 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 SYMBOL_PREFIX
+#define SYMBOL(str)     SYMBOL_PREFIX #str
+#else
+#define SYMBOL(str)     #str
+#endif
+
+/* Called from asm.  */
+static void __attribute__((used))
+func2 (void)
+{}
+
+static int
+func1 (int a, int b)
+{
+  int r = a * b;
+
+  /* `set_point' is the label where we'll set tracepoint at.  The insn
+     at the label must the large enough to fit a fast tracepoint
+     jump.  */
+  asm ("    .global " SYMBOL(set_point) "\n"
+       SYMBOL(set_point) ":\n"
+#if (defined __x86_64__ || defined __i386__)
+       "    call " SYMBOL(func2) "\n"
+#endif
+       );
+
+  r =+ (a | b);
+  r =+ (a - b);
+
+  return r;
+}
+
+int
+main(void)
+{
+  int a = 0;
+  int b = 1;
+  int c = 2;
+  int d = 3;
+  int e = 4;
+
+  e = 10 + func1 (a + b, c * d); /* location 1 */
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.trace/range-stepping.exp b/gdb/testsuite/gdb.trace/range-stepping.exp
new file mode 100644
index 0000000..22c705d
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/range-stepping.exp
@@ -0,0 +1,89 @@
+# Copyright 2013 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/>.
+
+load_lib "trace-support.exp"
+
+standard_testfile
+set executable $testfile
+set expfile $testfile.exp
+
+if [prepare_for_testing $expfile $executable $srcfile \
+	{debug nowarnings}] {
+    untested "failed to prepare for trace tests"
+    return -1
+}
+
+if ![runto_main] {
+    fail "Can't run to main to check for trace support"
+    return -1
+}
+
+if ![gdb_target_supports_trace] {
+    unsupported "target does not support trace"
+    return -1;
+}
+
+# Check range stepping works well with tracepoint.
+proc range_stepping_with_tracepoint { type } {
+    with_test_prefix "${type}" {
+
+	gdb_breakpoint [gdb_get_line_number "location 1"]
+	gdb_continue_to_breakpoint "location 1"
+	delete_breakpoints
+
+	gdb_test "${type} set_point" ".*"
+	gdb_test_no_output "tstart"
+
+	# GDB will step over function func1, in which a tracepoint is
+	# set.  GDB will send two vCont;r packets because calling to
+	# func1 is out of the range.  However, tracepoint itself
+	# shouldn't have any effect on range stepping.
+	gdb_test_no_output "set \$range_stepping_counter = 0" ""
+	gdb_test "next"
+	gdb_test "p \$range_stepping_counter" " = 2"
+	gdb_test_no_output "tstop"
+	gdb_test "tfind" "Found trace frame 0.*" "tfind 0"
+	gdb_test "tfind" \
+	    "Target failed to find requested trace frame.*" \
+	    "tfind 1"
+
+	delete_breakpoints
+    }
+}
+
+range_stepping_with_tracepoint "trace"
+
+set libipa [get_in_proc_agent]
+gdb_load_shlibs $libipa
+
+if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+	  executable [list debug nowarnings shlib=$libipa] ] != "" } {
+    untested "failed to compile ftrace tests"
+    return -1
+}
+
+clean_restart ${executable}
+
+if ![runto_main] {
+    fail "Can't run to main for ftrace tests"
+    return 0
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+if { [gdb_test "info sharedlibrary" ".*${libipa}.*" "IPA loaded"] != 0 } {
+    untested "Could not find IPA lib loaded"
+} else {
+    range_stepping_with_tracepoint "ftrace"
+}
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]