RE: [patch v9 22/23] testsuite, gdb.btrace: add btrace tests

christian.himpel
2013-03-06T15:32:07Z

> From: Jan Kratochvil [mailto:jan.kratochvil@redhat.com]
> Sent: Tuesday, March 05, 2013 9:14 PM
> To: Metzger, Markus T
> Cc: gdb-patches@sourceware.org; markus.t.metzger@gmail.com; Himpel, Christian
> Subject: Re: [patch v9 22/23] testsuite, gdb.btrace: add btrace tests
>
> On Mon, 04 Mar 2013 18:06:09 +0100, Markus Metzger wrote:
> > From: Christian Himpel <christian.himpel@intel.com>
> >
> > Recursive function calls are listed as only one function call. This is
> > marked as an XFAIL.
> >
> > 2013-03-04 Christian Himpel <christian.himpel@intel.com>
> >
> > gdb/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/x86-instruction_history.S: New file.
> > * lib/gdb.exp: Add btrace skip proc.
> [...]
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.btrace/enable.exp
> > @@ -0,0 +1,83 @@
> > +# 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"
>
> \ -> \\
> First processing is by TCL, second processing is by regex.
> This is regex backslash. This way it acts the same as:
> gdb_test "record stop" "No record target is currently active..*" "record stop without target"
>
> One can also use {...} instead of "..." which avoids the Tcl processing, it
> would be then:
> gdb_test "record stop" {No record target is currently active\.} "record stop without target"

Thanks, I'll address the \. issue in all files.

> And that trailing .* is not needed there, gdb_test automatically matches
> trailing "\r\n$gdb_prompt $".

Yes, but the output is actually 2 lines:
No record target is currently active.
Use one of the "target record-<tab><tab>" commands first.

> > +
> > +# btrace cannot be enabled without a running inferior
> > +gdb_test "record btrace" "The program is not being run\." "record btrace without running program"
>
> Again \ -> \\ .
>
>
>
>
> > +
> > +# 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
>
> standard_testfile should be at the top of file; it does not start/contol GDB
> any way.
>
>
> > +if [prepare_for_testing $testfile.exp $testfile {} {debug}] {
> > + return -1
> > +}
>
> > +runto_main
>
> if ![runto_main] {
> return -1
> }

Done.

> > +
> > +# 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"
>
> \. -> \\.
> twice
>
>
> > +
> > +# 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"
>
> \. -> \\.
>
>
> Many times below again and in the other *.exp files.
>
>
> > +
> > +# 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"
> > +
>
>
> > +# rerun
> > +send_gdb "run\n"
> > +gdb_expect {
> > + -re "The program .* has been started already.*y or n. $" {
> > + send_gdb "y\n"
> > + exp_continue
> > + }
> > + -re "Starting program.*$gdb_prompt $" {
> > + pass "rerun to main"
> > + }
> > + -re "$gdb_prompt $" {
> > + fail "rerun to main"
> > + }
> > + timeout {
> > + fail "(timeout) rerun to main"
> > + }
> > +}
>
> In general one should never use gdb_expect. And send_gdb is used only
> exceptionally. For complicated cases there is gdb_test_multiple. But in this
> case why there isn't just another runto_main?
>
> if ![runto_main] {
> return -1
> }

I had an xfail here before, but that was fixed meanwhile. I'll just use runto_main
instead as you suggested.

> > diff --git a/gdb/testsuite/gdb.btrace/function_call_history.c
> b/gdb/testsuite/gdb.btrace/function_call_history.c
> > new file mode 100644
> > index 0000000..a76b7c3
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.btrace/function_call_history.c
> > @@ -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
> > index 0000000..711dd20
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.btrace/function_call_history.exp
> > @@ -0,0 +1,211 @@
> > +# 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
> > +}
>
>
> > +runto_main
>
> if ![runto_main] {
> return -1
> }

Done.

