btrace: indicate speculative execution
authorMarkus Metzger <markus.t.metzger@intel.com>
Wed, 19 Mar 2014 12:49:58 +0000 (13:49 +0100)
committerMarkus Metzger <markus.t.metzger@intel.com>
Fri, 7 Aug 2015 08:22:39 +0000 (10:22 +0200)
Indicate speculatively executed instructions with a leading '?'.  We use the
space that is normally used for the PC prefix.  In the case where the
instruction at the current PC had been executed speculatively before, the PC
prefix will be partially overwritten resulting in "?> ".

As a side-effect, the /p modifier to omit the PC prefix in the "record
instruction-history" command now uses a 3-space PC prefix "   " in order to
have enough space for the speculative execution indication.

gdb/
* btrace.c (btrace_compute_ftrace_bts): Clear insn flags.
(pt_btrace_insn_flags): New.
(ftrace_add_pt): Call pt_btrace_insn_flags.
* btrace.h (btrace_insn_flag): New.
(btrace_insn) <flags>: New.
* record-btrace.c (btrace_insn_history): Print insn prefix.
* NEWS: Announce it.

doc/
* gdb.texinfo (Process Record and Replay): Document prefixing of
speculatively executed instructions in the "record instruction-history"
command.

testsuite/
* gdb.btrace/instruction_history.exp: Update.
* gdb.btrace/tsx.exp: New.
* gdb.btrace/tsx.c: New.
* lib/gdb.exp (skip_tsx_tests, skip_btrace_pt_tests): New.

13 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/btrace.c
gdb/btrace.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/record-btrace.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.btrace/instruction_history.exp
gdb/testsuite/gdb.btrace/tsx.c [new file with mode: 0644]
gdb/testsuite/gdb.btrace/tsx.exp [new file with mode: 0644]
gdb/testsuite/gdb.btrace/x86-tsx.S [new file with mode: 0644]
gdb/testsuite/lib/gdb.exp

index 105ab5a43dd746504392918fe11f190711843eb6..e9ba28127b6b03773ceef6dcd106d416e2a0984b 100644 (file)
@@ -1,3 +1,13 @@
+2015-08-07  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * btrace.c (btrace_compute_ftrace_bts): Clear insn flags.
+       (pt_btrace_insn_flags): New.
+       (ftrace_add_pt): Call pt_btrace_insn_flags.
+       * btrace.h (btrace_insn_flag): New.
+       (btrace_insn) <flags>: New.
+       * record-btrace.c (btrace_insn_history): Print insn prefix.
+       * NEWS: Announce it.
+
 2015-08-07  Markus Metzger  <markus.t.metzger@intel.com>
 
        * configure.ac: Check for PERF_ATTR_SIZE_VER5 in linux/perf_event.h
index 7ce97587b83ecc332f37b79255474c93ef92fbd5..7e58cc3f31aa961f700ca9b511a0b6c558f73a90 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -5,6 +5,9 @@
 
 * Support for tracepoints on aarch64-linux was added in GDBserver.
 
+* The 'record instruction-history' command now indicates speculative execution
+  when using the Intel(R) Processor Trace recording format.
+
 *** Changes in GDB 7.10
 
 * Support for process record-replay and reverse debugging on aarch64*-linux*
index 94942f4a490347f18afc661505eea525da65a8c5..abdf639f23772fca53e7b68ab4ee73d24ac7990a 100644 (file)
@@ -660,6 +660,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
          insn.pc = pc;
          insn.size = size;
          insn.iclass = ftrace_classify_insn (gdbarch, pc);
+         insn.flags = 0;
 
          ftrace_update_insns (end, &insn);
 
@@ -725,6 +726,19 @@ pt_reclassify_insn (enum pt_insn_class iclass)
     }
 }
 
+/* Return the btrace instruction flags for INSN.  */
+
+static enum btrace_insn_flag
+pt_btrace_insn_flags (const struct pt_insn *insn)
+{
+  enum btrace_insn_flag flags = 0;
+
+  if (insn->speculative)
+    flags |= BTRACE_INSN_FLAG_SPECULATIVE;
+
+  return flags;
+}
+
 /* Add function branch trace using DECODER.  */
 
 static void
