btrace: indicate speculative execution

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.
This commit is contained in:
Markus Metzger 2014-03-19 13:49:58 +01:00
parent 5599c40462
commit da8c46d296
13 changed files with 311 additions and 14 deletions

View 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> 2015-08-07 Markus Metzger <markus.t.metzger@intel.com>
* configure.ac: Check for PERF_ATTR_SIZE_VER5 in linux/perf_event.h * configure.ac: Check for PERF_ATTR_SIZE_VER5 in linux/perf_event.h

View file

@ -5,6 +5,9 @@
* Support for tracepoints on aarch64-linux was added in GDBserver. * 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 *** Changes in GDB 7.10
* Support for process record-replay and reverse debugging on aarch64*-linux* * Support for process record-replay and reverse debugging on aarch64*-linux*

View file

@ -660,6 +660,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
insn.pc = pc; insn.pc = pc;
insn.size = size; insn.size = size;
insn.iclass = ftrace_classify_insn (gdbarch, pc); insn.iclass = ftrace_classify_insn (gdbarch, pc);
insn.flags = 0;
ftrace_update_insns (end, &insn); 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. */ /* Add function branch trace using DECODER. */
static void static void
@ -792,6 +806,7 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
btinsn.pc = (CORE_ADDR) insn.ip; btinsn.pc = (CORE_ADDR) insn.ip;
btinsn.size = (gdb_byte) insn.size; btinsn.size = (gdb_byte) insn.size;
btinsn.iclass = pt_reclassify_insn (insn.iclass); btinsn.iclass = pt_reclassify_insn (insn.iclass);
btinsn.flags = pt_btrace_insn_flags (&insn);
ftrace_update_insns (end, &btinsn); ftrace_update_insns (end, &btinsn);
} }

View file

@ -52,6 +52,13 @@ enum btrace_insn_class
BTRACE_INSN_JUMP 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. /* A branch trace instruction.
This represents a single instruction in a branch trace. */ This represents a single instruction in a branch trace. */
@ -65,6 +72,9 @@ struct btrace_insn
/* The instruction class of this instruction. */ /* The instruction class of this instruction. */
enum btrace_insn_class iclass; enum btrace_insn_class iclass;
/* A bit vector of BTRACE_INSN_FLAGS. */
enum btrace_insn_flag flags;
}; };
/* A vector of branch trace instructions. */ /* A vector of branch trace instructions. */

View 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> 2015-07-20 Doug Evans <dje@google.com>
* Makefile.in (STABS_DOC_BUILD_INCLUDES): Add gdb-cfg.texi, GDBvn.texi. * Makefile.in (STABS_DOC_BUILD_INCLUDES): Add gdb-cfg.texi, GDBvn.texi.

View file

@ -6736,8 +6736,13 @@ recorded ``future'' and begin recording a new ``future''.
Disassembles instructions from the recorded execution log. By Disassembles instructions from the recorded execution log. By
default, ten instructions are disassembled. This can be changed using default, ten instructions are disassembled. This can be changed using
the @code{set record instruction-history-size} command. Instructions the @code{set record instruction-history-size} command. Instructions
are printed in execution order. There are several ways to specify are printed in execution order.
what part of the execution log to disassemble:
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 @table @code
@item record instruction-history @var{insn} @item record instruction-history @var{insn}

View file

@ -567,14 +567,35 @@ btrace_insn_history (struct ui_out *uiout,
} }
else 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. */ /* Print the instruction index. */
ui_out_field_uint (uiout, "index", btrace_insn_number (&it)); ui_out_field_uint (uiout, "index", btrace_insn_number (&it));
ui_out_text (uiout, "\t"); 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. /* Disassembly with '/m' flag may not produce the expected result.
See PR gdb/11833. */ See PR gdb/11833. */
gdb_disassembly (gdbarch, uiout, NULL, flags, 1, insn->pc, gdb_disassembly (gdbarch, uiout, NULL, flags | DISASSEMBLY_OMIT_PC,
insn->pc + 1); 1, insn->pc, insn->pc + 1);
} }
} }
} }

View 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> 2015-08-06 Pedro Alves <palves@redhat.com>
* gdb.reverse/step-precsave.exp: Use with_timeout_factor to * gdb.reverse/step-precsave.exp: Use with_timeout_factor to

View 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 \ 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\]+>" \ "3\t 0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje 0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
"4\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tdec %eax" \ "4\t 0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tdec %eax" \
"5\t0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tjmp 0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \ "5\t 0x\[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" \ "6\t 0x\[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" \ "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 \ 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\]+>" \ "3\t 0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje 0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
"4\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tdec %eax" \ "4\t 0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tdec %eax" \
"5\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tjmp 0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \ "5\t 0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tjmp 0x\[0-9a-f\]+ <loop\\+\[0-9\]+>" \
"6\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tcmp \\\$0x0,%eax" \ "6\t 0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tcmp \\\$0x0,%eax" \
"7\t0x\[0-9a-f\]+ <\\+\[0-9\]+>:\tje 0x\[0-9a-f\]+ <loop\\+\[0-9\]+>\r" \ "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" 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"

View file

@ -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;
}

View file

@ -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\]*" \
".*" \
]

View file

@ -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

View file

@ -2562,6 +2562,63 @@ gdb_caching_proc skip_vsx_tests {
return $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, # 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. # 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 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 # Skip all the tests in the file if you are not on an hppa running
# hpux target. # hpux target.