> > +
> > +# 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 main\r
> > +1 inc\r
> > +2 main\r
> > +3 inc\r
> > +4 main\r
> > +5 inc\r
> > +6 main\r
> > +7 inc\r
> > +8 main\r
> > +9 inc\r
> > +10 main\r
> > +11 inc\r
> > +12 main\r
> > +13 inc\r
> > +14 main\r
> > +15 inc\r
> > +16 main\r
> > +17 inc\r
> > +18 main\r
> > +19 inc\r
> > +20 main\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 main\r
> > +1 inc\r
> > +2 main\r
> > +3 inc\r
> > +4 main\r
> > +5 inc\r
> > +6 main\r
> > +7 inc\r
> > +8 main\r
> > +9 inc\r
> > +10 main\r
> > +11 inc\r
> > +12 main\r
> > +13 inc\r
> > +14 main\r
> > +15 inc\r
> > +16 main\r
> > +17 inc\r
> > +18 main\r
> > +19 inc\r
> > +20 main\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 main\r
> > +1 inc\r
> > +2 main\r
> > +3 inc\r
> > +4 main\r
> > +5 inc\r
> > +6 main\r
> > +7 inc\r
> > +8 main\r
> > +9 inc\r
> > +10 main\r
> > +11 inc\r
> > +12 main\r
> > +13 inc\r
> > +14 main\r" "record function-call-history - show first 15 entries"
> > +
> > +# show last 6 entries
> > +gdb_test "record function-call-history +" "15 inc\r
> > +16 main\r
> > +17 inc\r
> > +18 main\r
> > +19 inc\r
> > +20 main\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 main\r
> > +7 inc\r
> > +8 main\r
> > +9 inc\r
> > +10 main\r
> > +11 inc\r
> > +12 main\r
> > +13 inc\r
> > +14 main\r
> > +15 inc\r
> > +16 main\r
> > +17 inc\r
> > +18 main\r
> > +19 inc\r
> > +20 main\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 main\r
> > +1 inc\r
> > +2 main\r
> > +3 inc\r
> > +4 main\r
> > +5 inc\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 main\r
> > +.*$srcfile:22-24 inc\r
> > +.*$srcfile:40-41 main\r
> > +.*$srcfile:22-24 inc\r
> > +.*$srcfile:40-41 main\r
> > +.*$srcfile:22-24 inc\r
> > +.*$srcfile:40-41 main\r
> > +.*$srcfile:22-24 inc\r
> > +.*$srcfile:40-41 main\r
> > +.*$srcfile:22-24 inc\r
> > +.*$srcfile:40-41 main\r
> > +.*$srcfile:22-24 inc\r
> > +.*$srcfile:40-41 main\r
> > +.*$srcfile:22-24 inc\r
> > +.*$srcfile:40-41 main\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 inc\r
> > +.*$srcfile:40-41 main\r
> > +.*$srcfile:22-24 inc\r
> > +.*$srcfile:40-41 main\r
> > +.*$srcfile:22-24 inc\r
> > +.*$srcfile:40-43 main\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 inc\r
> > +4 main\r
> > +5 inc\r
> > +6 main\r
> > +7 inc\r
> > +8 main\r
> > +9 inc\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 main\r\n14 fib\r\n15 fib\r\n16 fib\r\n17 fib\r\n18 fib\r\n19 fib\r\n20
> fib\r\n21 fib\r\n22 main\r\n$gdb_prompt " {
> > + pass $message
> > + }
> > + -re "13 inc\r\n14 main\r\n15 inc\r\n16 main\r\n17 inc\r\n18 main\r\n19 inc\r\n20
> main\r\n21 fib\r\n22 main\r\n$gdb_prompt " {
> > + # recursive function calls appear only as 1 call
> > + xfail $message
>
> kfail, as already discussed before.
>
>
> A nitpick but there can (and therefore should) be trailing $ match so that no
> more accidental input is accepted there, therefore in both cases:
> main\r\n$gdb_prompt " {
> ->
> main\r\n$gdb_prompt $" {
>
>
>
> > + }
> > +}
> > diff --git a/gdb/testsuite/gdb.btrace/instruction_history.c
> b/gdb/testsuite/gdb.btrace/instruction_history.c
> > new file mode 100644
> > index 0000000..2dc3c6b
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.btrace/instruction_history.c
> > @@ -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 x86-instruction_history.S
>
> Rather /* comments */ ; although one will probably never use such new feature
> with old compilers not supporting // for .c .
>
>
> > + 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
> > index 0000000..92288eb
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.btrace/instruction_history.exp
> > @@ -0,0 +1,190 @@
> > +# 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
> > +if [prepare_for_testing instruction_history.exp $testfile "$testfile.c x86-$testfile.S" {debug}] {
>
> standard_testfile has parameters for this purpose:
> standard_testfile .c x86-instruction_history.S
> if [prepare_for_testing $testfile.exp $testfile "$srcfile $srcfile2" {debug}] {
>
> And please rename x86-instruction_history.S to instruction_history-x86.S so
> that completion works for all the files belonging to a testcase.
>
>
> > + return -1
> > +}
> > +
>
> > +runto_main
>
> if ![runto_main] {
> return -1
> }
>
>
> > +
> > +# set bp before loop and continue
> > +set bp_location [gdb_get_line_number "bp.1" x86-$testfile.S]
> > +gdb_breakpoint x86-$testfile.S:$bp_location
> > +gdb_continue_to_breakpoint "cont to $bp_location" ".*x86-$testfile.S:$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" x86-$testfile.S]
> > +gdb_breakpoint x86-$testfile.S:$bp_location
> > +gdb_continue_to_breakpoint "cont to $bp_location" ".*x86-$testfile.S:$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 " {
>
> Again trailing $gdb_prompt $" like in the other file.
>
>
> > + 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
>
> It is OK as is but FYI one can do the escaping automatically at runtime for any
> string using 'string_to_regexp' function.
>
>
> > +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\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 /pf 1,6" "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"
> > +
> > +# 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 " {
>
> trailing $ again.
>
>
> > + 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"
> > diff --git a/gdb/testsuite/gdb.btrace/x86-instruction_history.S b/gdb/testsuite/gdb.btrace/x86-
> instruction_history.S
> > new file mode 100644
> > index 0000000..5c74b46
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.btrace/x86-instruction_history.S
> > @@ -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/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> > index 8b16b38..1393455 100644
> > --- a/gdb/testsuite/lib/gdb.exp
> > +++ b/gdb/testsuite/lib/gdb.exp
> > @@ -2097,6 +2097,75 @@ 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 btrace[pid].c
> > + set exe btrace[pid].x
>
> Use:
> 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() { return 0; }"
>
> For C there should be:
> 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.
> > +
> > + gdb_exit
> > + gdb_start
> > + gdb_reinitialize_dir $srcdir/$subdir
> > + gdb_load "$exe"
>
> This can be replaced by:
> clean_restart btrace[pid].x
>
> Unfortunately one cannot use $exe as that one has standard_output_file already
> applied which must not be done for clean_restart.
>
>
> > + runto_main
>
> if ![runto_main] {
> return [...]
> }
>
>
> > + # 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 "$gdb_prompt $" {
>
> To test no output has been produced (instead of any output has been produced):
> -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.
> >
> > --
> > 1.7.1
>
> If you follow the advices there shold not be an issue but it would be probably
> worth another review.

Jan, thanks for the feedback. The updated version of the patch will be
submitted by Markus.

Thanks,
christian

>
> Thanks,
> Jan