@@ -792,6 +806,7 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
          btinsn.pc = (CORE_ADDR) insn.ip;
          btinsn.size = (gdb_byte) insn.size;
          btinsn.iclass = pt_reclassify_insn (insn.iclass);
+         btinsn.flags = pt_btrace_insn_flags (&insn);
 
          ftrace_update_insns (end, &btinsn);
        }
index 93c84ffa0fb0270b3889a15b928d3448690202d0..756a778fe1992ac6d219c6713ca4e11ece163b11 100644 (file)
@@ -52,6 +52,13 @@ enum btrace_insn_class
   BTRACE_INSN_JUMP
 };
 
+/* Instruction flags.  */
+enum btrace_insn_flag
+{
+  /* The instruction has been executed speculatively.  */
+  BTRACE_INSN_FLAG_SPECULATIVE = (1 << 0)
+};
+
 /* A branch trace instruction.
 
    This represents a single instruction in a branch trace.  */
@@ -65,6 +72,9 @@ struct btrace_insn
 
   /* The instruction class of this instruction.  */
   enum btrace_insn_class iclass;
+
+  /* A bit vector of BTRACE_INSN_FLAGS.  */
+  enum btrace_insn_flag flags;
 };
 
 /* A vector of branch trace instructions.  */
index eec2dc658a6b8737becc9b0b136079df8ef05915..473debfcf5e7ebabcf984b65535b792858ad9b98 100644 (file)
@@ -1,3 +1,9 @@
+2015-08-07  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * gdb.texinfo (Process Record and Replay): Document prefixing of
+       speculatively executed instructions in the "record instruction-history"
+       command.
+
 2015-07-20  Doug Evans  <dje@google.com>
 
        * Makefile.in (STABS_DOC_BUILD_INCLUDES): Add gdb-cfg.texi, GDBvn.texi.
index 9e2ecd150353bc07feedabe47d25f2b98a92057d..863bb66fcad6ae294e82cc3233dfd5b78f321e12 100644 (file)
@@ -6736,8 +6736,13 @@ recorded ``future'' and begin recording a new ``future''.
 Disassembles instructions from the recorded execution log.  By
 default, ten instructions are disassembled.  This can be changed using
 the @code{set record instruction-history-size} command.  Instructions
-are printed in execution order.  There are several ways to specify
-what part of the execution log to disassemble:
+are printed in execution order.
+
+Speculatively executed instructions are prefixed with @samp{?}.  This
+feature is not available for all recording formats.
+
+There are several ways to specify what part of the execution log to
+disassemble:
 
 @table @code
 @item record instruction-history @var{insn}
index 6f4ee669422c0757259e4e8bd55f34bc62ce30fa..2f4317161fec8de6f9e0dba0a4bf1a7de45831cb 100644 (file)
@@ -567,14 +567,35 @@ btrace_insn_history (struct ui_out *uiout,
        }
       else
        {
+         char prefix[4];
+
+         /* We may add a speculation prefix later.  We use the same space
+            that is used for the pc prefix.  */
+         if ((flags & DISASSEMBLY_OMIT_PC) == 0)
+           strncpy (prefix, pc_prefix (insn->pc), 3);
+         else
+           {
+             prefix[0] = ' ';
+             prefix[1] = ' ';
+             prefix[2] = ' ';
+           }
+         prefix[3] = 0;
+
          /* Print the instruction index.  */
          ui_out_field_uint (uiout, "index", btrace_insn_number (&it));
          ui_out_text (uiout, "\t");
 
+         /* Indicate speculative execution by a leading '?'.  */
+         if ((insn->flags & BTRACE_INSN_FLAG_SPECULATIVE) != 0)
+           prefix[0] = '?';
+
+         /* Print the prefix; we tell gdb_disassembly below to omit it.  */
+         ui_out_field_fmt (uiout, "prefix", "%s", prefix);
+
          /* Disassembly with '/m' flag may not produce the expected result.
             See PR gdb/11833.  */
-         gdb_disassembly (gdbarch, uiout, NULL, flags, 1, insn->pc,
-                          insn->pc + 1);
+         gdb_disassembly (gdbarch, uiout, NULL, flags | DISASSEMBLY_OMIT_PC,
+                          1, insn->pc, insn->pc + 1);
        }
     }
 }
