Add tests for the new record-btrace target.
authorMarkus Metzger <mmetzger@sourceware.org>
Mon, 11 Mar 2013 08:59:00 +0000 (08:59 +0000)
committerMarkus Metzger <mmetzger@sourceware.org>
Mon, 11 Mar 2013 08:59:00 +0000 (08:59 +0000)
testsuite/
* Makefile.in: Add btrace testsuite.
* configure: Regenerated.
* configure.ac: Add btrace testsuite.
* gdb.btrace/Makefile.in: New file.
* gdb.btrace/enable.c: New file.
* gdb.btrace/enable.exp: New file.
* gdb.btrace/function_call_history.c: New file.
* gdb.btrace/function_call_history.exp: New file.
* gdb.btrace/instruction_history.c: New file.
* gdb.btrace/instruction_history.exp: New file.
* gdb.btrace/instruction_history.S: New file.
* lib/gdb.exp: Add btrace skip proc.

13 files changed:
gdb/testsuite/ChangeLog
gdb/testsuite/Makefile.in
gdb/testsuite/configure
gdb/testsuite/configure.ac
gdb/testsuite/gdb.btrace/Makefile.in [new file with mode: 0644]
gdb/testsuite/gdb.btrace/enable.c [new file with mode: 0644]
gdb/testsuite/gdb.btrace/enable.exp [new file with mode: 0644]
gdb/testsuite/gdb.btrace/function_call_history.c [new file with mode: 0644]
gdb/testsuite/gdb.btrace/function_call_history.exp [new file with mode: 0644]
gdb/testsuite/gdb.btrace/instruction_history.S [new file with mode: 0644]
gdb/testsuite/gdb.btrace/instruction_history.c [new file with mode: 0644]
gdb/testsuite/gdb.btrace/instruction_history.exp [new file with mode: 0644]
gdb/testsuite/lib/gdb.exp

index 7d57e7d1eb15ffe93dd5ee9147210edd2a4d27a6..f5b9dcbda4c7c2169f8e9349f0f4ec841008b689 100644 (file)
@@ -1,3 +1,18 @@
+2013-03-11  Christian Himpel  <christian.himpel@intel.com>
+
+       * Makefile.in: Add btrace testsuite.
+       * configure: Regenerated.
+       * configure.ac: Add btrace testsuite.
+       * gdb.btrace/Makefile.in: New file.
+       * gdb.btrace/enable.c: New file.
+       * gdb.btrace/enable.exp: New file.
+       * gdb.btrace/function_call_history.c: New file.
+       * gdb.btrace/function_call_history.exp: New file.
+       * gdb.btrace/instruction_history.c: New file.
+       * gdb.btrace/instruction_history.exp: New file.
+       * gdb.btrace/instruction_history.S: New file.
+       * lib/gdb.exp: Add btrace skip proc.
+
 2013-03-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Fix entry-values if the callee called a noreturn function.
index b0ace4054e37636ad49e5a399e555fb17d55e904..348901cfb353fb27f9f39d0edf3a7b47be5cb2fa 100644 (file)
@@ -32,8 +32,8 @@ SHELL = @SHELL@
 EXEEXT = @EXEEXT@
 SUBDIRS = @subdirs@
 RPATH_ENVVAR = @RPATH_ENVVAR@
-ALL_SUBDIRS = gdb.ada gdb.arch gdb.asm gdb.base gdb.cell gdb.cp gdb.disasm \
-       gdb.dwarf2 gdb.fortran gdb.gdb gdb.hp \
+ALL_SUBDIRS = gdb.ada gdb.arch gdb.asm gdb.base gdb.btrace gdb.cell gdb.cp \
+       gdb.disasm gdb.dwarf2 gdb.fortran gdb.gdb gdb.hp \
        gdb.java gdb.linespec gdb.mi gdb.modula2 gdb.multi \
        gdb.objc gdb.opencl gdb.opt gdb.pascal gdb.python gdb.server \
        gdb.stabs gdb.reverse gdb.threads gdb.trace gdb.xml \
index 0c8c3447d2937ba7d926b0b5933fad9f2efd1051..a40c1443097585c96fe70104f91e86dac73b01c1 100755 (executable)
@@ -3448,7 +3448,7 @@ done
 
 
 
-ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/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.btrace/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/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
@@ -4153,6 +4153,7 @@ do
     "gdb.arch/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.arch/Makefile" ;;
     "gdb.asm/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.asm/Makefile" ;;
     "gdb.base/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.base/Makefile" ;;
+    "gdb.btrace/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.btrace/Makefile" ;;
     "gdb.cell/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.cell/Makefile" ;;
     "gdb.cp/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.cp/Makefile" ;;
     "gdb.disasm/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.disasm/Makefile" ;;
index 66de8daaad26c1d136564b5e4bd4159498259563..9e070215d00455f8a6f7ac2e31d365d2801cfe31 100644 (file)
@@ -89,7 +89,7 @@ AC_EXEEXT
 
 AC_OUTPUT([Makefile \
   gdb.ada/Makefile \
-  gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile \
+  gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.btrace/Makefile \
   gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile \
   gdb.fortran/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile \
   gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile \
diff --git a/gdb/testsuite/gdb.btrace/Makefile.in b/gdb/testsuite/gdb.btrace/Makefile.in
new file mode 100644 (file)
index 0000000..f4c06d1
--- /dev/null
@@ -0,0 +1,17 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES   = enable function_call_history instruction_history
+
+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 *.dwo *.dwp
+       rm -f $(EXECUTABLES) $(MISCELLANEOUS)
+
+distclean maintainer-clean realclean: clean
+       rm -f Makefile config.status config.log site.* gdb.log gdb.sum
diff --git a/gdb/testsuite/gdb.btrace/enable.c b/gdb/testsuite/gdb.btrace/enable.c
new file mode 100644 (file)
index 0000000..ce77651
--- /dev/null
@@ -0,0 +1,24 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2013 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <christian.himpel@intel.com>
+
+   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
+main (void)
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.btrace/enable.exp b/gdb/testsuite/gdb.btrace/enable.exp
new file mode 100644 (file)
index 0000000..f3acbf8
--- /dev/null
@@ -0,0 +1,84 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <christian.himpel@intel.com>
+#
+# 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/>.
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+# record cannot be stopped, if it was never active
+gdb_test "record stop" "No record target is currently active\\..*" "record stop without target"
+
+# btrace cannot be enabled without a running inferior
+gdb_test "record btrace" "The program is not being run\\." "record btrace without running program"
+
+# no function and no instruction history without btrace enabled
+gdb_test "record function-call-history" "No record target is currently active\\..*" "record function-call-history without target"
+gdb_test "record instruction-history" "No record target is currently active\\..*" "record instruction-history without target"
+gdb_test "info record" "No record target is currently active\\." "info record without target"
+
+# start inferior
+standard_testfile
+if [prepare_for_testing $testfile.exp $testfile {} {debug}] {
+    return -1
+}
+if ![runto_main] {
+    return -1
+}
+
+# enable btrace
+gdb_test_no_output "record btrace" "record btrace"
+gdb_test "record function-call-history" "No trace\\." "record function-call-history without trace"
+gdb_test "record instruction-history" "No trace\\." "record instruction-history without trace"
+
+# btrace cannot be enabled twice
+gdb_test "record btrace" "The process is already being recorded\\." "record btrace the second time"
+
+# full record cannot be activated as long as btrace is active
+gdb_test "record full" "Process record target already running\\.  Use \"record stop\" to stop record target first\\." "record full cannot be enabled"
+
+# no trace recorded yet
+gdb_test "info record" "Active record target: record-btrace\r\nRecorded 0 instructions in 0 functions for thread 1.*\\." "info record without trace"
+
+# stop btrace record
+gdb_test "record stop" "Process record is stopped and all execution logs are deleted\\." "record stop"
+gdb_test "record stop" "No record target is currently active\\..*" "record stop the second time"
+
+# enable btrace again
+gdb_test_no_output "record btrace" "record btrace re-enable"
+gdb_test "record btrace" "The process is already being recorded\\." "record btrace re-enable twice"
+
+# continue to the end and make sure we don't die
+gdb_test "continue" ".*Inferior.*exited.*" "continue to end"
+
+# skip the rerun test when using gdbserver
+# otherwise rerun twice, target should be automatically disabled
+load_lib gdbserver-support.exp
+if [skip_gdbserver_tests] {
+    return 0
+}
+clean_restart $testfile
+if ![runto_main] {
+    return -1
+}
+if ![runto_main] {
+    return -1
+}
diff --git a/gdb/testsuite/gdb.btrace/function_call_history.c b/gdb/testsuite/gdb.btrace/function_call_history.c
new file mode 100644 (file)
index 0000000..a76b7c3
--- /dev/null
@@ -0,0 +1,45 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2013 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <christian.himpel@intel.com>
+
+   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
+inc (int i)
+{
+  return i+1;
+}
+
+int
+fib (int n)
+{
+  if (n <= 1)
+    return n;
+
+  return fib(n-2) + fib(n-1);
+}
+
+int
+main (void)
+{
+  int i, j;
+
+  for (i = 0; i < 10; i++)
+    j += inc(i);
+
+  j += fib(3); /* bp.1 */
+  return j; /* bp.2 */
+}
diff --git a/gdb/testsuite/gdb.btrace/function_call_history.exp b/gdb/testsuite/gdb.btrace/function_call_history.exp
new file mode 100644 (file)
index 0000000..97447e1
--- /dev/null
@@ -0,0 +1,219 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <christian.himpel@intel.com>
+#
+# 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/>.
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# start inferior
+standard_testfile
+if [prepare_for_testing function_call_history.exp $testfile {} {debug}] {
+    return -1
+}
+if ![runto_main] {
+    return -1
+}
+
+# start btrace
+gdb_test_no_output "record btrace"
+
+# set bp after increment loop and continue
+set bp_location [gdb_get_line_number "bp.1" $testfile.c]
+gdb_breakpoint $bp_location
+gdb_continue_to_breakpoint "cont to $bp_location" ".*$testfile.c:$bp_location.*"
+
+# show function call history with unlimited size, we expect to see all 21 entries
+gdb_test_no_output "set record function-call-history-size 0"
+gdb_test "record function-call-history" "
+0\tmain\r
+1\tinc\r
+2\tmain\r
+3\tinc\r
+4\tmain\r
+5\tinc\r
+6\tmain\r
+7\tinc\r
+8\tmain\r
+9\tinc\r
+10\tmain\r
+11\tinc\r
+12\tmain\r
+13\tinc\r
+14\tmain\r
+15\tinc\r
+16\tmain\r
+17\tinc\r
+18\tmain\r
+19\tinc\r
+20\tmain\r" "record function-call-history - with size unlimited"
+
+# show function call history with size of 21, we expect to see all 21 entries
+gdb_test_no_output "set record function-call-history-size 21"
+# show function call history
+gdb_test "record function-call-history 0" "
+0\tmain\r
+1\tinc\r
+2\tmain\r
+3\tinc\r
+4\tmain\r
+5\tinc\r
+6\tmain\r
+7\tinc\r
+8\tmain\r
+9\tinc\r
+10\tmain\r
+11\tinc\r
+12\tmain\r
+13\tinc\r
+14\tmain\r
+15\tinc\r
+16\tmain\r
+17\tinc\r
+18\tmain\r
+19\tinc\r
+20\tmain\r" "record function-call-history - show all 21 entries"
+
+# show first 15 entries
+gdb_test_no_output "set record function-call-history-size 15"
+gdb_test "record function-call-history 0" "
+0\tmain\r
+1\tinc\r
+2\tmain\r
+3\tinc\r
+4\tmain\r
+5\tinc\r
+6\tmain\r
+7\tinc\r
+8\tmain\r
+9\tinc\r
+10\tmain\r
+11\tinc\r
+12\tmain\r
+13\tinc\r
+14\tmain\r" "record function-call-history - show first 15 entries"
+
+# show last 6 entries
+gdb_test "record function-call-history +" "
+15\tinc\r
+16\tmain\r
+17\tinc\r
+18\tmain\r
+19\tinc\r
+20\tmain\r" "record function-call-history - show last 6 entries"
+
+# moving further should not work
+gdb_test "record function-call-history +" "At the end of the branch trace record\\." "record function-call-history - at the end (1)"
+
+# make sure we cannot move any further a second time
+gdb_test "record function-call-history +" "At the end of the branch trace record\\." "record function-call-history - at the end (2)"
+
+# moving back showing the latest 15 function calls
+gdb_test "record function-call-history -" "
+6\tmain\r
+7\tinc\r
+8\tmain\r
+9\tinc\r
+10\tmain\r
+11\tinc\r
+12\tmain\r
+13\tinc\r
+14\tmain\r
+15\tinc\r
+16\tmain\r
+17\tinc\r
+18\tmain\r
+19\tinc\r
+20\tmain\r" "record function-call-history - show last 15 entries"
+
+# moving further back shows the 6 first function calls
+gdb_test "record function-call-history -" "
+0\tmain\r
+1\tinc\r
+2\tmain\r
+3\tinc\r
+4\tmain\r
+5\tinc\r" "record function-call-history - show first 6 entries"
+
+# moving further back shouldn't work
+gdb_test "record function-call-history -" "At the start of the branch trace record\\." "record function-call-history - at the start (1)"
+
+# make sure we cannot move any further back
+gdb_test "record function-call-history -" "At the start of the branch trace record\\." "record function-call-history - at the start (2)"
+
+# moving forward again, but this time with file and line number, expected to see the first 15 entries
+gdb_test "record function-call-history /l +" "
+.*$srcfile:40-41\tmain\r
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-41\tmain\r
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-41\tmain\r
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-41\tmain\r
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-41\tmain\r
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-41\tmain\r
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-41\tmain\r
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-41\tmain\r" "record function-call-history /l - show first 15 entries"
+
+# moving forward and expect to see the latest 6 entries
+gdb_test "record function-call-history /l +" "
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-41\tmain\r
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-41\tmain\r
+.*$srcfile:22-24\tinc\r
+.*$srcfile:40-43\tmain\r" "record function-call-history /l - show last 6 entries"
+
+# moving further forward shouldn't work
+gdb_test "record function-call-history /l +" "At the end of the branch trace record\\." "record function-call-history /l - at the end (1)"
+gdb_test "record function-call-history /l" "At the end of the branch trace record\\." "record function-call-history /l - at the end (2)"
+
+set expected_range "3\tinc\r
+4\tmain\r
+5\tinc\r
+6\tmain\r
+7\tinc\r
+8\tmain\r
+9\tinc\r"
+
+# show functions in instruction range
+gdb_test "record function-call-history 3,10" $expected_range "absolute instruction range"
+gdb_test "record function-call-history 3,+7" $expected_range "relative positive instruction range"
+gdb_test "record function-call-history 10,-7" $expected_range "relative negative instruction range"
+
+# set bp after fib recursion and continue
+set bp_location [gdb_get_line_number "bp.2" $testfile.c]
+gdb_breakpoint $bp_location
+gdb_continue_to_breakpoint "cont to $bp_location" ".*$testfile.c:$bp_location.*"
+
+# at this point we expect to have main, fib, ..., fib, main, where fib occurs 8 times,
+# so we limit the output to only show the latest 10 function calls
+gdb_test_no_output "set record function-call-history-size 10"
+set message "show recursive function call history"
+gdb_test_multiple "record function-call-history" $message {
+    -re "13\tmain\r\n14\tfib\r\n15\tfib\r\n16\tfib\r\n17\tfib\r\n18\tfib\r\n19\tfib\r\n20\tfib\r\n21\tfib\r\n22         main\r\n$gdb_prompt $" {
+        pass $message
+    }
+    -re "13\tinc\r\n14\tmain\r\n15\tinc\r\n16\tmain\r\n17\tinc\r\n18\tmain\r\n19\tinc\r\n20\tmain\r\n21\tfib\r\n22\tmain\r\n$gdb_prompt $" {
+        # recursive function calls appear only as 1 call
+        kfail "gdb/15240" $message
+    }
+}
diff --git a/gdb/testsuite/gdb.btrace/instruction_history.S b/gdb/testsuite/gdb.btrace/instruction_history.S
new file mode 100644 (file)
index 0000000..5c74b46
--- /dev/null
@@ -0,0 +1,32 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2013 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <christian.himpel@intel.com>
+
+   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/>.  */
+
+       .text
+       .globl loop
+       .type  loop, @function
+
+loop:
+       movl $0x2, %eax /* bp.1 */
+.L1:
+       cmpl $0, %eax
+       je .L2
+       decl %eax
+       jmp .L1
+.L2:
+       ret /* bp.2 */
diff --git a/gdb/testsuite/gdb.btrace/instruction_history.c b/gdb/testsuite/gdb.btrace/instruction_history.c
new file mode 100644 (file)
index 0000000..45d9d67
--- /dev/null
@@ -0,0 +1,26 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2013 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <christian.himpel@intel.com>
+
+   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
+main (void)
+{
+  /* loop is declared in instruction_history.S */
+  loop ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.btrace/instruction_history.exp b/gdb/testsuite/gdb.btrace/instruction_history.exp
new file mode 100644 (file)
index 0000000..c1a61b7
--- /dev/null
@@ -0,0 +1,195 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <christian.himpel@intel.com>
+#
+# 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/>.
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# compile and run to main
+standard_testfile .c .S
+if [prepare_for_testing $testfile.exp $testfile "$srcfile $srcfile2" {debug}] {
+    return -1
+}
+if ![runto_main] {
+    return -1
+}
+
+# set bp before loop and continue
+set bp_location [gdb_get_line_number "bp.1" $srcfile2]
+gdb_breakpoint $srcfile2:$bp_location
+gdb_continue_to_breakpoint "cont to $bp_location" ".*$srcfile2:$bp_location.*"
+
+# start btrace
+gdb_test_no_output "record btrace"
+
+# set bp after loop and continue
+set bp_location [gdb_get_line_number "bp.2" $srcfile2]
+gdb_breakpoint $srcfile2:$bp_location
+gdb_continue_to_breakpoint "cont to $bp_location" ".*$srcfile2:$bp_location.*"
+
+# The following test cases test if "browsing" through the
+# instruction history works as expected. So for the tests
+# it is necessary to count the number of lines that are
+# shown by the "record instruction-history" command.
+
+set testname "determine number of recorded instructions"
+gdb_test_multiple "info record" $testname {
+    -re "Active record target: record-btrace\r\nRecorded \(\[0-9\]*\) instructions in \(\[0-9\]*\) functions for thread 1 .*\\.\r\n$gdb_prompt $" {
+        set traced $expect_out(1,string)
+        set traced_functions $expect_out(2,string)
+        pass $testname
+    }
+}
+
+# we have exactly 7 instructions here
+set message "exactly 7 instructions"
+if { $traced != 7 } {
+    fail $message
+} else {
+    pass $message
+}
+
+# test that we see the expected instructions
+gdb_test "record instruction-history 1,6" "
+1\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r
+2\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tdec    %eax\r
+3\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tjmp    0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r
+4\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tcmp    \\\$0x0,%eax\r
+5\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r"
+
+gdb_test "record instruction-history /f 1,+5" "
+1\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r
+2\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tdec    %eax\r
+3\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tjmp    0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r
+4\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tcmp    \\\$0x0,%eax\r
+5\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r"
+
+gdb_test "record instruction-history /p 6,-5" "
+1\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r
+2\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tdec    %eax\r
+3\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tjmp    0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r
+4\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tcmp    \\\$0x0,%eax\r
+5\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r"
+
+gdb_test "record instruction-history /pf 1,6" "
+1\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r
+2\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tdec    %eax\r
+3\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tjmp    0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r
+4\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tcmp    \\\$0x0,%eax\r
+5\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r"
+
+# the following tests are checking the iterators
+# to avoid lots of regexps, we just check the number of lines that
+# were printed during command execution.
+
+# test_lines_output returns the output lines from command as a list.
+proc test_lines_output { command message } {
+    global gdb_prompt
+    set message "test_lines_output: $message"
+    gdb_test_multiple $command $message {
+        -re "\n\(.*\)\r\n$gdb_prompt $" {
+            return [split [string trim $expect_out(1,string)] "\n"]
+        }
+    }
+}
+
+# test_lines_length returns the number of lines from command.
+proc test_lines_length { command message } {
+    return [llength [test_lines_output $command $message]]
+}
+
+# show instruction history with unlimited size, we expect to see
+# all $traced instructions
+gdb_test_no_output "set record instruction-history-size 0"
+set message "record instruction-history - unlimited"
+set lines [test_lines_length "record instruction-history 0" $message]
+if { $traced != $lines } {
+    fail $message
+} else {
+    pass $message
+}
+
+gdb_test_no_output "set record instruction-history-size $traced"
+set message "record instruction-history - traced"
+set lines [test_lines_length "record instruction-history 0" $message]
+if { $traced != $lines } {
+    fail $message
+} else {
+    pass $message
+}
+
+# test that the iterator works
+set history_size 3
+gdb_test_no_output "set record instruction-history-size $history_size"
+set message "browse history forward start"
+set lines [test_lines_length "record instruction-history 0" $message]
+if { $lines != $history_size } {
+    fail $message
+} else {
+    pass $message
+}
+
+set message "browse history forward middle"
+set lines [test_lines_length "record instruction-history +" $message]
+if { $lines != $history_size } {
+    fail $message
+} else {
+    pass $message
+}
+
+set message "browse history forward last"
+set lines [test_lines_length "record instruction-history +" $message]
+if { $lines != 1 } {
+    fail $message
+} else {
+    pass $message
+}
+
+gdb_test "record instruction-history" "At the end of the branch trace record\\." "browse history forward beyond 1"
+
+# make sure we cannot move further
+gdb_test "record instruction-history" "At the end of the branch trace record\\." "browse history forward beyond 2"
+
+set message "browse history backward last"
+set lines [test_lines_length "record instruction-history -" $message]
+if { $lines != $history_size } {
+    fail $message
+} else {
+    pass $message
+}
+
+set message "browse history backward middle"
+set lines [test_lines_length "record instruction-history -" $message]
+if { $lines != $history_size } {
+    fail $message
+} else {
+    pass $message
+}
+
+set message "browse history backward first"
+set lines [test_lines_length "record instruction-history -" $message]
+if { $lines != 1 } {
+    fail $message
+} else {
+    pass $message
+}
+
+gdb_test "record instruction-history -" "At the start of the branch trace record\\." "browse history backward beyond 1"
+
+# make sure we cannot move further back
+gdb_test "record instruction-history -" "At the start of the branch trace record\\." "browse history backward beyond 2"
index 8b16b3827e96107741787ed70981001405bccd72..f7f2ac9473d410c7fc168ad75e1535a813dec970 100644 (file)
@@ -2097,6 +2097,74 @@ proc skip_vsx_tests {} {
     return $skip_vsx_tests_saved
 }
 
+# Run a test on the target to see if it supports btrace hardware.  Return 0 if so,
+# 1 if it does not.  Based on 'check_vmx_hw_available' from the GCC testsuite.
+
+proc skip_btrace_tests {} {
+    global skip_btrace_tests_saved
+    global srcdir subdir gdb_prompt inferior_exited_re
+
+    # Use the cached value, if it exists.
+    set me "skip_btrace_tests"
+    if [info exists skip_btrace_tests_saved] {
+        verbose "$me:  returning saved $skip_btrace_tests_saved" 2
+        return $skip_btrace_tests_saved
+    }
+
+    if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
+        verbose "$me:  target does not support btrace, returning 1" 2
+        return [set skip_btrace_tests_saved 1]
+    }
+
+    # Set up, compile, and execute a test program.
+    # Include the current process ID in the file names to prevent conflicts
+    # with invocations for multiple testsuites.
+    set src [standard_output_file btrace[pid].c]
+    set exe [standard_output_file btrace[pid].x]
+
+    set f [open $src "w"]
+    puts $f "int main(void) { return 0; }"
+    close $f
+
+    verbose "$me:  compiling testfile $src" 2
+    set compile_flags {debug nowarnings quiet}
+    set lines [gdb_compile $src $exe executable $compile_flags]
+    file delete $src
+
+    if ![string match "" $lines] then {
+        verbose "$me:  testfile compilation failed, returning 1" 2
+        return [set skip_btrace_tests_saved 1]
+    }
+
+    # No error message, compilation succeeded so now run it via gdb.
+
+    clean_restart btrace[pid].x
+    if ![runto_main] {
+        return [set skip_btrace_tests_saved 1]
+    }
+    # In case of an unexpected output, we return 2 as a fail value.
+    set skip_btrace_tests_saved 2
+    gdb_test_multiple "record btrace" "check btrace support" {
+        -re "You can't do that when your target is.*\r\n$gdb_prompt $" {
+            set skip_btrace_tests_saved 1
+        }
+        -re "Target does not support branch tracing.*\r\n$gdb_prompt $" {
+            set skip_btrace_tests_saved 1
+        }
+        -re "Could not enable branch tracing.*\r\n$gdb_prompt $" {
+            set skip_btrace_tests_saved 1
+        }
+        -re "^record btrace\r\n$gdb_prompt $" {
+            set skip_btrace_tests_saved 0
+        }
+    }
+    gdb_exit
+    remote_file build delete $exe
+
+    verbose "$me:  returning $skip_btrace_tests_saved" 2
+    return $skip_btrace_tests_saved
+}
+
 # Skip all the tests in the file if you are not on an hppa running
 # hpux target.