index bf845a4dbfabd305ab592bbb642627578462af88..14171883aba61292390ae375236e70e1f3dd5bca 100644 (file)
@@ -1,3 +1,10 @@
+2015-08-07  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * lib/gdb.exp (skip_tsx_tests, skip_btrace_pt_tests): New.
+       * gdb.btrace/instruction_history.exp: Update.
+       * gdb.btrace/tsx.exp: New.
+       * gdb.btrace/tsx.c: New.
+
 2015-08-06  Pedro Alves <palves@redhat.com>
 
        * gdb.reverse/step-precsave.exp: Use with_timeout_factor to
index ba06647f9ab0a16160f29f20c4917da60ebec4ba..0348f704122e4d2d6d21ccc0bf30bec038d5b4bc 100644 (file)
@@ -82,19 +82,19 @@ gdb_test "record instruction-history /f 3,+5" [multi_line \
   ]
 
 gdb_test "record instruction-history /p 7,-5" [multi_line \
-  "3\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
-  "4\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tdec    %eax" \
-  "5\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tjmp    0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
-  "6\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tcmp    \\\$0x0,%eax" \
-  "7\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r" \
+  "3\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
+  "4\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tdec    %eax" \
+  "5\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tjmp    0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
+  "6\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tcmp    \\\$0x0,%eax" \
+  "7\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r" \
   ]
 
 gdb_test "record instruction-history /pf 3,7" [multi_line \
-  "3\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
-  "4\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tdec    %eax" \
-  "5\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tjmp    0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
-  "6\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tcmp    \\\$0x0,%eax" \
-  "7\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r" \
+  "3\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
+  "4\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tdec    %eax" \
+  "5\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tjmp    0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
+  "6\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tcmp    \\\$0x0,%eax" \
+  "7\t   0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r" \
   ]
 
 gdb_test "record instruction-history 3,3" "3\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r"
diff --git a/gdb/testsuite/gdb.btrace/tsx.c b/gdb/testsuite/gdb.btrace/tsx.c
new file mode 100644 (file)
index 0000000..f06046d
--- /dev/null
@@ -0,0 +1,26 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2015 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/>.  */
+
+
+extern void test (void);
+
+int
+main (void)
+{
+  test ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.btrace/tsx.exp b/gdb/testsuite/gdb.btrace/tsx.exp
new file mode 100644 (file)
index 0000000..525d4d2
--- /dev/null
@@ -0,0 +1,41 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2015 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/>.
+
+if { [skip_btrace_pt_tests] } { return -1 }
+if { [skip_tsx_tests] } { return -1 }
+
+# compile and run to main
+standard_testfile .c x86-tsx.S
+if [prepare_for_testing tsx.exp $testfile "$srcfile $srcfile2" {debug}] {
+    return -1
+}
+if ![runto_main] {
+    return -1
+}
+
+# record the test
+gdb_test_no_output "record btrace pt"
+gdb_test "next"
+
+# look at the instruction trace
+gdb_test "record instruction-history" [multi_line \
+  ".*" \
+  "\[0-9\]*\t\\?  0x\[0-9a-f\]+ <test\\+\[0-9\]+>:\txbegin\[^\\\r\\\n\]*" \
+  "\[0-9\]*\t\\?  0x\[0-9a-f\]+ <test\\+\[0-9\]+>:\tmov\[^\\\r\\\n\]*" \
+  "\[0-9\]*\t   0x\[0-9a-f\]+ <test\\+\[0-9\]+>:\txend\[^\\\r\\\n\]*" \
+  ".*" \
+  ]
diff --git a/gdb/testsuite/gdb.btrace/x86-tsx.S b/gdb/testsuite/gdb.btrace/x86-tsx.S
new file mode 100644 (file)
index 0000000..640d969
--- /dev/null
@@ -0,0 +1,29 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2015 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/>.  */
+
+       .text
+       .globl test
+       .type  test, @function
+
+test:
+       xbegin .Lhandler
+       mov $0, %eax
+       xend
+       ret
+.Lhandler:
+       mov $1, %eax
+       ret
index 5659906c0b9e590762aff6f74d97cdd81fb9a727..ad2ad6e00acf86ed53bd350ce0c9ecfa2e617aa1 100644 (file)
@@ -2562,6 +2562,63 @@ gdb_caching_proc skip_vsx_tests {
     return $skip_vsx_tests
 }
 
+# Run a test on the target to see if it supports TSX hardware.  Return 0 if so,
+# 1 if it does not.  Based on 'check_vmx_hw_available' from the GCC testsuite.
+
+gdb_caching_proc skip_tsx_tests {
+    global srcdir subdir gdb_prompt inferior_exited_re
+
+    set me "skip_tsx_tests"
+
+    set src [standard_temp_file tsx[pid].c]
+    set exe [standard_temp_file tsx[pid].x]
+
+    gdb_produce_source $src {
+    int main() {
+        asm volatile ("xbegin .L0");
+        asm volatile ("xend");
+        asm volatile (".L0: nop");
+        return 0;
+    }
+    }
+
+    verbose "$me:  compiling testfile $src" 2
+    set lines [gdb_compile $src $exe executable {nowarnings quiet}]
+    file delete $src
+
+    if ![string match "" $lines] then {
+        verbose "$me:  testfile compilation failed." 2
+        return 1
+    }
+
+    # No error message, compilation succeeded so now run it via gdb.
+
+    gdb_exit
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_load "$exe"
+    gdb_run_cmd
+    gdb_expect {
+        -re ".*Illegal instruction.*${gdb_prompt} $" {
+            verbose -log "$me:  TSX hardware not detected."
+            set skip_tsx_tests 1
+        }
+        -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
+            verbose -log "$me:  TSX hardware detected."
+            set skip_tsx_tests 0
+        }
+        default {
+            warning "\n$me:  default case taken."
+            set skip_tsx_tests 1
+        }
+    }
+    gdb_exit
+    remote_file build delete $exe
+
+    verbose "$me:  returning $skip_tsx_tests" 2
+    return $skip_tsx_tests
+}
+
 # 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.
 
@@ -2628,6 +2685,73 @@ gdb_caching_proc skip_btrace_tests {
     return $skip_btrace_tests
 }
 
+# Run a test on the target to see if it supports btrace pt hardware.
+# Return 0 if so, 1 if it does not.  Based on 'check_vmx_hw_available'
+# from the GCC testsuite.
+
+gdb_caching_proc skip_btrace_pt_tests {
+    global srcdir subdir gdb_prompt inferior_exited_re
+
+    set me "skip_btrace_tests"
+    if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
+        verbose "$me:  target does not support btrace, returning 1" 2
+        return 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_temp_file btrace[pid].c]
+    set exe [standard_temp_file btrace[pid].x]
+
+    gdb_produce_source $src {
+       int main(void) { return 0; }
+    }
+
+    verbose "$me:  compiling testfile $src" 2
+    set compile_flags {debug nowarnings quiet}
+    set lines [gdb_compile $src $exe executable $compile_flags]
+
+    if ![string match "" $lines] then {
+        verbose "$me:  testfile compilation failed, returning 1" 2
+       file delete $src
+        return 1
+    }
+
+    # No error message, compilation succeeded so now run it via gdb.
+
+    gdb_exit
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_load $exe
+    if ![runto_main] {
+       file delete $src
+        return 1
+    }
+    file delete $src
+    # In case of an unexpected output, we return 2 as a fail value.
+    set skip_btrace_tests 2
+    gdb_test_multiple "record btrace pt" "check btrace support" {
+        -re "You can't do that when your target is.*\r\n$gdb_prompt $" {
+            set skip_btrace_tests 1
+        }
+        -re "Target does not support branch tracing.*\r\n$gdb_prompt $" {
+            set skip_btrace_tests 1
+        }
+        -re "Could not enable branch tracing.*\r\n$gdb_prompt $" {
+            set skip_btrace_tests 1
+        }
+        -re "^record btrace pt\r\n$gdb_prompt $" {
+            set skip_btrace_tests 0
+        }
+    }
+    gdb_exit
+    remote_file build delete $exe
+
+    verbose "$me:  returning $skip_btrace_tests" 2
+    return $skip_btrace_tests
+}
+
 # Skip all the tests in the file if you are not on an hppa running
 # hpux target.