[1/1] testsuite, btrace: update btrace testsuite to test all btrace recording methods

Message ID 20240304082354.3336-2-abdul.b.ijaz@intel.com
State New
Headers
Series update btrace tests to test all recording methods |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Ijaz, Abdul B March 4, 2024, 8:23 a.m. UTC
  From: "Ijaz, Abdul B" <abdul.b.ijaz@intel.com>

With this change, gdb.btrace will, instead of selecting the
default recording method, run all tests for all available and
applicable methods. This increases testing coverage.

2024-03-02 Abdul Basit Ijaz <abdul.b.ijaz@intel.com>
---
 gdb/testsuite/gdb.btrace/buffer-size.exp      |  37 +-
 gdb/testsuite/gdb.btrace/data.exp             |  64 +--
 gdb/testsuite/gdb.btrace/delta.exp            | 102 +++--
 gdb/testsuite/gdb.btrace/dlopen.exp           |  37 +-
 .../gdb.btrace/enable-new-thread.exp          |  35 +-
 gdb/testsuite/gdb.btrace/enable-running.exp   |  59 +--
 gdb/testsuite/gdb.btrace/enable.exp           | 153 ++++---
 gdb/testsuite/gdb.btrace/exception.exp        | 103 +++--
 .../gdb.btrace/function_call_history.exp      | 414 +++++++++---------
 gdb/testsuite/gdb.btrace/gcore.exp            |  34 +-
 .../gdb.btrace/instruction_history.exp        | 303 ++++++-------
 gdb/testsuite/gdb.btrace/multi-inferior.exp   |  62 +--
 .../gdb.btrace/multi-thread-step.exp          | 106 ++---
 gdb/testsuite/gdb.btrace/nohist.exp           |  30 +-
 gdb/testsuite/gdb.btrace/non-stop.exp         | 305 ++++++-------
 gdb/testsuite/gdb.btrace/reconnect.exp        |  94 ++--
 gdb/testsuite/gdb.btrace/record_goto-step.exp |  39 +-
 gdb/testsuite/gdb.btrace/record_goto.exp      | 310 ++++++-------
 gdb/testsuite/gdb.btrace/rn-dl-bind.exp       |  61 +--
 gdb/testsuite/gdb.btrace/segv.exp             |  40 +-
 gdb/testsuite/gdb.btrace/step.exp             |  48 +-
 gdb/testsuite/gdb.btrace/stepi.exp            | 205 ++++-----
 gdb/testsuite/gdb.btrace/tailcall-only.exp    |  92 ++--
 gdb/testsuite/gdb.btrace/tailcall.exp         | 133 +++---
 gdb/testsuite/gdb.btrace/tsx.exp              |   2 +-
 .../gdb.btrace/unknown_functions.exp          |  66 +--
 gdb/testsuite/gdb.btrace/vdso.exp             |  34 +-
 .../gdb.python/py-record-btrace-threads.exp   |  75 ++--
 gdb/testsuite/lib/gdb.exp                     | 124 +++---
 29 files changed, 1689 insertions(+), 1478 deletions(-)
  

Comments

Metzger, Markus T March 26, 2024, 9:16 a.m. UTC | #1
Hello Abdul,

>With this change, gdb.btrace will, instead of selecting the
>default recording method, run all tests for all available and
>applicable methods. This increases testing coverage.

I reviewed this with 'git show -w'.


>+foreach_with_prefix method {"bts" "pt"} {
>+    if { ![target_supports_btrace $method] } {
>+	unsupported "target does not support record-btrace ${method}"
>+	continue
>+    }

The terminology is 'recording format', not 'recording method'.

In the unsupported string, the $method should already be part of the test prefix.

>+
>+    clean_restart "${testfile}"
>+    if ![runto_main] {
>+	continue
>+    }

We don't need that since the test is going to start over...

>+
>+    # start fresh - without an executable
>+    gdb_exit
>+    gdb_start

...right here.

>+
>+    # record cannot be stopped, if it was never active
>+    gdb_test "record stop" "No recording is currently active\\..*" "record stop
>without target"
>+
>+    # btrace cannot be enabled without a running inferior
>+    gdb_test "record btrace ${method}" "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 recording is currently
>active\\..*" "record function-call-history without target"
>+    gdb_test "record instruction-history" "No recording is currently active\\..*"
>"record instruction-history without target"
>+    gdb_test "info record" "No recording is currently active\\." "info record
>without target"
>+
>+    clean_restart "${testfile}"
>+    if ![runto_main] {
>+	continue
>+    }
>+
>+    # enable btrace
>+    gdb_test_no_output "record btrace ${method}" "record btrace ${method}"

There already is a test prefix supplying $method.  We don't need to repeat that
in the test name.  There are more instances in this file.


>+    # trace the code between the two breakpoints
>+    gdb_continue_to_breakpoint "cont to bp.1" ".*$srcfile:$bp_1\r\n.*"
>+    # increase the BTS buffer size - the trace can be quite big for bts method
>+    gdb_test_no_output "set record btrace ${method} buffer-size 128000"

The comment no longer matches the code.

>+    # moving forward and expect to see the latest 6 entries
>+    gdb_test "record function-call-history /l +" [multi_line \
>+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
>+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
>+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
>+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
>+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
>+	"\[0-9\]*\tmain\tat $srcfile:40,43" \
>+
>+    ] "forward /l - 2"

Why this empty line in the multi_line pattern?


>diff --git a/gdb/testsuite/gdb.btrace/multi-inferior.exp
>b/gdb/testsuite/gdb.btrace/multi-inferior.exp
>index 6996b182e65..06ca93a9686 100644
>--- a/gdb/testsuite/gdb.btrace/multi-inferior.exp
>+++ b/gdb/testsuite/gdb.btrace/multi-inferior.exp

>+	gdb_test_no_output "record btrace ${method}" "record btrace
>${method}"
>+    }

The $method is already part of the test prefix.  We don't need to repeat it
in the test message.  We may be able to just drop the message and use
the default.


>diff --git a/gdb/testsuite/gdb.btrace/reconnect.exp
>b/gdb/testsuite/gdb.btrace/reconnect.exp
>index 41f702a38b3..349d7f7cda9 100644

>-# Test that recording is now off.
>-with_test_prefix "third" {
>-  gdb_test "info record" "No recording is currently active."
>+    # Test that recording is now off.
>+    with_test_prefix "third" {
>+	gdb_test "info record" "No recording is currently active."
>+    }
>+    gdb_test "disconnect" ".*"
> }

Is there an extra

    gdb_test "disconnect" ".*"

at the end?  It shows more clearly with 'git show -w'.


>diff --git a/gdb/testsuite/gdb.btrace/tailcall-only.exp
>b/gdb/testsuite/gdb.btrace/tailcall-only.exp
>index ae3b04e3b66..c90ba8b1bd3 100644
>--- a/gdb/testsuite/gdb.btrace/tailcall-only.exp
>+++ b/gdb/testsuite/gdb.btrace/tailcall-only.exp


>-# We can neither finish nor return.
>-gdb_test "finish" "Cannot find the caller frame.*"
>-gdb_test_multiple "return" "return" {
>-  -re "Make .* return now.*y or n. $" {
>-    send_gdb "y\n"
>-    exp_continue
>-  }

This gets changed from exp_continue...

>+    # We can neither finish nor return.
>+    gdb_test "finish" "Cannot find the caller frame.*"
>+    gdb_test_multiple "return" "return" {
>+	-re "Make .* return now.*y or n. $" {
>+	    send_gdb "y\n"
>+	    continue
>+	}

...to continue.


>diff --git a/gdb/testsuite/gdb.btrace/tsx.exp
>b/gdb/testsuite/gdb.btrace/tsx.exp
>index d312b15027c..11e230c8547 100644
>--- a/gdb/testsuite/gdb.btrace/tsx.exp
>+++ b/gdb/testsuite/gdb.btrace/tsx.exp
>@@ -15,7 +15,7 @@
> # You should have received a copy of the GNU General Public License
> # along with this program.  If not, see <http://www.gnu.org/licenses/>.
>
>-require allow_btrace_pt_tests allow_tsx_tests
>+require allow_btrace_pt_tests allow_tsx_tests allow_btrace_tests

Do we really need allow_btrace_tests when we already require
allow_btrace_pt_tests?


>diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
>index fe4ac7d2719..62eadc9696f 100644
>--- a/gdb/testsuite/lib/gdb.exp
>+++ b/gdb/testsuite/lib/gdb.exp
>@@ -4008,68 +4008,29 @@ gdb_caching_proc allow_avx512fp16_tests {} {
>     return $allow_avx512fp16_tests
> }
>
>-# Run a test on the target to see if it supports btrace hardware.  Return 1 if
>so,
>-# 0 if it does not.  Based on 'check_vmx_hw_available' from the GCC
>testsuite.
>+# Check if btrace is supported on the target.  Return 1 if
>+# so, 0 if it does not.
>
> gdb_caching_proc allow_btrace_tests {} {
>-    global srcdir subdir gdb_prompt inferior_exited_re
>-
>-    set me "allow_btrace_tests"
>     if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
>-	verbose "$me:  target does not support btrace, returning 0" 2
>-	return 0
>-    }
>-
>-    # Compile a test program.
>-    set src { int main() { return 0; } }
>-    if {![gdb_simple_compile $me $src executable]} {
>+	verbose "target_supports_btrace:  target does not support btrace,
>returning 0" 2

Why 'target_supports_btrace:'?

Since we now check the different recording formats, I don't think this
target check adds anything.

> 	return 0
>     }
>
>-    # No error message, compilation succeeded so now run it via gdb.
>-
>-    gdb_exit
>-    gdb_start
>-    gdb_reinitialize_dir $srcdir/$subdir
>-    gdb_load $obj
>-    if ![runto_main] {
>+    if { ![allow_btrace_bts_tests] && ![allow_btrace_pt_tests] } {
> 	return 0
>     }

The inverted logic may be easier to read and extend, i.e.

if { [allow_btrace_bts_tests] } {
  return 1
}
if { [allow_btrace_pt_tests] } {
  return 1
}
return 0

>-    # In case of an unexpected output, we return 2 as a fail value.
>-    set allow_btrace_tests 2
>-    gdb_test_multiple "record btrace" "check btrace support" {
>-        -re "You can't do that when your target is.*\r\n$gdb_prompt $" {
>-	    set allow_btrace_tests 0
>-        }
>-        -re "Target does not support branch tracing.*\r\n$gdb_prompt $" {
>-	    set allow_btrace_tests 0
>-        }
>-        -re "Could not enable branch tracing.*\r\n$gdb_prompt $" {
>-	    set allow_btrace_tests 0
>-        }
>-        -re "^record btrace\r\n$gdb_prompt $" {
>-	    set allow_btrace_tests 1
>-        }
>-    }
>-    gdb_exit
>-    remote_file build delete $obj
>-
>-    verbose "$me:  returning $allow_btrace_tests" 2
>-    return $allow_btrace_tests
>+    return 1
> }
>
>-# Run a test on the target to see if it supports btrace pt hardware.
>+# Run a test on the target to see if it supports btrace input method.
> # Return 1 if so, 0 if it does not.  Based on 'check_vmx_hw_available'
> # from the GCC testsuite.
>
>-gdb_caching_proc allow_btrace_pt_tests {} {
>+proc check_btrace_method_support {method} {
>     global srcdir subdir gdb_prompt inferior_exited_re
>
>-    set me "allow_btrace_pt_tests"
>-    if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
>-	verbose "$me:  target does not support btrace, returning 1" 2
>-	return 0
>-    }
>+    set me "check_btrace_${method}_support"

Should this be 'check_btrace_method_support ${method}'`?

>
>     # Compile a test program.
>     set src { int main() { return 0; } }
>@@ -4087,31 +4048,62 @@ gdb_caching_proc allow_btrace_pt_tests {} {
> 	return 0
>     }
>     # In case of an unexpected output, we return 2 as a fail value.
>-    set allow_btrace_pt_tests 2
>-    gdb_test_multiple "record btrace pt" "check btrace pt support" {
>-        -re "You can't do that when your target is.*\r\n$gdb_prompt $" {
>-	    set allow_btrace_pt_tests 0
>-        }
>-        -re "Target does not support branch tracing.*\r\n$gdb_prompt $" {
>-	    set allow_btrace_pt_tests 0
>-        }
>-        -re "Could not enable branch tracing.*\r\n$gdb_prompt $" {
>-	    set allow_btrace_pt_tests 0
>-        }
>-        -re "support was disabled at compile time.*\r\n$gdb_prompt $" {
>-	    set allow_btrace_pt_tests 0
>-        }
>-        -re "^record btrace pt\r\n$gdb_prompt $" {
>-	    set allow_btrace_pt_tests 1
>-        }
>+    set supports_method 2
>+    gdb_test_multiple "record btrace ${method}" "check btrace ${method}
>support" {
>+	-re -wrap "You can't do that when your target is.*" {
>+	    set supports_method 0
>+	}
>+	-re -wrap "Target does not support branch tracing.*" {
>+	    set supports_method 0
>+	}
>+	-re -wrap "Could not enable branch tracing.*" {
>+	    set supports_method 0
>+	}
>+	-re -wrap "support was disabled at compile time.*" {
>+	    set supports_method 0
>+	}

We need at least one more fail case:

(gdb) record btrace foo
Undefined record btrace command: "foo".  Try "help record btrace".

>+	-re -wrap "" {
>+	    set supports_method 1
>+	}
>     }
>     gdb_exit
>     remote_file build delete $obj
>
>-    verbose "$me:  returning $allow_btrace_pt_tests" 2
>-    return $allow_btrace_pt_tests
>+    verbose "$me:  returning $supports_method" 2
>+    return $supports_method
> }
>
>+# Run a test on the target to see if it supports btrace 'bts' method.  Return
>+# 1 if so, 0 if it does not.
>+
>+gdb_caching_proc allow_btrace_bts_tests {} {
>+    return [check_btrace_method_support "bts"]
>+}

This 'method' sounds a bit odd.  Without, it would read
'check_btrace_support "bts"'.  We could make it
'btrace_supports "bts"' if we wanted to.

I'm wondering if we even need those allow_btrace_<method>_tests.
Their purpose is to cache the result, but could we declare the underlying
check_btrace_method_support caching?

We'd still want a better name, e.g.

>+proc target_supports_btrace {method} {


>+    if {[string match "pt" "${method}"]} {
>+	return [allow_btrace_pt_tests]
>+    } elseif {[string match "bts" "${method}"]} {
>+	return [allow_btrace_bts_tests]
>+    }
>+
>+    verbose -log "warning: unknown btrace recording method '${method}'"
>+    # Skip test for unknown method name.
>+    return 0
>+}
>+
>+
> # Run a test on the target to see if it supports Aarch64 SVE hardware.
> # Return 1 if so, 0 if it does not.  Note this causes a restart of GDB.
>
>--
>2.34.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
  
Metzger, Markus T April 9, 2024, 9:54 a.m. UTC | #2
>>With this change, gdb.btrace will, instead of selecting the
>>default recording method, run all tests for all available and
>>applicable methods. This increases testing coverage.

Linux does not allow BTS and PT to be used at the same time.

This change, which was requested by Simon some time ago,
does not work with 'make check-parallel' when two gdb.btrace
tests are executed concurrently.

Is there a way to teach make check-parallel to run gdb.btrace
sequentially?

There are a few python tests that use btrace, but they could be
moved to gdb.btrace.

Regards,
Markus.

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
  

Patch

diff --git a/gdb/testsuite/gdb.btrace/buffer-size.exp b/gdb/testsuite/gdb.btrace/buffer-size.exp
index 1008fa8037b..196a62ed133 100644
--- a/gdb/testsuite/gdb.btrace/buffer-size.exp
+++ b/gdb/testsuite/gdb.btrace/buffer-size.exp
@@ -20,23 +20,30 @@ 
 require allow_btrace_tests
 
 standard_testfile record_goto.c
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
-gdb_test_no_output "set record btrace bts buffer-size 1"
-gdb_test_no_output "set record btrace pt buffer-size 1"
-gdb_test "show record btrace bts buffer-size" "The record/replay bts buffer size is 1\."
-gdb_test "show record btrace pt buffer-size" "The record/replay pt buffer size is 1\."
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
 
-gdb_test_no_output "record btrace"
-gdb_test "info record" [multi_line \
-  "Active record target: record-btrace" \
-  "Recording format: \[^\\\r\\\n\]*" \
-  "Buffer size: 4kB\." \
-  "Recorded 0 instructions in 0 functions \\\(0 gaps\\\) for \[^\\\r\\\n\]*" \
-  ]
+    gdb_test_no_output "set record btrace ${method} buffer-size 1"
+    gdb_test "show record btrace ${method} buffer-size" "The record/replay ${method} buffer size is 1\."
+
+    gdb_test_no_output "record btrace ${method}"
+    gdb_test "info record" [multi_line \
+	"Active record target: record-btrace" \
+	"Recording format: \[^\\\r\\\n\]*" \
+	"Buffer size: 4kB\." \
+	"Recorded 0 instructions in 0 functions \\\(0 gaps\\\) for \[^\\\r\\\n\]*" \
+	]
+}
diff --git a/gdb/testsuite/gdb.btrace/data.exp b/gdb/testsuite/gdb.btrace/data.exp
index 30a946c3633..eeb4b23f073 100644
--- a/gdb/testsuite/gdb.btrace/data.exp
+++ b/gdb/testsuite/gdb.btrace/data.exp
@@ -20,41 +20,49 @@ 
 require allow_btrace_tests
 
 standard_testfile
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
-# trace the test code
-gdb_test_no_output "record btrace"
-gdb_test "next" ".*main\.3.*"
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
 
-# reverse step into test
-gdb_test "reverse-step" ".*test\.4.*"
+    # trace the test code
+    gdb_test_no_output "record btrace ${method}"
+    gdb_test "next" ".*main\.3.*"
 
-# we can't read memory while we're replaying
-with_test_prefix "replay" {
-    with_test_prefix "default" {
-	gdb_test "print glob" "unavailable\[^\\\r\\\n\]*"
-	gdb_test "print loc" "unavailable\[^\\\r\\\n\]*"
-    }
+    # reverse step into test
+    gdb_test "reverse-step" ".*test\.4.*"
 
-    # we can read memory if we explicitly allow it.
-    with_test_prefix "read-write" {
-	gdb_test_no_output "set record btrace replay-memory-access read-write"
-	gdb_test "print glob" "1"
-    }
+    # we can't read memory while we're replaying
+    with_test_prefix "replay" {
+	with_test_prefix "default" {
+	    gdb_test "print glob" "unavailable\[^\\\r\\\n\]*"
+	    gdb_test "print loc" "unavailable\[^\\\r\\\n\]*"
+	}
+
+	# we can read memory if we explicitly allow it.
+	with_test_prefix "read-write" {
+	    gdb_test_no_output "set record btrace replay-memory-access read-write"
+	    gdb_test "print glob" "1"
+	}
 
-    # we can't if we don't explicitly allow it.
-    with_test_prefix "read-only" {
-	gdb_test_no_output "set record btrace replay-memory-access read-only"
-	gdb_test "print glob" "unavailable\[^\\\r\\\n\]*"
+	# we can't if we don't explicitly allow it.
+	with_test_prefix "read-only" {
+	    gdb_test_no_output "set record btrace replay-memory-access read-only"
+	    gdb_test "print glob" "unavailable\[^\\\r\\\n\]*"
+	}
     }
-}
 
-# stop replaying and try again
-gdb_test "record goto end" ".*main\.3.*"
-gdb_test "print glob" "1"
+    # stop replaying and try again
+    gdb_test "record goto end" ".*main\.3.*"
+    gdb_test "print glob" "1"
+}
diff --git a/gdb/testsuite/gdb.btrace/delta.exp b/gdb/testsuite/gdb.btrace/delta.exp
index 4e4d06a1812..a6b25b78a54 100644
--- a/gdb/testsuite/gdb.btrace/delta.exp
+++ b/gdb/testsuite/gdb.btrace/delta.exp
@@ -20,64 +20,72 @@ 
 require allow_btrace_tests
 
 standard_testfile record_goto.c
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
-if ![runto_main] {
-    return -1
+proc check_trace {} {
+    gdb_test "info record" [multi_line \
+	"Active record target: record-btrace" \
+	"Recording format: .*" \
+	"Recorded 1 instructions in 1 functions \\\(0 gaps\\\) for .*" \
+	]
 }
 
-# proceed to some sequential code
-gdb_test "next"
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
 
-# start tracing
-gdb_test_no_output "record btrace"
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
 
-# we start without trace
-with_test_prefix "no trace" {
-  gdb_test "info record" [multi_line \
-    "Active record target: record-btrace" \
-    "Recording format: .*" \
-    "Recorded 0 instructions in 0 functions \\\(0 gaps\\\) for .*" \
-    ]
-  gdb_test "record instruction-history" "No trace\."
-  gdb_test "record function-call-history" "No trace\."
-}
+    # proceed to some sequential code
+    gdb_test "next"
 
-# we record each single-step, even if we have not seen a branch, yet.
-gdb_test "stepi"
+    # start tracing
+    gdb_test_no_output "record btrace ${method}"
 
-proc check_trace {} {
-  gdb_test "info record" [multi_line \
-    "Active record target: record-btrace" \
-    "Recording format: .*" \
-    "Recorded 1 instructions in 1 functions \\\(0 gaps\\\) for .*" \
-    ]
-}
+    # we start without trace
+    with_test_prefix "no trace" {
+	gdb_test "info record" [multi_line \
+	    "Active record target: record-btrace" \
+	    "Recording format: .*" \
+	    "Recorded 0 instructions in 0 functions \\\(0 gaps\\\) for .*" \
+	    ]
+	gdb_test "record instruction-history" "No trace\."
+	gdb_test "record function-call-history" "No trace\."
+    }
 
-# make sure we don't extend the trace when we ask twice.
-with_test_prefix "once" {
-  check_trace
-}
+    # we record each single-step, even if we have not seen a branch, yet.
+    gdb_test "stepi"
 
-with_test_prefix "twice" {
-  check_trace
-}
+    # make sure we don't extend the trace when we ask twice.
+    with_test_prefix "once" {
+	check_trace
+    }
 
-# check that we can reverse-stepi that instruction
-with_test_prefix "reverse" {
-    gdb_test "reverse-stepi"
-    gdb_test "info record" [multi_line \
-      "Active record target: record-btrace" \
-      "Recording format: .*" \
-      "Recorded 1 instructions in 1 functions \\\(0 gaps\\\) for .*" \
-      "Replay in progress\.  At instruction 1\." \
-    ]
-}
+    with_test_prefix "twice" {
+	check_trace
+    }
 
-# and back
-with_test_prefix "forward" {
-    gdb_test "stepi"
-    check_trace
+    # check that we can reverse-stepi that instruction
+    with_test_prefix "reverse" {
+	gdb_test "reverse-stepi"
+	gdb_test "info record" [multi_line \
+	    "Active record target: record-btrace" \
+	    "Recording format: .*" \
+	    "Recorded 1 instructions in 1 functions \\\(0 gaps\\\) for .*" \
+	    "Replay in progress\.  At instruction 1\." \
+	    ]
+    }
+
+    # and back
+    with_test_prefix "forward" {
+	gdb_test "stepi"
+	check_trace
+    }
 }
diff --git a/gdb/testsuite/gdb.btrace/dlopen.exp b/gdb/testsuite/gdb.btrace/dlopen.exp
index d0e5a65e346..360a9807a2a 100644
--- a/gdb/testsuite/gdb.btrace/dlopen.exp
+++ b/gdb/testsuite/gdb.btrace/dlopen.exp
@@ -28,23 +28,30 @@  if { [gdb_compile_shlib $srcfile_lib $binfile_lib {}] != "" } {
     return -1
 }
 
-if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
+if { [build_executable "failed to prepare" $testfile $srcfile \
 	  [list additional_flags=-DDSO_NAME=\"$binfile_lib\" libs=-ldl]] } {
     return -1
 }
 
-if ![runto_main] {
-    return -1
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
+
+    # Trace the test function
+    #
+    gdb_test_no_output "record btrace ${method}"
+    gdb_test "next"
+
+    # The memory containing the library call we traced is already gone.
+    # Trace decode used to run into a SEGV after corrupting the cleanup chain.
+    #
+    # The test passes if we don't crash GDB.
+    #
+    gdb_test "info record"
 }
-
-# Trace the test function
-#
-gdb_test_no_output "record btrace"
-gdb_test "next"
-
-# The memory containing the library call we traced is already gone.
-# Trace decode used to run into a SEGV after corrupting the cleanup chain.
-#
-# The test passes if we don't crash GDB.
-#
-gdb_test "info record"
diff --git a/gdb/testsuite/gdb.btrace/enable-new-thread.exp b/gdb/testsuite/gdb.btrace/enable-new-thread.exp
index dbbe6a78516..46b63f061ee 100644
--- a/gdb/testsuite/gdb.btrace/enable-new-thread.exp
+++ b/gdb/testsuite/gdb.btrace/enable-new-thread.exp
@@ -20,21 +20,11 @@ 
 require allow_btrace_tests
 
 standard_testfile
-if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile {debug pthreads}] {
     return -1
 }
 
-# Record the main thread.  Recording will automatically be enabled for the
-# other thread.
-gdb_test "record btrace"
-
-gdb_breakpoint [gdb_get_line_number "bp.1" $srcfile]
-gdb_continue_to_breakpoint "cont to bp.1" ".*/\\* bp\.1 \\*/.*"
-
 proc check_thread_recorded { num } {
     global decimal
 
@@ -49,5 +39,24 @@  proc check_thread_recorded { num } {
     }
 }
 
-check_thread_recorded 1
-check_thread_recorded 2
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+
+    if ![runto_main] {
+	continue
+    }
+
+    # Record the main thread.  Recording will automatically be enabled for the
+    # other thread.
+    gdb_test "record btrace ${method}"
+
+    gdb_breakpoint [gdb_get_line_number "bp.1" $srcfile]
+    gdb_continue_to_breakpoint "cont to bp.1" ".*/\\* bp\.1 \\*/.*"
+
+    check_thread_recorded 1
+    check_thread_recorded 2
+}
diff --git a/gdb/testsuite/gdb.btrace/enable-running.exp b/gdb/testsuite/gdb.btrace/enable-running.exp
index 0d3555ae739..bc8432f15ca 100644
--- a/gdb/testsuite/gdb.btrace/enable-running.exp
+++ b/gdb/testsuite/gdb.btrace/enable-running.exp
@@ -16,32 +16,13 @@ 
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 require allow_btrace_tests
-
 standard_testfile
+
 if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" "$binfile" executable {debug}] != "" } {
     untested "failed to prepare"
     return -1
 }
 
-# We need to enable non-stop mode for the remote case.
-save_vars { GDBFLAGS } {
-    append GDBFLAGS " -ex \"set non-stop on\""
-    clean_restart $testfile
-}
-
-if ![runto_main] {
-    return -1
-}
-
-set bp_1 [gdb_get_line_number "bp.1" $srcfile]
-
-gdb_breakpoint $bp_1
-gdb_continue_to_breakpoint "cont to $bp_1" ".*$bp_1\r\n.*"
-gdb_test "cont&" "Continuing\."
-
-# All threads are running.  Let's start recording.
-gdb_test_no_output "record btrace"
-
 proc check_tracing_enabled { thread } {
     global gdb_prompt
 
@@ -87,10 +68,36 @@  proc check_tracing_enabled { thread } {
     }
 }
 
-# Check that recording was started on each thread.
-foreach thread {1 2 3 4} {
-    check_tracing_enabled $thread
-}
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+
+    # We need to enable non-stop mode for the remote case.
+    save_vars { GDBFLAGS } {
+	append GDBFLAGS " -ex \"set non-stop on\""
+	clean_restart $testfile
+    }
+
+    if ![runto_main] {
+	continue
+    }
+
+    set bp_1 [gdb_get_line_number "bp.1" $srcfile]
 
-# Stop recording while all threads are running.
-gdb_test "record stop" "Process record is stopped \[^\\\r\\\n\]*"
+    gdb_breakpoint $bp_1
+    gdb_continue_to_breakpoint "cont to $bp_1" ".*$bp_1\r\n.*"
+    gdb_test "cont&" "Continuing\."
+
+    # All threads are running.  Let's start recording.
+    gdb_test_no_output "record btrace ${method}"
+
+    # Check that recording was started on each thread.
+    foreach thread {1 2 3 4} {
+	check_tracing_enabled $thread
+    }
+
+    # Stop recording while all threads are running.
+    gdb_test "record stop" "Process record is stopped \[^\\\r\\\n\]*"
+}
diff --git a/gdb/testsuite/gdb.btrace/enable.exp b/gdb/testsuite/gdb.btrace/enable.exp
index 4e39c07472b..8a8d09c8871 100644
--- a/gdb/testsuite/gdb.btrace/enable.exp
+++ b/gdb/testsuite/gdb.btrace/enable.exp
@@ -19,79 +19,90 @@ 
 
 require allow_btrace_tests
 
-# start fresh - without an executable
-gdb_exit
-gdb_start
-
-# record cannot be stopped, if it was never active
-gdb_test "record stop" "No recording 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 recording is currently active\\..*" "record function-call-history without target"
-gdb_test "record instruction-history" "No recording is currently active\\..*" "record instruction-history without target"
-gdb_test "info record" "No recording is currently active\\." "info record without target"
-
 standard_testfile
-if [prepare_for_testing "failed to prepare" $testfile {} {debug}] {
-    return -1
-}
-
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile {} {debug}] {
     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\\.  Use \"record stop\" to stop recording first\\." "record btrace the second time"
-
-# full record cannot be activated as long as btrace is active
-gdb_test "record full" "The process is already being recorded\\.  Use \"record stop\" to stop recording first\\." "record full cannot be enabled"
-
-# no trace recorded yet
-gdb_test "info record" "Active record target: record-btrace\r
-.*\r
-Recorded 0 instructions in 0 functions \\\(0 gaps\\\) for thread 1.*\\." "info record without trace"
-
-# stop btrace record
-gdb_test "record stop" "Process record is stopped and all execution logs are deleted\\."
-gdb_test "record stop" "No recording 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\\.  Use \"record stop\" to stop recording first\\." "record btrace re-enable twice"
-
-# continue to the end and make sure we don't die
-gdb_test "continue" ".*Inferior.*exited.*" "continue to end"
-
-# allow_gdbserver_tests requires GDB not running.
-gdb_exit
-
-# skip the rerun test when using gdbserver
-# otherwise rerun twice, target should be automatically disabled
-load_lib gdbserver-support.exp
-require allow_gdbserver_tests
-clean_restart $testfile
-if ![runto_main] {
-    return -1
-}
-if ![runto_main] {
-    return -1
-}
-
-# make sure record-btrace can be enabled after re-run
-clean_restart $testfile
-if ![runto_main] {
-    return -1
-}
-gdb_test_no_output "record btrace" "enable after restart"
-if ![runto_main] {
-    return -1
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
+
+    # start fresh - without an executable
+    gdb_exit
+    gdb_start
+
+    # record cannot be stopped, if it was never active
+    gdb_test "record stop" "No recording is currently active\\..*" "record stop without target"
+
+    # btrace cannot be enabled without a running inferior
+    gdb_test "record btrace ${method}" "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 recording is currently active\\..*" "record function-call-history without target"
+    gdb_test "record instruction-history" "No recording is currently active\\..*" "record instruction-history without target"
+    gdb_test "info record" "No recording is currently active\\." "info record without target"
+
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
+
+    # enable btrace
+    gdb_test_no_output "record btrace ${method}" "record btrace ${method}"
+    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 ${method}" "The process is already being recorded\\.  Use \"record stop\" to stop recording first\\." "record btrace ${method} the second time"
+
+    # full record cannot be activated as long as btrace is active
+    gdb_test "record full" "The process is already being recorded\\.  Use \"record stop\" to stop recording first\\." "record full cannot be enabled"
+
+    # no trace recorded yet
+    gdb_test "info record" "Active record target: record-btrace\r.*Recorded 0 instructions in 0 functions \\\(0 gaps\\\) for thread 1.*\\." "info record without trace"
+
+    # stop btrace record
+    gdb_test "record stop" "Process record is stopped and all execution logs are deleted\\."
+    gdb_test "record stop" "No recording is currently active\\..*" "record stop the second time"
+
+    # enable btrace again
+    gdb_test_no_output "record btrace ${method}" "record btrace ${method} re-enable"
+    gdb_test "record btrace ${method}" "The process is already being recorded\\.  Use \"record stop\" to stop recording first\\." "record btrace ${method} re-enable twice"
+
+    # continue to the end and make sure we don't die
+    gdb_test "continue" ".*Inferior.*exited.*" "continue to end"
+
+    # allow_gdbserver_tests requires GDB not running.
+    gdb_exit
+
+    # skip the rerun test when using gdbserver
+    # otherwise rerun twice, target should be automatically disabled
+    load_lib gdbserver-support.exp
+    require allow_gdbserver_tests
+    clean_restart $testfile
+    if ![runto_main] {
+	continue
+    }
+    if ![runto_main] {
+	continue
+    }
+
+    # make sure record-btrace can be enabled after re-run
+    clean_restart $testfile
+    if ![runto_main] {
+	continue
+    }
+    gdb_test_no_output "record btrace" "enable after restart"
+    if ![runto_main] {
+	continue
+    }
+    gdb_test_no_output "record btrace" "enable after re-run"
 }
-gdb_test_no_output "record btrace" "enable after re-run"
diff --git a/gdb/testsuite/gdb.btrace/exception.exp b/gdb/testsuite/gdb.btrace/exception.exp
index 61cc6c904b6..a4b6a4fab62 100755
--- a/gdb/testsuite/gdb.btrace/exception.exp
+++ b/gdb/testsuite/gdb.btrace/exception.exp
@@ -22,59 +22,68 @@  require allow_btrace_tests
 # We expect a specific function call history.  This gets messed up with
 # PIE on 32-bit.
 standard_testfile exception.cc
-if [prepare_for_testing "failed to prepare" $testfile $srcfile \
+
+if [build_executable "failed to prepare" $testfile $srcfile \
 	{nopie c++ debug}] {
     return -1
 }
 
-if ![runto_main] {
-    return -1
-}
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
 
-# we want to see the full trace for this test
-gdb_test_no_output "set record function-call-history-size 0"
+    if ![runto_main] {
+	continue
+    }
 
-# set bp
-set bp_1 [gdb_get_line_number "bp.1" $srcfile]
-set bp_2 [gdb_get_line_number "bp.2" $srcfile]
-gdb_breakpoint $bp_1
-gdb_breakpoint $bp_2
+    # we want to see the full trace for this test
+    gdb_test_no_output "set record function-call-history-size 0"
 
-# trace the code between the two breakpoints
-gdb_continue_to_breakpoint "cont to bp.1" ".*$srcfile:$bp_1\r\n.*"
-# increase the BTS buffer size - the trace can be quite big
-gdb_test_no_output "set record btrace bts buffer-size 128000"
-gdb_test_no_output "record btrace"
-gdb_continue_to_breakpoint "cont to bp.2" ".*$srcfile:$bp_2\r\n.*"
+    # set bp
+    set bp_1 [gdb_get_line_number "bp.1" $srcfile]
+    set bp_2 [gdb_get_line_number "bp.2" $srcfile]
+    gdb_breakpoint $bp_1
+    gdb_breakpoint $bp_2
 
-# show the flat branch trace
-send_gdb "record function-call-history 1\n"
-gdb_expect_list "flat" "\r\n$gdb_prompt $" [list \
-  [multi_line \
-    "1\tmain\\(\\)" \
-    "2\ttest\\(\\)" \
-    "3\tfoo\\(\\)" \
-    "4\tbar\\(\\)" \
-    "5\tbad\\(\\)\r" \
-  ] "" \
-  [multi_line \
-    "\[0-9\]*\ttest\\(\\)" \
-    "\[0-9\]*\tmain\\(\\)" \
-  ] "" \
-  ]
+    # trace the code between the two breakpoints
+    gdb_continue_to_breakpoint "cont to bp.1" ".*$srcfile:$bp_1\r\n.*"
+    # increase the BTS buffer size - the trace can be quite big for bts method
+    gdb_test_no_output "set record btrace ${method} buffer-size 128000"
+    gdb_test_no_output "record btrace ${method}"
+    gdb_continue_to_breakpoint "cont to bp.2" ".*$srcfile:$bp_2\r\n.*"
 
-# show the branch trace with calls indented
-send_gdb "record function-call-history /c 1\n"
-gdb_expect_list "indented" "\r\n$gdb_prompt $" [list \
-  [multi_line \
-    "1\tmain\\(\\)" \
-    "2\t  test\\(\\)" \
-    "3\t    foo\\(\\)" \
-    "4\t      bar\\(\\)" \
-    "5\t        bad\\(\\)\r" \
-  ] "" \
-  [multi_line \
-    "\[0-9\]*\t  test\\(\\)" \
-    "\[0-9\]*\tmain\\(\\)" \
-  ] "" \
-  ]
+    # show the flat branch trace
+    send_gdb "record function-call-history 1\n"
+    gdb_expect_list "flat" "\r\n$gdb_prompt $" [list \
+	[multi_line \
+	    "1\tmain\\(\\)" \
+	    "2\ttest\\(\\)" \
+	    "3\tfoo\\(\\)" \
+	    "4\tbar\\(\\)" \
+	    "5\tbad\\(\\)\r" \
+	] "" \
+	[multi_line \
+	    "\[0-9\]*\ttest\\(\\)" \
+	    "\[0-9\]*\tmain\\(\\)" \
+	] "" \
+    ]
+
+    # show the branch trace with calls indented
+    send_gdb "record function-call-history /c 1\n"
+    gdb_expect_list "indented" "\r\n$gdb_prompt $" [list \
+	[multi_line \
+	    "1\tmain\\(\\)" \
+	    "2\t  test\\(\\)" \
+	    "3\t    foo\\(\\)" \
+	    "4\t      bar\\(\\)" \
+	    "5\t        bad\\(\\)\r" \
+	] "" \
+	[multi_line \
+	    "\[0-9\]*\t  test\\(\\)" \
+	    "\[0-9\]*\tmain\\(\\)" \
+	] "" \
+    ]
+}
diff --git a/gdb/testsuite/gdb.btrace/function_call_history.exp b/gdb/testsuite/gdb.btrace/function_call_history.exp
index ce3d1a02ff6..1e332ff8e1c 100644
--- a/gdb/testsuite/gdb.btrace/function_call_history.exp
+++ b/gdb/testsuite/gdb.btrace/function_call_history.exp
@@ -22,22 +22,11 @@  require allow_btrace_tests
 # We expect a specific function call history.  This gets messed up with
 # PIE on 32-bit.
 standard_testfile
-if [prepare_for_testing "failed to prepare" $testfile {} {nopie debug}] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile {} {nopie debug}] {
     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.*"
-
 proc rec_fun_all {} {
   gdb_test "record function-call-history 1" [multi_line \
     "1\tmain" \
@@ -63,194 +52,215 @@  proc rec_fun_all {} {
     "21\tmain"]
 }
 
-# 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"
-with_test_prefix "size unlimited" rec_fun_all
-
-# 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"
-with_test_prefix "size 21" rec_fun_all
-
-# show first 15 entries
-gdb_test_no_output "set record function-call-history-size 15"
-gdb_test "record function-call-history 1" [multi_line \
-  "1\tmain" \
-  "2\tinc" \
-  "3\tmain" \
-  "4\tinc" \
-  "5\tmain" \
-  "6\tinc" \
-  "7\tmain" \
-  "8\tinc" \
-  "9\tmain" \
-  "10\tinc" \
-  "11\tmain" \
-  "12\tinc" \
-  "13\tmain" \
-  "14\tinc" \
-  "15\tmain"] "forward - 1"
-
-# show last 6 entries
-gdb_test "record function-call-history +" [multi_line \
-  "16\tinc" \
-  "17\tmain" \
-  "18\tinc" \
-  "19\tmain" \
-  "20\tinc" \
-  "21\tmain"] "forward - 2"
-
-# moving further should not work
-gdb_test "record function-call-history +" "At the end of the branch trace record\\." "forward - 3"
-
-# make sure we cannot move any further a second time
-gdb_test "record function-call-history +" "At the end of the branch trace record\\." "forward - 4"
-
-# moving back showing the latest 15 function calls
-gdb_test "record function-call-history -" [multi_line \
-  "7\tmain" \
-  "8\tinc" \
-  "9\tmain" \
-  "10\tinc" \
-  "11\tmain" \
-  "12\tinc" \
-  "13\tmain" \
-  "14\tinc" \
-  "15\tmain" \
-  "16\tinc" \
-  "17\tmain" \
-  "18\tinc" \
-  "19\tmain" \
-  "20\tinc" \
-  "21\tmain"] "backward - 1"
-
-# moving further back shows the 6 first function calls
-gdb_test "record function-call-history -" [multi_line \
-  "1\tmain" \
-  "2\tinc" \
-  "3\tmain" \
-  "4\tinc" \
-  "5\tmain" \
-  "6\tinc"] "backward - 2"
-
-# moving further back shouldn't work
-gdb_test "record function-call-history -" "At the start of the branch trace record\\." "backward - 3"
-
-# make sure we cannot move any further back
-gdb_test "record function-call-history -" "At the start of the branch trace record\\." "backward - 4"
-
-# don't mess around with path names
-gdb_test_no_output "set filename-display basename"
-
-# 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 +" [multi_line \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  ] "forward /l - 1"
-
-# moving forward and expect to see the latest 6 entries
-gdb_test "record function-call-history /l +" [multi_line \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,41" \
-  "\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
-  "\[0-9\]*\tmain\tat $srcfile:40,43" \
-  ] "forward /l - 2"
-
-# moving further forward shouldn't work
-gdb_test "record function-call-history /l +" "At the end of the branch trace record\\." "forward /l - 3"
-gdb_test "record function-call-history /l" "At the end of the branch trace record\\." "forward /l - 4"
-
-set expected_range [multi_line \
-  "4\tinc" \
-  "5\tmain" \
-  "6\tinc" \
-  "7\tmain" \
-  "8\tinc" \
-  "9\tmain" \
-  "10\tinc"]
-
-# show functions in instruction range
-gdb_test "record function-call-history 4,10" $expected_range
-gdb_test "record function-call-history 4,+7" $expected_range
-gdb_test "record function-call-history 10,-7" $expected_range
-gdb_test "record function-call-history 4,4" "4\tinc"
-
-# 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 9 times,
-# so we limit the output to only show the latest 11 function calls
-gdb_test_no_output "set record function-call-history-size 11"
-gdb_test "record function-call-history" [multi_line \
-  "21\tmain" \
-  "22\tfib" \
-  "23\tfib" \
-  "24\tfib" \
-  "25\tfib" \
-  "26\tfib" \
-  "27\tfib" \
-  "28\tfib" \
-  "29\tfib" \
-  "30\tfib" \
-  "31\tmain"] "recursive"
-
-# show indented function call history for fib
-gdb_test "record function-call-history /c 21, +11" [multi_line \
-  "21\tmain" \
-  "22\t  fib" \
-  "23\t    fib" \
-  "24\t  fib" \
-  "25\t    fib" \
-  "26\t      fib" \
-  "27\t    fib" \
-  "28\t      fib" \
-  "29\t    fib" \
-  "30\t  fib" \
-  "31\tmain" \
-  ] "indented"
-
-# make sure we can handle incomplete trace with respect to indentation
-if ![runto_main] {
-    return -1
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+
+    if ![runto_main] {
+	continue
+    }
+
+    # start btrace
+    gdb_test_no_output "record btrace ${method}"
+
+    # 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"
+    with_test_prefix "size unlimited" rec_fun_all
+
+    # 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"
+    with_test_prefix "size 21" rec_fun_all
+
+    # show first 15 entries
+    gdb_test_no_output "set record function-call-history-size 15"
+    gdb_test "record function-call-history 1" [multi_line \
+	"1\tmain" \
+	"2\tinc" \
+	"3\tmain" \
+	"4\tinc" \
+	"5\tmain" \
+	"6\tinc" \
+	"7\tmain" \
+	"8\tinc" \
+	"9\tmain" \
+	"10\tinc" \
+	"11\tmain" \
+	"12\tinc" \
+	"13\tmain" \
+	"14\tinc" \
+	"15\tmain"] "forward - 1"
+
+    # show last 6 entries
+    gdb_test "record function-call-history +" [multi_line \
+	"16\tinc" \
+	"17\tmain" \
+	"18\tinc" \
+	"19\tmain" \
+	"20\tinc" \
+	"21\tmain"] "forward - 2"
+
+    # moving further should not work
+    gdb_test "record function-call-history +" "At the end of the branch trace record\\." "forward - 3"
+
+    # make sure we cannot move any further a second time
+    gdb_test "record function-call-history +" "At the end of the branch trace record\\." "forward - 4"
+
+    # moving back showing the latest 15 function calls
+    gdb_test "record function-call-history -" [multi_line \
+	"7\tmain" \
+	"8\tinc" \
+	"9\tmain" \
+	"10\tinc" \
+	"11\tmain" \
+	"12\tinc" \
+	"13\tmain" \
+	"14\tinc" \
+	"15\tmain" \
+	"16\tinc" \
+	"17\tmain" \
+	"18\tinc" \
+	"19\tmain" \
+	"20\tinc" \
+	"21\tmain"] "backward - 1"
+
+    # moving further back shows the 6 first function calls
+    gdb_test "record function-call-history -" [multi_line \
+	"1\tmain" \
+	"2\tinc" \
+	"3\tmain" \
+	"4\tinc" \
+	"5\tmain" \
+	"6\tinc"] "backward - 2"
+
+    # moving further back shouldn't work
+    gdb_test "record function-call-history -" "At the start of the branch trace record\\." "backward - 3"
+
+    # make sure we cannot move any further back
+    gdb_test "record function-call-history -" "At the start of the branch trace record\\." "backward - 4"
+
+    # don't mess around with path names
+    gdb_test_no_output "set filename-display basename"
+
+    # 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 +" [multi_line \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+    ] "forward /l - 1"
+
+    # moving forward and expect to see the latest 6 entries
+    gdb_test "record function-call-history /l +" [multi_line \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,41" \
+	"\[0-9\]*\tinc\tat $srcfile:22,2\[34\]" \
+	"\[0-9\]*\tmain\tat $srcfile:40,43" \
+
+    ] "forward /l - 2"
+
+    # moving further forward shouldn't work
+    gdb_test "record function-call-history /l +" "At the end of the branch trace record\\." "forward /l - 3"
+    gdb_test "record function-call-history /l" "At the end of the branch trace record\\." "forward /l - 4"
+
+    set expected_range [multi_line \
+	"4\tinc" \
+	"5\tmain" \
+	"6\tinc" \
+	"7\tmain" \
+	"8\tinc" \
+	"9\tmain" \
+	"10\tinc"]
+
+    # show functions in instruction range
+    gdb_test "record function-call-history 4,10" $expected_range
+    gdb_test "record function-call-history 4,+7" $expected_range
+    gdb_test "record function-call-history 10,-7" $expected_range
+    gdb_test "record function-call-history 4,4" "4\tinc"
+
+    # 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 9 times,
+    # so we limit the output to only show the latest 11 function calls
+    gdb_test_no_output "set record function-call-history-size 11"
+    gdb_test "record function-call-history" [multi_line \
+	"21\tmain" \
+	"22\tfib" \
+	"23\tfib" \
+	"24\tfib" \
+	"25\tfib" \
+	"26\tfib" \
+	"27\tfib" \
+	"28\tfib" \
+	"29\tfib" \
+	"30\tfib" \
+	"31\tmain"] "recursive"
+
+    # show indented function call history for fib
+    gdb_test "record function-call-history /c 21, +11" [multi_line \
+	"21\tmain" \
+	"22\t  fib" \
+	"23\t    fib" \
+	"24\t  fib" \
+	"25\t    fib" \
+	"26\t      fib" \
+	"27\t    fib" \
+	"28\t      fib" \
+	"29\t    fib" \
+	"30\t  fib" \
+	"31\tmain" \
+    ] "indented"
+
+    # make sure we can handle incomplete trace with respect to indentation
+    if ![runto_main] {
+	return -1
+    }
+    # navigate to the fib in line 24 above
+    gdb_breakpoint fib
+    gdb_continue_to_breakpoint "cont to fib.1"
+    gdb_continue_to_breakpoint "cont to fib.2"
+    gdb_continue_to_breakpoint "cont to fib.3"
+    gdb_continue_to_breakpoint "cont to fib.4"
+
+    # start tracing
+    gdb_test_no_output "record btrace ${method}" "start recording after rerun"
+
+    # continue until line 30 above
+    delete_breakpoints
+    set bp_location [gdb_get_line_number "bp.2" $testfile.c]
+    gdb_breakpoint $bp_location
+    gdb_continue_to_breakpoint "cont to bp.2" ".*$testfile.c:$bp_location\r\n.*"
+
+    # let's look at the trace. we expect to see the tail of the above listing.
+    gdb_test "record function-call-history /c" [multi_line \
+	"1\t      fib" \
+	"2\t    fib" \
+	"3\t      fib" \
+	"4\t    fib" \
+	"5\t  fib" \
+	"6\tmain" \
+    ] "indented tail"
 }
-# navigate to the fib in line 24 above
-gdb_breakpoint fib
-gdb_continue_to_breakpoint "cont to fib.1"
-gdb_continue_to_breakpoint "cont to fib.2"
-gdb_continue_to_breakpoint "cont to fib.3"
-gdb_continue_to_breakpoint "cont to fib.4"
-
-# start tracing
-gdb_test_no_output "record btrace" "start recording after rerun"
-
-# continue until line 30 above
-delete_breakpoints
-set bp_location [gdb_get_line_number "bp.2" $testfile.c]
-gdb_breakpoint $bp_location
-gdb_continue_to_breakpoint "cont to bp.2" ".*$testfile.c:$bp_location\r\n.*"
-
-# let's look at the trace. we expect to see the tail of the above listing.
-gdb_test "record function-call-history /c" [multi_line \
-  "1\t      fib" \
-  "2\t    fib" \
-  "3\t      fib" \
-  "4\t    fib" \
-  "5\t  fib" \
-  "6\tmain" \
-  ] "indented tail"
diff --git a/gdb/testsuite/gdb.btrace/gcore.exp b/gdb/testsuite/gdb.btrace/gcore.exp
index ff607b5643c..5400598d4b7 100644
--- a/gdb/testsuite/gdb.btrace/gcore.exp
+++ b/gdb/testsuite/gdb.btrace/gcore.exp
@@ -20,22 +20,30 @@ 
 require allow_btrace_tests
 
 standard_testfile record_goto.c
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
-# trace the call to the test function
-gdb_test_no_output "record btrace"
-gdb_test "next" ".*main\.3.*"
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
 
-# start replaying
-gdb_test "record goto begin" ".*main\.2.*"
+    # trace the call to the test function
+    gdb_test_no_output "record btrace ${method}"
+    gdb_test "next" ".*main\.3.*"
 
-# generate a core file - this used to assert
-set corefile [host_standard_output_file core]
-gdb_test "generate-core-file $corefile" "Saved corefile $corefile" \
-    "generate-core-file core"
+    # start replaying
+    gdb_test "record goto begin" ".*main\.2.*"
+
+    # generate a core file - this used to assert
+    set corefile [standard_output_file core]
+    gdb_test "generate-core-file $corefile" "Saved corefile $corefile" \
+	"generate-core-file core"
+}
diff --git a/gdb/testsuite/gdb.btrace/instruction_history.exp b/gdb/testsuite/gdb.btrace/instruction_history.exp
index d3ff313c570..4b783a1c0aa 100644
--- a/gdb/testsuite/gdb.btrace/instruction_history.exp
+++ b/gdb/testsuite/gdb.btrace/instruction_history.exp
@@ -20,88 +20,10 @@ 
 require allow_btrace_tests
 
 standard_testfile .c .S
-if [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" {debug}] {
+if [build_executable "failed to prepare" $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 traced {}
-set testname "determine number of recorded instructions"
-gdb_test_multiple "info record" $testname {
-    -re "Active record target: record-btrace\r\n.*\r\nRecorded \(\[0-9\]*\) instructions in \(\[0-9\]*\) functions \\\(0 gaps\\\) for thread 1 .*\\.\r\n$gdb_prompt $" {
-        set traced $expect_out(1,string)
-        pass $testname
-    }
-}
-
-# we have exactly 11 instructions here
-set message "exactly 11 instructions"
-if { $traced != 11 } {
-    fail $message
-} else {
-    pass $message
-}
-
-# test that we see the expected instructions
-gdb_test "record instruction-history 3,7" [multi_line \
-  "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\]+>" \
-  ]
-
-gdb_test "record instruction-history /f 3,+5" [multi_line \
-  "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\]+>" \
-  ]
-
-gdb_test "record instruction-history /p 7,-5" [multi_line \
-  "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\]+>" \
-  ]
-
-gdb_test "record instruction-history /pf 3,7" [multi_line \
-  "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\]+>" \
-  ]
-
-gdb_test "record instruction-history 3,3" "3\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>"
-
-# 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
@@ -118,83 +40,168 @@  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 1" $message]
-if { $traced != $lines } {
-    fail $message
-} else {
-    pass $message
-}
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
 
-gdb_test_no_output "set record instruction-history-size $traced"
-set message "record instruction-history - traced"
-set lines [test_lines_length "record instruction-history 1" $message]
-if { $traced != $lines } {
-    fail $message
-} else {
-    pass $message
-}
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
+    # 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 ${method}"
+
+    # 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 traced {}
+    set testname "determine number of recorded instructions"
+    gdb_test_multiple "info record" $testname {
+	-re "Active record target: record-btrace\r\n.*\r\nRecorded \(\[0-9\]*\) instructions in \(\[0-9\]*\) functions \\\(0 gaps\\\) for thread 1 .*\\.\r\n$gdb_prompt $" {
+	    set traced $expect_out(1,string)
+	    pass $testname
+	}
+    }
 
-# test that the iterator works
-set history_size 4
-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 1" $message]
-if { $lines != $history_size } {
-    fail $message
-} else {
-    pass $message
-}
+    # we have exactly 11 instructions here
+    set message "exactly 11 instructions"
+    if { $traced != 11 } {
+	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
-}
+    # test that we see the expected instructions
+    gdb_test "record instruction-history 3,7" [multi_line \
+	"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\]+>" \
+	]
+
+    gdb_test "record instruction-history /f 3,+5" [multi_line \
+	"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\]+>" \
+	]
+
+    gdb_test "record instruction-history /p 7,-5" [multi_line \
+	"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\]+>" \
+	]
+
+    gdb_test "record instruction-history /pf 3,7" [multi_line \
+	"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\]+>" \
+	]
+
+    gdb_test "record instruction-history 3,3" "3\t   0x\[0-9a-f\]+ <loop\\+\[0-9\]+>:\tje     0x\[0-9a-f\]+ <loop\\+\[0-9\]+>"
+
+    # 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.
+
+    # 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 1" $message]
+    if { $traced != $lines } {
+	fail $message
+    } else {
+	pass $message
+    }
 
-set message "browse history forward last"
-set lines [test_lines_length "record instruction-history +" $message]
-if { $lines != 3 } {
-    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 1" $message]
+    if { $traced != $lines } {
+	fail $message
+    } else {
+	pass $message
+    }
 
-gdb_test "record instruction-history" "At the end of the branch trace record\\." "browse history forward beyond 1"
+    # test that the iterator works
+    set history_size 4
+    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 1" $message]
+    if { $lines != $history_size } {
+	fail $message
+    } else {
+	pass $message
+    }
 
-# 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 forward middle"
+    set lines [test_lines_length "record instruction-history +" $message]
+    if { $lines != $history_size } {
+	fail $message
+    } else {
+	pass $message
+    }
 
-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 forward last"
+    set lines [test_lines_length "record instruction-history +" $message]
+    if { $lines != 3 } {
+	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
-}
+    gdb_test "record instruction-history" "At the end of the branch trace record\\." "browse history forward beyond 1"
 
-set message "browse history backward first"
-set lines [test_lines_length "record instruction-history -" $message]
-if { $lines != 3 } {
-    fail $message
-} else {
-    pass $message
-}
+    # 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 != 3 } {
+	fail $message
+    } else {
+	pass $message
+    }
 
-gdb_test "record instruction-history -" "At the start of the branch trace record\\." "browse history backward beyond 1"
+    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"
+    # 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/multi-inferior.exp b/gdb/testsuite/gdb.btrace/multi-inferior.exp
index 6996b182e65..06ca93a9686 100644
--- a/gdb/testsuite/gdb.btrace/multi-inferior.exp
+++ b/gdb/testsuite/gdb.btrace/multi-inferior.exp
@@ -27,46 +27,54 @@  require allow_btrace_tests
 require !use_gdb_stub
 
 standard_testfile
-if [prepare_for_testing "failed to prepare" $testfile {} {debug}] {
+if [build_executable "failed to prepare" $testfile {} {debug}] {
     return -1
 }
 
 set host_binfile [gdb_remote_download host $binfile]
 
-with_test_prefix "inferior 1" {
-    if ![runto_main] {
-	return -1
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
     }
-}
-
-with_test_prefix "inferior 2" {
-    gdb_test "add-inferior -exec $host_binfile" "Added inferior 2.*" \
-	"add second inferior"
-    gdb_test "inferior 2" "Switching to inferior 2.*"
+    clean_restart "${testfile}"
 
-    if ![runto_main] {
-	return -1
+    with_test_prefix "inferior 1" {
+	if ![runto_main] {
+	    continue
+	}
     }
 
-    gdb_test_no_output "record btrace" "record btrace"
-}
+    with_test_prefix "inferior 2" {
+	gdb_test "add-inferior -exec $host_binfile" "Added inferior 2.*" \
+	    "add second inferior"
+	gdb_test "inferior 2" "Switching to inferior 2.*"
 
-with_test_prefix "inferior 1" {
-    gdb_test "inferior 1" "Switching to inferior 1.*"
+	if ![runto_main] {
+	    continue
+	}
 
-    gdb_test "info record" "No recording is currently active\\."
-    gdb_test_no_output "record btrace" "record btrace"
-}
+	gdb_test_no_output "record btrace ${method}" "record btrace ${method}"
+    }
 
-with_test_prefix "inferior 3" {
-    gdb_test "add-inferior -exec ${host_binfile}" "Added inferior 3.*" \
-	"add third inferior"
-    gdb_test "inferior 3" "Switching to inferior 3.*"
+    with_test_prefix "inferior 1" {
+	gdb_test "inferior 1" "Switching to inferior 1.*"
 
-    if ![runto_main] {
-	return -1
+	gdb_test "info record" "No recording is currently active\\."
+	gdb_test_no_output "record btrace ${method}" "record btrace ${method}"
     }
 
-    gdb_test "info record" "No recording is currently active\\."
-    gdb_test_no_output "record btrace" "record btrace"
+    with_test_prefix "inferior 3" {
+	gdb_test "add-inferior -exec ${host_binfile}" "Added inferior 3.*" \
+	    "add third inferior"
+	gdb_test "inferior 3" "Switching to inferior 3.*"
+
+	if ![runto_main] {
+	    continue
+	}
+
+	gdb_test "info record" "No recording is currently active\\."
+	gdb_test_no_output "record btrace ${method}" "record btrace ${method}"
+    }
 }
diff --git a/gdb/testsuite/gdb.btrace/multi-thread-step.exp b/gdb/testsuite/gdb.btrace/multi-thread-step.exp
index 154db9ae515..6ab5969f457 100644
--- a/gdb/testsuite/gdb.btrace/multi-thread-step.exp
+++ b/gdb/testsuite/gdb.btrace/multi-thread-step.exp
@@ -24,16 +24,6 @@  if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" "$binfile" executable {debu
     untested "failed to prepare"
     return -1
 }
-clean_restart $testfile
-
-if ![runto_main] {
-    return -1
-}
-
-# set up breakpoints
-set bp_1 [gdb_get_line_number "bp.1" $srcfile]
-set bp_2 [gdb_get_line_number "bp.2" $srcfile]
-set bp_3 [gdb_get_line_number "bp.3" $srcfile]
 
 proc gdb_cont_to_line { line } {
     gdb_breakpoint $line
@@ -61,14 +51,6 @@  proc check_not_replaying { thread } {
     }
 }
 
-# trace the code between the two breakpoints
-delete_breakpoints
-gdb_cont_to_line $srcfile:$bp_1
-# make sure GDB knows about the new thread
-gdb_test "info threads" ".*"
-gdb_test_no_output "record btrace"
-gdb_cont_to_line $srcfile:$bp_2
-
 proc test_navigate {} {
     with_test_prefix "navigate" {
         gdb_test "thread 1" ".*"
@@ -168,46 +150,70 @@  proc test_goto_end {} {
     }
 }
 
-foreach schedlock { "replay" "on" "step" } {
-    with_test_prefix "schedlock-$schedlock" {
-        gdb_test_no_output "set scheduler-locking $schedlock"
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
+
+    # set up breakpoints
+    set bp_1 [gdb_get_line_number "bp.1" $srcfile]
+    set bp_2 [gdb_get_line_number "bp.2" $srcfile]
+    set bp_3 [gdb_get_line_number "bp.3" $srcfile]
 
-        test_navigate
-        test_step
-        if { $schedlock == "step" } {
-            test_cont_all
-        } else {
-            test_cont
-        }
-        test_rstep
-        test_goto_end
+    # trace the code between the two breakpoints
+    delete_breakpoints
+    gdb_cont_to_line $srcfile:$bp_1
+    # make sure GDB knows about the new thread
+    gdb_test "info threads" ".*"
+    gdb_test_no_output "record btrace ${method}"
+    gdb_cont_to_line $srcfile:$bp_2
+
+    foreach schedlock { "replay" "on" "step" } {
+	with_test_prefix "schedlock-$schedlock" {
+	    gdb_test_no_output "set scheduler-locking $schedlock"
+
+	    test_navigate
+	    test_step
+	    if { $schedlock == "step" } {
+		test_cont_all
+	    } else {
+		test_cont
+	    }
+	    test_rstep
+	    test_goto_end
+	}
     }
-}
 
-# schedlock-off is difficult to test since we can't really say where the other
-# thread will be when the resumed thread stops.
+    # schedlock-off is difficult to test since we can't really say where the other
+    # thread will be when the resumed thread stops.
 
-# navigate back into the history for thread 1 and continue thread 2
-with_test_prefix "cont-to-end" {
-    # this test only works for scheduler-locking replay
-    gdb_test_no_output "set scheduler-locking replay"
+    # navigate back into the history for thread 1 and continue thread 2
+    with_test_prefix "cont-to-end" {
+	# this test only works for scheduler-locking replay
+	gdb_test_no_output "set scheduler-locking replay"
 
-    gdb_test "thread 1" ".*"
-    with_test_prefix "thread 1" {
-        gdb_test "record goto begin" ".*"
+	gdb_test "thread 1" ".*"
+	with_test_prefix "thread 1" {
+	    gdb_test "record goto begin" ".*"
 
-        check_replay_insn 1 1
-    }
-    gdb_test "thread 2" ".*"
-    with_test_prefix "thread 2" {
-        gdb_test "record goto end" ".*"
+	    check_replay_insn 1 1
+	}
+	gdb_test "thread 2" ".*"
+	with_test_prefix "thread 2" {
+	    gdb_test "record goto end" ".*"
 
-        check_not_replaying 2
+	    check_not_replaying 2
 
-        # if we reach the breakpoint, thread 2 terminated...
-        gdb_cont_to_line $srcfile:$bp_3
+	    # if we reach the breakpoint, thread 2 terminated...
+	    gdb_cont_to_line $srcfile:$bp_3
 
-        # and thread 1 stopped replaying
-        check_not_replaying 1
+	    # and thread 1 stopped replaying
+	    check_not_replaying 1
+	}
     }
 }
diff --git a/gdb/testsuite/gdb.btrace/nohist.exp b/gdb/testsuite/gdb.btrace/nohist.exp
index d71909181c4..3a7dd264c53 100644
--- a/gdb/testsuite/gdb.btrace/nohist.exp
+++ b/gdb/testsuite/gdb.btrace/nohist.exp
@@ -20,11 +20,8 @@ 
 require allow_btrace_tests
 
 standard_testfile record_goto.c
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
@@ -36,14 +33,25 @@  proc check_not_replaying {} {
     ]
 }
 
-gdb_test_no_output "record btrace"
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
 
-with_test_prefix "forward" {
-    check_not_replaying
-}
+    gdb_test_no_output "record btrace ${method}"
+
+    with_test_prefix "forward" {
+	check_not_replaying
+    }
 
-gdb_test "reverse-continue" "No more reverse-execution history\.\r\n.*"
+    gdb_test "reverse-continue" "No more reverse-execution history\.\r\n.*"
 
-with_test_prefix "backward" {
-    check_not_replaying
+    with_test_prefix "backward" {
+	check_not_replaying
+    }
 }
diff --git a/gdb/testsuite/gdb.btrace/non-stop.exp b/gdb/testsuite/gdb.btrace/non-stop.exp
index 62c940e4cd6..ed05a2cf480 100644
--- a/gdb/testsuite/gdb.btrace/non-stop.exp
+++ b/gdb/testsuite/gdb.btrace/non-stop.exp
@@ -23,29 +23,6 @@  if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" "$binfile" executable {debu
     return -1
 }
 
-save_vars { GDBFLAGS } {
-    append GDBFLAGS " -ex \"set non-stop on\""
-    clean_restart $testfile
-}
-
-if ![runto_main] {
-    return -1
-}
-
-# set up breakpoints
-set bp_1 [gdb_get_line_number "bp.1" $srcfile]
-set bp_2 [gdb_get_line_number "bp.2" $srcfile]
-set bp_3 [gdb_get_line_number "bp.3" $srcfile]
-
-gdb_breakpoint $bp_1
-gdb_breakpoint $bp_2
-
-# get the line number containing most of the trace
-set loop [gdb_get_line_number "loop" $srcfile]
-
-# a stop on the above line as reported by GDB
-set loop_line "$loop\[^\\\r\\\n\]*/\\\* loop \\\*/"
-
 # make sure $line matches the full expected output per thread.
 # and let's hope that GDB never mixes the output from different threads.
 proc gdb_cont_to { threads cmd line nthreads } {
@@ -89,165 +66,195 @@  proc gdb_cont_to_no_history { threads cmd nthreads } {
         $nthreads
 }
 
-# trace the code between the two breakpoints
-with_test_prefix "prepare" {
-    gdb_cont_to_bp_line "$srcfile:$bp_1" all 2
-}
-with_test_prefix "record" {
-    gdb_test_no_output "record btrace"
-    gdb_cont_to_bp_line "$srcfile:$bp_2" all 2
-}
-
-# we don't need those breakpoints any longer.
-# they will only disturb our stepping.
-delete_breakpoints
-
-# show the threads - this is useful for debugging fails
-gdb_test "thread apply all info rec" ".*"
-gdb_test "info threads" ".*"
-
-with_test_prefix "navigate" {
-    gdb_test "thread apply 1 record goto 3" "$loop_line"
-    gdb_test "thread apply 2 record goto 4" "$loop_line"
-    gdb_test "thread apply 1 info record" \
-        ".*Replay in progress\.  At instruction 3\." "thread 1 at insn 3"
-    gdb_test "thread apply 2 info record" \
-        ".*Replay in progress\.  At instruction 4\." "thread 2 at insn 4"
-
-    gdb_test "thread apply all record goto 5" "$loop_line"
-    gdb_test "thread apply 1 info record" \
-        ".*Replay in progress\.  At instruction 5\." "thread 1 at insn 5"
-    gdb_test "thread apply 2 info record" \
-        ".*Replay in progress\.  At instruction 5\." "thread 2 at insn 5"
-}
-
-with_test_prefix "step" {
-    with_test_prefix "thread 1" {
-        gdb_test "thread apply 1 stepi 2" "$loop_line"
-        gdb_test "thread apply 1 info record" \
-            ".*Replay in progress\.  At instruction 7\."
-        gdb_test "thread apply 2 info record" \
-            ".*Replay in progress\.  At instruction 5\."
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
     }
 
-    with_test_prefix "thread 2" {
-        gdb_test "thread apply 2 stepi 3" "$loop_line"
-        gdb_test "thread apply 1 info record" \
-            ".*Replay in progress\.  At instruction 7\."
-        gdb_test "thread apply 2 info record" \
-            ".*Replay in progress\.  At instruction 8\."
+    save_vars { GDBFLAGS } {
+	append GDBFLAGS " -ex \"set non-stop on\""
+	clean_restart $testfile
     }
 
-    with_test_prefix "all" {
-        gdb_cont_to all "stepi 4" "$loop_line" 2
-        gdb_test "thread apply 1 info record" \
-            ".*Replay in progress\.  At instruction 11\."
-        gdb_test "thread apply 2 info record" \
-            ".*Replay in progress\.  At instruction 12\."
+    if ![runto_main] {
+	continue
     }
-}
 
-with_test_prefix "reverse-step" {
-    with_test_prefix "thread 1" {
-        gdb_test "thread apply 1 reverse-stepi 2" "$loop_line"
-        gdb_test "thread apply 1 info record" \
-            ".*Replay in progress\.  At instruction 9\."
-        gdb_test "thread apply 2 info record" \
-            ".*Replay in progress\.  At instruction 12\."
-    }
+    # set up breakpoints
+    set bp_1 [gdb_get_line_number "bp.1" $srcfile]
+    set bp_2 [gdb_get_line_number "bp.2" $srcfile]
+    set bp_3 [gdb_get_line_number "bp.3" $srcfile]
+
+    gdb_breakpoint $bp_1
+    gdb_breakpoint $bp_2
 
-    with_test_prefix "thread 2" {
-        gdb_test "thread apply 2 reverse-stepi 3" "$loop_line"
-        gdb_test "thread apply 1 info record" \
-            ".*Replay in progress\.  At instruction 9\."
-        gdb_test "thread apply 2 info record" \
-            ".*Replay in progress\.  At instruction 9\."
+    # get the line number containing most of the trace
+    set loop [gdb_get_line_number "loop" $srcfile]
+
+    # a stop on the above line as reported by GDB
+    set loop_line "$loop\[^\\\r\\\n\]*/\\\* loop \\\*/"
+
+    # trace the code between the two breakpoints
+    with_test_prefix "prepare" {
+	gdb_cont_to_bp_line "$srcfile:$bp_1" all 2
+    }
+    with_test_prefix "record" {
+	gdb_test_no_output "record btrace ${method}"
+	gdb_cont_to_bp_line "$srcfile:$bp_2" all 2
     }
 
-    with_test_prefix "all" {
-        gdb_cont_to all "reverse-stepi 4" "$loop_line" 2
-        gdb_test "thread apply 1 info record" \
-            ".*Replay in progress\.  At instruction 5\."
-        gdb_test "thread apply 2 info record" \
-            ".*Replay in progress\.  At instruction 5\."
+    # we don't need those breakpoints any longer.
+    # they will only disturb our stepping.
+    delete_breakpoints
+
+    # show the threads - this is useful for debugging fails
+    gdb_test "thread apply all info rec" ".*"
+    gdb_test "info threads" ".*"
+
+    with_test_prefix "navigate" {
+	gdb_test "thread apply 1 record goto 3" "$loop_line"
+	gdb_test "thread apply 2 record goto 4" "$loop_line"
+	gdb_test "thread apply 1 info record" \
+	    ".*Replay in progress\.  At instruction 3\." "thread 1 at insn 3"
+	gdb_test "thread apply 2 info record" \
+	    ".*Replay in progress\.  At instruction 4\." "thread 2 at insn 4"
+
+	gdb_test "thread apply all record goto 5" "$loop_line"
+	gdb_test "thread apply 1 info record" \
+	    ".*Replay in progress\.  At instruction 5\." "thread 1 at insn 5"
+	gdb_test "thread apply 2 info record" \
+	    ".*Replay in progress\.  At instruction 5\." "thread 2 at insn 5"
     }
-}
 
-with_test_prefix "continue" {
-    with_test_prefix "thread 1" {
-	with_test_prefix "continue" {
-	    gdb_cont_to_no_history 1 "continue" 1
+    with_test_prefix "step" {
+	with_test_prefix "thread 1" {
+	    gdb_test "thread apply 1 stepi 2" "$loop_line"
 	    gdb_test "thread apply 1 info record" \
-		".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
+		".*Replay in progress\.  At instruction 7\."
 	    gdb_test "thread apply 2 info record" \
 		".*Replay in progress\.  At instruction 5\."
 	}
-	with_test_prefix "reverse-continue" {
-	    gdb_cont_to_no_history 1 "reverse-continue" 1
+
+	with_test_prefix "thread 2" {
+	    gdb_test "thread apply 2 stepi 3" "$loop_line"
 	    gdb_test "thread apply 1 info record" \
-		".*Replay in progress\.  At instruction 1\."
+		".*Replay in progress\.  At instruction 7\."
 	    gdb_test "thread apply 2 info record" \
-		".*Replay in progress\.  At instruction 5\."
+		".*Replay in progress\.  At instruction 8\."
+	}
+
+	with_test_prefix "all" {
+	    gdb_cont_to all "stepi 4" "$loop_line" 2
+	    gdb_test "thread apply 1 info record" \
+		".*Replay in progress\.  At instruction 11\."
+	    gdb_test "thread apply 2 info record" \
+		".*Replay in progress\.  At instruction 12\."
 	}
     }
 
-    with_test_prefix "thread 2" {
-	with_test_prefix "continue" {
-	    gdb_cont_to_no_history 2 "continue" 1
+    with_test_prefix "reverse-step" {
+	with_test_prefix "thread 1" {
+	    gdb_test "thread apply 1 reverse-stepi 2" "$loop_line"
 	    gdb_test "thread apply 1 info record" \
-		".*Replay in progress\.  At instruction 1\."
+		".*Replay in progress\.  At instruction 9\."
 	    gdb_test "thread apply 2 info record" \
-		".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
+		".*Replay in progress\.  At instruction 12\."
+	}
+
+	with_test_prefix "thread 2" {
+	    gdb_test "thread apply 2 reverse-stepi 3" "$loop_line"
+	    gdb_test "thread apply 1 info record" \
+		".*Replay in progress\.  At instruction 9\."
+	    gdb_test "thread apply 2 info record" \
+		".*Replay in progress\.  At instruction 9\."
 	}
-	with_test_prefix "reverse-continue" {
-	    gdb_cont_to_no_history 2 "reverse-continue" 1
+
+	with_test_prefix "all" {
+	    gdb_cont_to all "reverse-stepi 4" "$loop_line" 2
 	    gdb_test "thread apply 1 info record" \
-		".*Replay in progress\.  At instruction 1\."
+		".*Replay in progress\.  At instruction 5\."
 	    gdb_test "thread apply 2 info record" \
-		".*Replay in progress\.  At instruction 1\."
+		".*Replay in progress\.  At instruction 5\."
 	}
     }
-}
 
-# a thread may only resume if no thread is still replaying
-with_test_prefix "no progress" {
-    with_test_prefix "thread 1" {
-        gdb_test "thread apply 1 record goto end" ".*"
-        gdb_test "thread apply 2 record goto begin" ".*"
-
-        gdb_cont_to_no_history 1 "continue" 1
-        gdb_cont_to_no_history 1 "step" 1
-        gdb_test "thread apply 1 info record" \
-            ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
-        gdb_test "thread apply 2 info record" \
-            ".*Replay in progress\.  At instruction 1\."
+    with_test_prefix "continue" {
+	with_test_prefix "thread 1" {
+	    with_test_prefix "continue" {
+		gdb_cont_to_no_history 1 "continue" 1
+		gdb_test "thread apply 1 info record" \
+		    ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
+		gdb_test "thread apply 2 info record" \
+		    ".*Replay in progress\.  At instruction 5\."
+	    }
+	    with_test_prefix "reverse-continue" {
+		gdb_cont_to_no_history 1 "reverse-continue" 1
+		gdb_test "thread apply 1 info record" \
+		    ".*Replay in progress\.  At instruction 1\."
+		gdb_test "thread apply 2 info record" \
+		    ".*Replay in progress\.  At instruction 5\."
+	    }
+	}
+
+	with_test_prefix "thread 2" {
+	    with_test_prefix "continue" {
+		gdb_cont_to_no_history 2 "continue" 1
+		gdb_test "thread apply 1 info record" \
+		    ".*Replay in progress\.  At instruction 1\."
+		gdb_test "thread apply 2 info record" \
+		    ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
+	    }
+	    with_test_prefix "reverse-continue" {
+		gdb_cont_to_no_history 2 "reverse-continue" 1
+		gdb_test "thread apply 1 info record" \
+		    ".*Replay in progress\.  At instruction 1\."
+		gdb_test "thread apply 2 info record" \
+		    ".*Replay in progress\.  At instruction 1\."
+	    }
+	}
     }
 
-    with_test_prefix "thread 2" {
-        gdb_test "thread apply 1 record goto begin" ".*"
-        gdb_test "thread apply 2 record goto end" ".*"
+    # a thread may only resume if no thread is still replaying
+    with_test_prefix "no progress" {
+	with_test_prefix "thread 1" {
+	    gdb_test "thread apply 1 record goto end" ".*"
+	    gdb_test "thread apply 2 record goto begin" ".*"
 
-        gdb_cont_to_no_history 2 "continue" 1
-        gdb_cont_to_no_history 2 "step" 1
-        gdb_test "thread apply 1 info record" \
-            ".*Replay in progress\.  At instruction 1\."
-        gdb_test "thread apply 2 info record" \
-            ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
-    }
+	    gdb_cont_to_no_history 1 "continue" 1
+	    gdb_cont_to_no_history 1 "step" 1
+	    gdb_test "thread apply 1 info record" \
+		".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
+	    gdb_test "thread apply 2 info record" \
+		".*Replay in progress\.  At instruction 1\."
+	}
+
+	with_test_prefix "thread 2" {
+	    gdb_test "thread apply 1 record goto begin" ".*"
+	    gdb_test "thread apply 2 record goto end" ".*"
 
-    with_test_prefix "all" {
-        gdb_test "thread apply all record goto begin" ".*"
+	    gdb_cont_to_no_history 2 "continue" 1
+	    gdb_cont_to_no_history 2 "step" 1
+	    gdb_test "thread apply 1 info record" \
+		".*Replay in progress\.  At instruction 1\."
+	    gdb_test "thread apply 2 info record" \
+		".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
+	}
 
-        gdb_cont_to_no_history all "continue" 2
-        gdb_test "thread apply 1 info record" \
-            ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
-        gdb_test "thread apply 2 info record" \
-            ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
+	with_test_prefix "all" {
+	    gdb_test "thread apply all record goto begin" ".*"
+
+	    gdb_cont_to_no_history all "continue" 2
+	    gdb_test "thread apply 1 info record" \
+		".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
+	    gdb_test "thread apply 2 info record" \
+		".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*"
+	}
     }
-}
 
-# now that both threads stopped replaying we may resume recording
-with_test_prefix "cont to end" {
-    gdb_breakpoint $bp_3
-    gdb_cont_to_bp_line "$srcfile:$bp_3" all 1
+    # now that both threads stopped replaying we may resume recording
+    with_test_prefix "cont to end" {
+	gdb_breakpoint $bp_3
+	gdb_cont_to_bp_line "$srcfile:$bp_3" all 1
+    }
 }
diff --git a/gdb/testsuite/gdb.btrace/reconnect.exp b/gdb/testsuite/gdb.btrace/reconnect.exp
index 41f702a38b3..349d7f7cda9 100644
--- a/gdb/testsuite/gdb.btrace/reconnect.exp
+++ b/gdb/testsuite/gdb.btrace/reconnect.exp
@@ -23,59 +23,69 @@  require allow_btrace_tests
 require allow_gdbserver_tests
 
 standard_testfile
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
 set target_binfile [gdb_remote_download target $binfile]
 
-# Make sure we're disconnected and no recording is active, in case
-# we're testing with an extended-remote board, therefore already
-# connected.
-with_test_prefix "preparation" {
-  gdb_test "record stop" ".*"
-  gdb_test "disconnect" ".*"
-}
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
 
-# Start fresh gdbserver.
-set gdbserver_reconnect_p 1
-set res [gdbserver_start "" $target_binfile]
-set gdbserver_protocol [lindex $res 0]
-set gdbserver_gdbport [lindex $res 1]
-gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
+    clean_restart "${testfile}"
 
-# Create a record, check, reconnect
-with_test_prefix "first" {
-  gdb_test_no_output "record btrace" "record btrace enable"
-  gdb_test "stepi 19" ".*"
+    # Make sure we're disconnected and no recording is active, in case
+    # we're testing with an extended-remote board, therefore already
+    # connected.
+    with_test_prefix "preparation" {
+	gdb_test "record stop" ".*"
+	gdb_test "disconnect" ".*"
+    }
 
-  gdb_test "info record" [multi_line \
-    "Active record target: .*" \
-    "Recorded 19 instructions in .+ functions \\(. gaps\\) for thread 1 \\(Thread .*\\)."
-  ]
+    # Start fresh gdbserver.
+    set gdbserver_reconnect_p 1
+    set res [gdbserver_start "" $target_binfile]
+    set gdbserver_protocol [lindex $res 0]
+    set gdbserver_gdbport [lindex $res 1]
+    gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
 
-  gdb_test "disconnect" "Ending remote debugging."
-  gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
-}
+    # Create a record, check, reconnect
+    with_test_prefix "first" {
+	gdb_test_no_output "record btrace ${method}" "record btrace ${method} enable"
+	gdb_test "stepi 19" ".*"
 
-# Test if we can access the recorded data from first connect.
-# Note: BTS loses the first function call entry with its associated
-# instructions for technical reasons.  This is why we test for
-# "a number between 10 and 19", so we catch at least the case where
-# there are 0 instructions in the record.
-with_test_prefix "second" {
-  gdb_test "info record" [multi_line \
-    "Active record target: .*" \
-    "Recorded 1. instructions in .+ functions \\(. gaps\\) for thread 1 \\(Thread .*\\)."
-  ]
+	gdb_test "info record" [multi_line \
+	    "Active record target: .*" \
+	    "Recorded 19 instructions in .+ functions \\(. gaps\\) for thread 1 \\(Thread .*\\)."
+	    ]
 
-  gdb_test "record stop" "Process record is stopped and all execution logs are deleted."
+	gdb_test "disconnect" "Ending remote debugging."
+	gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
+    }
 
-  gdb_test "disconnect" "Ending remote debugging."
-  gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
-}
+    # Test if we can access the recorded data from first connect.
+    # Note: BTS loses the first function call entry with its associated
+    # instructions for technical reasons.  This is why we test for
+    # "a number between 10 and 19", so we catch at least the case where
+    # there are 0 instructions in the record.
+    with_test_prefix "second" {
+	gdb_test "info record" [multi_line \
+	    "Active record target: .*" \
+	    "Recorded 1. instructions in .+ functions \\(. gaps\\) for thread 1 \\(Thread .*\\)."
+	    ]
+
+	gdb_test "record stop" "Process record is stopped and all execution logs are deleted."
+
+	gdb_test "disconnect" "Ending remote debugging."
+	gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
+    }
 
-# Test that recording is now off.
-with_test_prefix "third" {
-  gdb_test "info record" "No recording is currently active."
+    # Test that recording is now off.
+    with_test_prefix "third" {
+	gdb_test "info record" "No recording is currently active."
+    }
+    gdb_test "disconnect" ".*"
 }
diff --git a/gdb/testsuite/gdb.btrace/record_goto-step.exp b/gdb/testsuite/gdb.btrace/record_goto-step.exp
index e7adc62eedd..f4f89c7b1c7 100644
--- a/gdb/testsuite/gdb.btrace/record_goto-step.exp
+++ b/gdb/testsuite/gdb.btrace/record_goto-step.exp
@@ -20,25 +20,34 @@ 
 require allow_btrace_tests
 
 standard_testfile record_goto.c
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
-set bp [gdb_get_line_number "fun4.3" $srcfile]
-gdb_breakpoint $srcfile:$bp
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+
+    if ![runto_main] {
+	continue
+    }
 
-# record the execution until we hit a breakpoint
-gdb_test_no_output "record btrace"
-gdb_continue_to_breakpoint "cont to $bp" ".*fun4\.3.*"
+    set bp [gdb_get_line_number "fun4.3" $srcfile]
+    gdb_breakpoint $srcfile:$bp
 
-# reverse-step, then jump to the end of the trace
-gdb_test "reverse-next" ".*fun4\.2.*"
-gdb_test "record goto end" ".*fun4\.3.*"
+    # record the execution until we hit a breakpoint
+    gdb_test_no_output "record btrace ${method}"
+    gdb_continue_to_breakpoint "cont to $bp" ".*fun4\.3.*"
 
-# test that we can step away from a breakpoint after jumping to
-# the breakpoint PC
-gdb_test "next" ".*fun4\.4.*"
+    # reverse-step, then jump to the end of the trace
+    gdb_test "reverse-next" ".*fun4\.2.*"
+    gdb_test "record goto end" ".*fun4\.3.*"
+
+    # test that we can step away from a breakpoint after jumping to
+    # the breakpoint PC
+    gdb_test "next" ".*fun4\.4.*"
+}
diff --git a/gdb/testsuite/gdb.btrace/record_goto.exp b/gdb/testsuite/gdb.btrace/record_goto.exp
index cd6ab387c40..df1cb970996 100644
--- a/gdb/testsuite/gdb.btrace/record_goto.exp
+++ b/gdb/testsuite/gdb.btrace/record_goto.exp
@@ -19,6 +19,11 @@ 
 
 require allow_btrace_tests
 
+# When GDB prints the file for a stop location, it may print the full path
+# depending on what information the compiler added.  This regexp allows for
+# that path to be present, but does not require it.
+set optional_filepath {[^\n]*}
+
 # The "record goto" command jumps to a specific instruction in the execution
 # trace.  To guarantee that we always get the same execution trace, we use
 # an assembly source file.
@@ -43,157 +48,162 @@  if [info exists COMPILE] {
     return -1
 }
 
-if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] {
+if [build_executable "failed to prepare" $testfile $srcfile $opts] {
     return -1
 }
 
-if ![runto_main] {
-    return -1
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
+
+    # we want a small context sizes to simplify the test
+    gdb_test_no_output "set record instruction-history-size 3"
+    gdb_test_no_output "set record function-call-history-size 3"
+
+    # trace the call to the test function
+    gdb_test_no_output "record btrace ${method}"
+    gdb_test "next"
+
+    # start by listing all functions
+    gdb_test "record function-call-history /ci 1, +20" [multi_line \
+	"1\tmain\tinst 1,1" \
+	"2\t  fun4\tinst 2,4" \
+	"3\t    fun1\tinst 5,8" \
+	"4\t  fun4\tinst 9,9" \
+	"5\t    fun2\tinst 10,12" \
+	"6\t      fun1\tinst 13,16" \
+	"7\t    fun2\tinst 17,18" \
+	"8\t  fun4\tinst 19,19" \
+	"9\t    fun3\tinst 20,22" \
+	"10\t      fun1\tinst 23,26" \
+	"11\t    fun3\tinst 27,27" \
+	"12\t      fun2\tinst 28,30" \
+	"13\t        fun1\tinst 31,34" \
+	"14\t      fun2\tinst 35,36" \
+	"15\t    fun3\tinst 37,38" \
+	"16\t  fun4\tinst 39,40" \
+	]
+
+    # let's see if we can go back in history
+    gdb_test \
+	"record goto 19" ".*fun4 \\(\\) at ${optional_filepath}record_goto.c:43.*"
+
+    # the function call history should start at the new location
+    gdb_test "record function-call-history /ci" [multi_line \
+	"8\t  fun4\tinst 19,19" \
+	"9\t    fun3\tinst 20,22" \
+	"10\t      fun1\tinst 23,26" \
+	] "function-call-history from 19 forwards"
+
+    # the instruction history should start at the new location
+    gdb_test "record instruction-history" [multi_line \
+	"19.*" \
+	"20.*" \
+	"21.*" \
+	] "instruction-history from 19 forwards"
+
+    # let's go to another place in the history
+    gdb_test \
+	"record goto 27" \
+	".*fun3 \\(\\) at ${optional_filepath}record_goto.c:35.*"
+
+    # check the back trace at that location
+    gdb_test "backtrace" [multi_line \
+	"#0.*fun3.*at ${optional_filepath}record_goto.c:35.*" \
+	"#1.*fun4.*at ${optional_filepath}record_goto.c:43.*" \
+	"#2.*main.*at ${optional_filepath}record_goto.c:49.*" \
+	"Backtrace stopped: not enough registers or memory available to unwind further" \
+	]
+
+    # walk the backtrace
+    gdb_test "up" ".*fun4.*at ${optional_filepath}record_goto.c:43.*" "up to fun4"
+    gdb_test "up" ".*main.*at ${optional_filepath}record_goto.c:49.*" "up to main"
+
+    # the function call history should start at the new location
+    gdb_test "record function-call-history /ci -" [multi_line \
+	"9\t    fun3\tinst 20,22" \
+	"10\t      fun1\tinst 23,26" \
+	"11\t    fun3\tinst 27,27" \
+	] "function-call-history from 27 backwards"
+
+    # the instruction history should start at the new location
+    gdb_test "record instruction-history -" [multi_line \
+	"25.*" \
+	"26.*" \
+	"27.*" \
+	] "instruction-history from 27 backwards"
+
+    # test that we can go to the begin of the trace
+    gdb_test "record goto begin" ".*main \\(\\) at ${optional_filepath}record_goto.c:49.*"
+
+    # check that we're filling up the context correctly
+    gdb_test "record function-call-history /ci -" [multi_line \
+	"1\tmain\tinst 1,1" \
+	"2\t  fun4\tinst 2,4" \
+	"3\t    fun1\tinst 5,8" \
+	] "function-call-history from begin backwards"
+
+    # check that we're filling up the context correctly
+    gdb_test "record instruction-history -" [multi_line \
+	"1.*" \
+	"2.*" \
+	"3.*" \
+	] "instruction-history from begin backwards"
+
+    # we should get the exact same history from the first instruction
+    gdb_test "record goto 2" ".*fun4 \\(\\) at ${optional_filepath}record_goto.c:40.*"
+
+    # check that we're filling up the context correctly
+    gdb_test "record function-call-history /ci -" [multi_line \
+	"1\tmain\tinst 1,1" \
+	"2\t  fun4\tinst 2,4" \
+	"3\t    fun1\tinst 5,8" \
+	] "function-call-history from 2 backwards"
+
+    # check that we're filling up the context correctly
+    gdb_test "record instruction-history -" [multi_line \
+	"1.*" \
+	"2.*" \
+	"3.*" \
+	] "instruction-history from 2 backwards"
+
+    # check that we can go to the end of the trace
+    gdb_test "record goto end" ".*main \\(\\) at ${optional_filepath}record_goto.c:50.*"
+
+    # check that we're filling up the context correctly
+    gdb_test "record function-call-history /ci" [multi_line \
+	"14\t      fun2\tinst 35,36" \
+	"15\t    fun3\tinst 37,38" \
+	"16\t  fun4\tinst 39,40" \
+	] "function-call-history from end forwards"
+
+    # check that we're filling up the context correctly
+    gdb_test "record instruction-history" [multi_line \
+	"38.*" \
+	"39.*" \
+	"40.*" \
+	] "instruction-history from end forwards"
+
+    # we should get the exact same history from the second to last instruction
+    gdb_test "record goto 39" ".*fun4 \\(\\) at ${optional_filepath}record_goto.c:44.*"
+
+    # check that we're filling up the context correctly
+    gdb_test "record function-call-history /ci" [multi_line \
+	"14\t      fun2\tinst 35,36" \
+	"15\t    fun3\tinst 37,38" \
+	"16\t  fun4\tinst 39,40" \
+	] "function-call-history from 39 forwards"
+
+    # check that we're filling up the context correctly
+    gdb_test "record instruction-history" [multi_line \
+	"38.*" \
+	"39.*" \
+	"40.*" \
+	] "instruction-history from 39 forwards"
 }
-
-# When GDB prints the file for a stop location, it may print the full path
-# depending on what information the compiler added.  This regexp allows for
-# that path to be present, but does not require it.
-set optional_filepath {[^\n]*}
-
-# we want a small context sizes to simplify the test
-gdb_test_no_output "set record instruction-history-size 3"
-gdb_test_no_output "set record function-call-history-size 3"
-
-# trace the call to the test function
-gdb_test_no_output "record btrace"
-gdb_test "next"
-
-# start by listing all functions
-gdb_test "record function-call-history /ci 1, +20" [multi_line \
-  "1\tmain\tinst 1,1" \
-  "2\t  fun4\tinst 2,4" \
-  "3\t    fun1\tinst 5,8" \
-  "4\t  fun4\tinst 9,9" \
-  "5\t    fun2\tinst 10,12" \
-  "6\t      fun1\tinst 13,16" \
-  "7\t    fun2\tinst 17,18" \
-  "8\t  fun4\tinst 19,19" \
-  "9\t    fun3\tinst 20,22" \
-  "10\t      fun1\tinst 23,26" \
-  "11\t    fun3\tinst 27,27" \
-  "12\t      fun2\tinst 28,30" \
-  "13\t        fun1\tinst 31,34" \
-  "14\t      fun2\tinst 35,36" \
-  "15\t    fun3\tinst 37,38" \
-  "16\t  fun4\tinst 39,40" \
-  ]
-
-# let's see if we can go back in history
-gdb_test "record goto 19" ".*fun4 \\(\\) at ${optional_filepath}record_goto.c:43.*"
-
-# the function call history should start at the new location
-gdb_test "record function-call-history /ci" [multi_line \
-  "8\t  fun4\tinst 19,19" \
-  "9\t    fun3\tinst 20,22" \
-  "10\t      fun1\tinst 23,26" \
-  ] "function-call-history from 19 forwards"
-
-# the instruction history should start at the new location
-gdb_test "record instruction-history" [multi_line \
-  "19.*" \
-  "20.*" \
-  "21.*" \
-  ] "instruction-history from 19 forwards"
-
-# let's go to another place in the history
-gdb_test "record goto 27" ".*fun3 \\(\\) at ${optional_filepath}record_goto.c:35.*"
-
-# check the back trace at that location
-gdb_test "backtrace" [multi_line \
-  "#0.*fun3.*at ${optional_filepath}record_goto.c:35.*" \
-  "#1.*fun4.*at ${optional_filepath}record_goto.c:43.*" \
-  "#2.*main.*at ${optional_filepath}record_goto.c:49.*" \
-  "Backtrace stopped: not enough registers or memory available to unwind further" \
-  ]
-
-# walk the backtrace
-gdb_test "up" ".*fun4.*at ${optional_filepath}record_goto.c:43.*" "up to fun4"
-gdb_test "up" ".*main.*at ${optional_filepath}record_goto.c:49.*" "up to main"
-
-# the function call history should start at the new location
-gdb_test "record function-call-history /ci -" [multi_line \
-  "9\t    fun3\tinst 20,22" \
-  "10\t      fun1\tinst 23,26" \
-  "11\t    fun3\tinst 27,27" \
-  ] "function-call-history from 27 backwards"
-
-# the instruction history should start at the new location
-gdb_test "record instruction-history -" [multi_line \
-  "25.*" \
-  "26.*" \
-  "27.*" \
-  ] "instruction-history from 27 backwards"
-
-# test that we can go to the begin of the trace
-gdb_test "record goto begin" ".*main \\(\\) at ${optional_filepath}record_goto.c:49.*"
-
-# check that we're filling up the context correctly
-gdb_test "record function-call-history /ci -" [multi_line \
-  "1\tmain\tinst 1,1" \
-  "2\t  fun4\tinst 2,4" \
-  "3\t    fun1\tinst 5,8" \
-  ] "function-call-history from begin backwards"
-
-# check that we're filling up the context correctly
-gdb_test "record instruction-history -" [multi_line \
-  "1.*" \
-  "2.*" \
-  "3.*" \
-  ] "instruction-history from begin backwards"
-
-# we should get the exact same history from the first instruction
-gdb_test "record goto 2" ".*fun4 \\(\\) at ${optional_filepath}record_goto.c:40.*"
-
-# check that we're filling up the context correctly
-gdb_test "record function-call-history /ci -" [multi_line \
-  "1\tmain\tinst 1,1" \
-  "2\t  fun4\tinst 2,4" \
-  "3\t    fun1\tinst 5,8" \
-  ] "function-call-history from 2 backwards"
-
-# check that we're filling up the context correctly
-gdb_test "record instruction-history -" [multi_line \
-  "1.*" \
-  "2.*" \
-  "3.*" \
-  ] "instruction-history from 2 backwards"
-
-# check that we can go to the end of the trace
-gdb_test "record goto end" ".*main \\(\\) at ${optional_filepath}record_goto.c:50.*"
-
-# check that we're filling up the context correctly
-gdb_test "record function-call-history /ci" [multi_line \
-  "14\t      fun2\tinst 35,36" \
-  "15\t    fun3\tinst 37,38" \
-  "16\t  fun4\tinst 39,40" \
-  ] "function-call-history from end forwards"
-
-# check that we're filling up the context correctly
-gdb_test "record instruction-history" [multi_line \
-  "38.*" \
-  "39.*" \
-  "40.*" \
-  ] "instruction-history from end forwards"
-
-# we should get the exact same history from the second to last instruction
-gdb_test "record goto 39" ".*fun4 \\(\\) at ${optional_filepath}record_goto.c:44.*"
-
-# check that we're filling up the context correctly
-gdb_test "record function-call-history /ci" [multi_line \
-  "14\t      fun2\tinst 35,36" \
-  "15\t    fun3\tinst 37,38" \
-  "16\t  fun4\tinst 39,40" \
-  ] "function-call-history from 39 forwards"
-
-# check that we're filling up the context correctly
-gdb_test "record instruction-history" [multi_line \
-  "38.*" \
-  "39.*" \
-  "40.*" \
-  ] "instruction-history from 39 forwards"
diff --git a/gdb/testsuite/gdb.btrace/rn-dl-bind.exp b/gdb/testsuite/gdb.btrace/rn-dl-bind.exp
index 756be2fe404..e7189100a36 100644
--- a/gdb/testsuite/gdb.btrace/rn-dl-bind.exp
+++ b/gdb/testsuite/gdb.btrace/rn-dl-bind.exp
@@ -24,39 +24,48 @@ 
 require allow_btrace_tests
 
 standard_testfile
-if [prepare_for_testing "failed to prepare" $testfile $srcfile \
-	{debug ldflags=-Wl,-z,lazy}] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile \
+	{c++ debug ldflags=-Wl,-z,lazy}] {
     return -1
 }
 
-# trace the code for the call to test
-gdb_test_no_output "record btrace"
-gdb_test "next" ".*main\.2.*"
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
 
-# just dump the function-call-history to help debugging
-gdb_test_no_output "set record function-call-history-size 0"
-gdb_test "record function-call-history /cli 1" ".*"
+    if ![runto_main] {
+	continue
+    }
 
-# check that we can reverse-next and next
-with_test_prefix "main" {
-    gdb_test "reverse-next" ".*main\.1.*"
+    # trace the code for the call to test
+    gdb_test_no_output "record btrace ${method}"
     gdb_test "next" ".*main\.2.*"
-}
 
-# now go into test and try to (reverse-)next over the library call
-#
-# reverse-stepping through the epilogue is not very reliable; depending on
-# debug information we may stop at the closing brace or at the return.
-#
-# instead, run to test
-gdb_breakpoint test {temporary}
-gdb_test "reverse-continue" ".*test\.1.*"
+    # just dump the function-call-history to help debugging
+    gdb_test_no_output "set record function-call-history-size 0"
+    gdb_test "record function-call-history /cli 1" ".*"
+
+    # check that we can reverse-next and next
+    with_test_prefix "main" {
+	gdb_test "reverse-next" ".*main\.1.*"
+	gdb_test "next" ".*main\.2.*"
+    }
+
+    # now go into test and try to (reverse-)next over the library call
+    #
+    # reverse-stepping through the epilogue is not very reliable; depending on
+    # debug information we may stop at the closing brace or at the return.
+    #
+    # instead, run to test
+    gdb_breakpoint test {temporary}
+    gdb_test "reverse-continue" ".*test\.1.*"
 
-with_test_prefix "test" {
-    gdb_test "next" ".*test\.2.*"
-    gdb_test "reverse-next" ".*test\.1.*"
+    with_test_prefix "test" {
+	gdb_test "next" ".*test\.2.*"
+	gdb_test "reverse-next" ".*test\.1.*"
+    }
 }
diff --git a/gdb/testsuite/gdb.btrace/segv.exp b/gdb/testsuite/gdb.btrace/segv.exp
index 9804b93a877..20c13b05d9a 100644
--- a/gdb/testsuite/gdb.btrace/segv.exp
+++ b/gdb/testsuite/gdb.btrace/segv.exp
@@ -20,24 +20,32 @@ 
 require allow_btrace_tests
 
 standard_testfile
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
-    return -1
-}
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
-# trace the test code
-gdb_test_no_output "record btrace"
-gdb_test "continue" [multi_line \
-  "Program received signal SIGSEGV, Segmentation fault\." \
-  "0x0* in \\\?\\\? \\\(\\\)" \
-  ] "cont to segv"
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
 
-# we cannot do any high-level stepping
-gdb_test "reverse-finish" "Cannot find bounds of current function"
-gdb_test "reverse-next" "Cannot find bounds of current function"
-gdb_test "reverse-step" "Cannot find bounds of current function"
+    # trace the test code
+    gdb_test_no_output "record btrace ${method}"
+    gdb_test "continue" [multi_line \
+	"Program received signal SIGSEGV, Segmentation fault\." \
+	"0x0* in \\\?\\\? \\\(\\\)" \
+    ] "cont to segv"
 
-# but we can do instruction stepping
-gdb_test "reverse-stepi" "test\.call\[^\\\r\\\n\]*"
+    # we cannot do any high-level stepping
+    gdb_test "reverse-finish" "Cannot find bounds of current function"
+    gdb_test "reverse-next" "Cannot find bounds of current function"
+    gdb_test "reverse-step" "Cannot find bounds of current function"
+
+    # but we can do instruction stepping
+    gdb_test "reverse-stepi" "test\.call\[^\\\r\\\n\]*"
+}
diff --git a/gdb/testsuite/gdb.btrace/step.exp b/gdb/testsuite/gdb.btrace/step.exp
index 0adc18bd924..678461045a2 100644
--- a/gdb/testsuite/gdb.btrace/step.exp
+++ b/gdb/testsuite/gdb.btrace/step.exp
@@ -20,29 +20,37 @@ 
 require allow_btrace_tests
 
 standard_testfile record_goto.c
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
-# trace the call to the test function
-with_test_prefix "record" {
-    gdb_test_no_output "record btrace"
-    gdb_test "next"
-}
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
+
+    # trace the call to the test function
+    with_test_prefix "record" {
+	gdb_test_no_output "record btrace ${method}"
+	gdb_test "next"
+    }
 
-# let's step around a bit
-with_test_prefix "replay" {
-    gdb_test "reverse-next" ".*main\.2.*" "reverse-next.1"
-    gdb_test "step" ".*fun4\.2.*" "step.1"
-    gdb_test "next" ".*fun4\.3.*" "next.1"
-    gdb_test "step" ".*fun2\.2.*" "step.2"
-    gdb_test "finish" ".*fun4\.4.*" "finish.1"
-    gdb_test "reverse-step" ".*fun2\.3.*" "reverse-step.1"
-    gdb_test "reverse-finish" ".*fun4\.3.*" "reverse-finish.1"
-    gdb_test "reverse-next" ".*fun4\.2.*" "reverse-next.2"
-    gdb_test "reverse-finish" ".*main\.2.*" "reverse-finish.2"
+    # let's step around a bit
+    with_test_prefix "replay" {
+	gdb_test "reverse-next" ".*main\.2.*" "reverse-next.1"
+	gdb_test "step" ".*fun4\.2.*" "step.1"
+	gdb_test "next" ".*fun4\.3.*" "next.1"
+	gdb_test "step" ".*fun2\.2.*" "step.2"
+	gdb_test "finish" ".*fun4\.4.*" "finish.1"
+	gdb_test "reverse-step" ".*fun2\.3.*" "reverse-step.1"
+	gdb_test "reverse-finish" ".*fun4\.3.*" "reverse-finish.1"
+	gdb_test "reverse-next" ".*fun4\.2.*" "reverse-next.2"
+	gdb_test "reverse-finish" ".*main\.2.*" "reverse-finish.2"
+    }
 }
diff --git a/gdb/testsuite/gdb.btrace/stepi.exp b/gdb/testsuite/gdb.btrace/stepi.exp
index a70a5adf046..c8346f28eef 100644
--- a/gdb/testsuite/gdb.btrace/stepi.exp
+++ b/gdb/testsuite/gdb.btrace/stepi.exp
@@ -41,11 +41,7 @@  if [info exists COMPILE] {
     return -1
 }
 
-if [prepare_for_testing "failed to prepare" $testfile $srcfile {}] {
-    return -1
-}
-
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
@@ -60,119 +56,130 @@  proc check_replay_at { insn } {
     ] "check replay at $insn"
 }
 
-# trace the call to the test function
-with_test_prefix "record" {
-    gdb_test_no_output "record btrace"
-    gdb_test "next" ".*" "next.1"
-}
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
 
-# we start with stepping to make sure that the trace is fetched automatically
-with_test_prefix "fetch" {
-    gdb_test "reverse-stepi" ".*fun4\.5.*" "reverse-stepi.1"
-    gdb_test "reverse-stepi" ".*fun4\.5.*" "reverse-stepi.2"
+    # trace the call to the test function
+    with_test_prefix "record" {
+	gdb_test_no_output "record btrace ${method}"
+	gdb_test "next" ".*" "next.1"
+    }
 
-    # let's check where we are in the trace
-    check_replay_at 39
-}
+    # we start with stepping to make sure that the trace is fetched automatically
+    with_test_prefix "fetch" {
+	gdb_test "reverse-stepi" ".*fun4\.5.*" "reverse-stepi.1"
+	gdb_test "reverse-stepi" ".*fun4\.5.*" "reverse-stepi.2"
 
-# let's step forward and check again
-with_test_prefix "stepi" {
-    gdb_test "stepi" ".*fun4\.5.*"
-    check_replay_at 40
-}
+	# let's check where we are in the trace
+	check_replay_at 39
+    }
 
-# with the next step, we stop replaying
-with_test_prefix "end" {
-    gdb_test "stepi" ".*main\.3.*"
-    gdb_test "info record" [multi_line \
-      "Active record target: record-btrace" \
-      ".*" \
-      "Recorded 40 instructions in 16 functions \\\(0 gaps\\\) for \[^\\\r\\\n\]*" \
-			       ]
-}
+    # let's step forward and check again
+    with_test_prefix "stepi" {
+	gdb_test "stepi" ".*fun4\.5.*"
+	check_replay_at 40
+    }
 
-# let's try nexti
-with_test_prefix "reverse-nexti.1" {
-    gdb_test "reverse-nexti" ".*main\.2.*"
-    check_replay_at 1
-}
+    # with the next step, we stop replaying
+    with_test_prefix "end" {
+	gdb_test "stepi" ".*main\.3.*"
+	gdb_test "info record" [multi_line \
+	    "Active record target: record-btrace" \
+	    ".*" \
+	    "Recorded 40 instructions in 16 functions \\\(0 gaps\\\) for \[^\\\r\\\n\]*" \
+	    ]
+    }
 
-# we can't reverse-nexti any further
-with_test_prefix "reverse-nexti.2" {
-    gdb_test "reverse-nexti" \
-	"No more reverse-execution history\.\r\n.*main\.2.*" \
-	"reverse-nexti.2"
-    check_replay_at 1
-}
+    # let's try nexti
+    with_test_prefix "reverse-nexti.1" {
+	gdb_test "reverse-nexti" ".*main\.2.*"
+	check_replay_at 1
+    }
 
-# but we can step back again
-with_test_prefix "nexti" {
-    gdb_test "nexti" ".*main\.3.*"
-    gdb_test "info record" [multi_line \
-      "Active record target: record-btrace" \
-      ".*" \
-      "Recorded 40 instructions in 16 functions \\\(0 gaps\\\) for \[^\\\r\\\n\]*" \
-			       ]
-}
+    # we can't reverse-nexti any further
+    with_test_prefix "reverse-nexti.2" {
+	gdb_test "reverse-nexti" \
+	    "No more reverse-execution history\.\r\n.*main\.2.*" \
+	    "reverse-nexti.2"
+	check_replay_at 1
+    }
 
-# let's step from a goto position somewhere in the middle
-with_test_prefix "goto" {
-    gdb_test "record goto 22" ".*fun3\.2.*"
-    with_test_prefix "goto 22" { check_replay_at 22 }
+    # but we can step back again
+    with_test_prefix "nexti" {
+	gdb_test "nexti" ".*main\.3.*"
+	gdb_test "info record" [multi_line \
+	    "Active record target: record-btrace" \
+	    ".*" \
+	    "Recorded 40 instructions in 16 functions \\\(0 gaps\\\) for \[^\\\r\\\n\]*" \
+	    ]
+    }
 
-    gdb_test "stepi" ".*fun1\.1.*" "stepi.3"
-    with_test_prefix "stepi to 23" { check_replay_at 23 }
+    # let's step from a goto position somewhere in the middle
+    with_test_prefix "goto" {
+	gdb_test "record goto 22" ".*fun3\.2.*"
+	with_test_prefix "goto 22" { check_replay_at 22 }
 
-    gdb_test "reverse-stepi" ".*fun3\.2.*" "reverse-stepi.3"
-    with_test_prefix "reverse-stepi to 22" { check_replay_at 22 }
+	gdb_test "stepi" ".*fun1\.1.*" "stepi.3"
+	with_test_prefix "stepi to 23" { check_replay_at 23 }
 
-    gdb_test "nexti" ".*fun3\.3.*"
-    with_test_prefix "nexti to 27" { check_replay_at 27 }
+	gdb_test "reverse-stepi" ".*fun3\.2.*" "reverse-stepi.3"
+	with_test_prefix "reverse-stepi to 22" { check_replay_at 22 }
 
-    gdb_test "reverse-nexti" ".*fun3\.2.*" "reverse-nexti.3"
-    with_test_prefix "reverse-nexti to 22" { check_replay_at 22 }
-}
+	gdb_test "nexti" ".*fun3\.3.*"
+	with_test_prefix "nexti to 27" { check_replay_at 27 }
 
-# let's try to step off the left end
-with_test_prefix "goto begin" {
-    gdb_test "record goto begin" ".*main\.2.*"
-    check_replay_at 1
+	gdb_test "reverse-nexti" ".*fun3\.2.*" "reverse-nexti.3"
+	with_test_prefix "reverse-nexti to 22" { check_replay_at 22 }
+    }
 
-    with_test_prefix "reverse-stepi" {
-	gdb_test "reverse-stepi" \
-	    "No more reverse-execution history\.\r\n.*main\.2.*" \
-	    "reverse-stepi.1"
-	gdb_test "reverse-stepi" \
-	    "No more reverse-execution history\.\r\n.*main\.2.*" \
-	    "reverse-stepi.2"
+    # let's try to step off the left end
+    with_test_prefix "goto begin" {
+	gdb_test "record goto begin" ".*main\.2.*"
 	check_replay_at 1
+
+	with_test_prefix "reverse-stepi" {
+	    gdb_test "reverse-stepi" \
+		"No more reverse-execution history\.\r\n.*main\.2.*" \
+		"reverse-stepi.1"
+	    gdb_test "reverse-stepi" \
+		"No more reverse-execution history\.\r\n.*main\.2.*" \
+		"reverse-stepi.2"
+	    check_replay_at 1
+	}
+
+	with_test_prefix "reverse-nexti" {
+	    gdb_test "reverse-nexti" \
+		"No more reverse-execution history\.\r\n.*main\.2.*" \
+		"reverse-nexti.1"
+	    gdb_test "reverse-nexti" \
+		"No more reverse-execution history\.\r\n.*main\.2.*" \
+		"reverse-nexti.2"
+	    check_replay_at 1
+	}
+
+	# we can step forward, though
+	with_test_prefix "stepi" {
+	    gdb_test "stepi" ".*fun4\.1.*"
+	    check_replay_at 2
+	}
     }
 
-    with_test_prefix "reverse-nexti" {
-	gdb_test "reverse-nexti" \
+    # let's try to step off the left end again
+    with_test_prefix "reverse-stepi" {
+	gdb_test "reverse-stepi" ".*main\.2.*" "reverse-stepi.1"
+	gdb_test "reverse-stepi" \
 	    "No more reverse-execution history\.\r\n.*main\.2.*" \
-	    "reverse-nexti.1"
-	gdb_test "reverse-nexti" \
+	    "reverse-stepi.2"
+	gdb_test "reverse-stepi" \
 	    "No more reverse-execution history\.\r\n.*main\.2.*" \
-	    "reverse-nexti.2"
+	    "reverse-stepi.3"
 	check_replay_at 1
     }
-
-    # we can step forward, though
-    with_test_prefix "stepi" {
-	gdb_test "stepi" ".*fun4\.1.*"
-	check_replay_at 2
-    }
-}
-
-# let's try to step off the left end again
-with_test_prefix "reverse-stepi" {
-    gdb_test "reverse-stepi" ".*main\.2.*" "reverse-stepi.1"
-    gdb_test "reverse-stepi" \
-	"No more reverse-execution history\.\r\n.*main\.2.*" \
-	"reverse-stepi.2"
-    gdb_test "reverse-stepi" \
-	"No more reverse-execution history\.\r\n.*main\.2.*" \
-	"reverse-stepi.3"
-    check_replay_at 1
 }
diff --git a/gdb/testsuite/gdb.btrace/tailcall-only.exp b/gdb/testsuite/gdb.btrace/tailcall-only.exp
index ae3b04e3b66..c90ba8b1bd3 100644
--- a/gdb/testsuite/gdb.btrace/tailcall-only.exp
+++ b/gdb/testsuite/gdb.btrace/tailcall-only.exp
@@ -21,7 +21,6 @@ 
 #
 
 require allow_btrace_tests
-
 # This test requires the compiler to generate a tail call.  To guarantee that
 # we always get one, we use an assembly source file.
 #
@@ -29,6 +28,7 @@  require allow_btrace_tests
 #
 # Luckily, they are similar enough that a single test script can handle
 # both.
+
 set opts {}
 if [info exists COMPILE] {
     # make check RUNTESTFLAGS="gdb.btrace/tailcall-only.exp COMPILE=1"
@@ -45,55 +45,63 @@  if [info exists COMPILE] {
     return -1
 }
 
-if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] {
+if [build_executable "failed to prepare" $testfile $srcfile $opts] {
     return -1
 }
 
-if ![runto_main] {
-    return -1
-}
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
 
-# we want to see the full trace for this test
-gdb_test_no_output "set record function-call-history-size 0"
+    if ![runto_main] {
+	continue
+    }
 
-# trace foo
-gdb_test "step" ".*" "prepare for recording"
-gdb_test_no_output "record btrace"
-gdb_test "stepi 4" ".*" "record branch trace"
+    # we want to see the full trace for this test
+    gdb_test_no_output "set record function-call-history-size 0"
 
-# for debugging
-gdb_test "info record" ".*"
+    # trace foo
+    gdb_test "step" ".*" "prepare for recording"
+    gdb_test_no_output "record btrace ${method}"
+    gdb_test "stepi 4" ".*" "record branch trace"
 
-# show the branch trace with calls indented
-gdb_test "record function-call-history /c 1" [multi_line \
-  "1\tfoo" \
-  "2\t  foo_1" \
-  "3\t    bar" \
-  "4\t      bar_1"
-  ] "function-call-history"
+    # for debugging
+    gdb_test "info record" ".*"
 
-# We can step
-gdb_test "record goto begin" ".*foo.*"
-gdb_test "stepi" ".*foo_1.*" "step into foo_1"
-gdb_test "step" ".*bar.*" "step into bar"
-gdb_test "stepi" ".*bar_1.*" "step into bar_1"
+    # show the branch trace with calls indented
+    gdb_test "record function-call-history /c 1" [multi_line \
+	"1\tfoo" \
+	"2\t  foo_1" \
+	"3\t    bar" \
+	"4\t      bar_1"
+	] "function-call-history"
 
-# We can neither finish nor return.
-gdb_test "finish" "Cannot find the caller frame.*"
-gdb_test_multiple "return" "return" {
-  -re "Make .* return now.*y or n. $" {
-    send_gdb "y\n"
-    exp_continue
-  }
-  -re "Cannot find the caller frame.*$gdb_prompt $" {
-    pass "return"
-  }
-}
+    # We can step
+    gdb_test "record goto begin" ".*foo.*"
+    gdb_test "stepi" ".*foo_1.*" "step into foo_1"
+    gdb_test "step" ".*bar.*" "step into bar"
+    gdb_test "stepi" ".*bar_1.*" "step into bar_1"
 
-# But we can reverse-finish
-gdb_test "reverse-finish" ".*bar.*"
-gdb_test "reverse-step" ".*foo_1.*"
+    # We can neither finish nor return.
+    gdb_test "finish" "Cannot find the caller frame.*"
+    gdb_test_multiple "return" "return" {
+	-re "Make .* return now.*y or n. $" {
+	    send_gdb "y\n"
+	    continue
+	}
+	-re "Cannot find the caller frame.*$gdb_prompt $" {
+	    pass "return"
+	}
+    }
 
-# Info frame isn't useful but doesn't crash as it used to.
-gdb_test "up" ".*foo.*"
-gdb_test "info frame" ".*"
+    # But we can reverse-finish
+    gdb_test "reverse-finish" ".*bar.*"
+    gdb_test "reverse-step" ".*foo_1.*"
+
+    # Info frame isn't useful but doesn't crash as it used to.
+    gdb_test "up" ".*foo.*"
+    gdb_test "info frame" ".*"
+}
diff --git a/gdb/testsuite/gdb.btrace/tailcall.exp b/gdb/testsuite/gdb.btrace/tailcall.exp
index 198cfa988dd..2116dae6a1c 100644
--- a/gdb/testsuite/gdb.btrace/tailcall.exp
+++ b/gdb/testsuite/gdb.btrace/tailcall.exp
@@ -32,20 +32,17 @@  if [info exists COMPILE] {
     standard_testfile tailcall.c
     lappend opts debug optimize=-O2
 } elseif {[istarget "i?86-*-*"] || [istarget "x86_64-*-*"]} {
-	if {[is_amd64_regs_target]} {
-		standard_testfile x86_64-tailcall.S
-	} else {
-		standard_testfile i686-tailcall.S
-	}
+    if {[is_amd64_regs_target]} {
+	standard_testfile x86_64-tailcall.S
+    } else {
+	standard_testfile i686-tailcall.S
+    }
 } else {
     unsupported "target architecture not supported"
     return -1
 }
 
-if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] {
-    return -1
-}
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile $opts] {
     return -1
 }
 
@@ -54,63 +51,75 @@  if ![runto_main] {
 # that path to be present, but does not require it.
 set optional_filepath {[^\n]*}
 
-# we want to see the full trace for this test
-gdb_test_no_output "set record function-call-history-size 0"
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+
+    if ![runto_main] {
+	continue
+    }
 
-# trace the call to foo
-gdb_test_no_output "record btrace"
-gdb_test "next 2"
+    # we want to see the full trace for this test
+    gdb_test_no_output "set record function-call-history-size 0"
 
-# show the flat branch trace
-gdb_test "record function-call-history 1" [multi_line \
-  "1\tmain" \
-  "2\tfoo" \
-  "3\tbar" \
-  "4\tmain" \
-  ] "flat"
+    # trace the call to foo
+    gdb_test_no_output "record btrace ${method}"
+    gdb_test "next 2"
 
-# show the branch trace with calls indented
-gdb_test "record function-call-history /c 1" [multi_line \
-  "1\tmain" \
-  "2\t  foo" \
-  "3\t    bar" \
-  "4\tmain" \
-  ] "indented"
+    # show the flat branch trace
+    gdb_test "record function-call-history 1" [multi_line \
+	"1\tmain" \
+	"2\tfoo" \
+	"3\tbar" \
+	"4\tmain" \
+	] "flat"
 
-# go into bar
-gdb_test "record goto 4" ".*bar \\(\\) at ${optional_filepath}tailcall.c:24\r\n.*"
+    # show the branch trace with calls indented
+    gdb_test "record function-call-history /c 1" [multi_line \
+	"1\tmain" \
+	"2\t  foo" \
+	"3\t    bar" \
+	"4\tmain" \
+	] "indented"
 
-# check the backtrace
-gdb_test "backtrace" [multi_line \
-  "#0.*bar \\(\\) at ${optional_filepath}tailcall.c:24" \
-  "#1.*foo \\(\\) at ${optional_filepath}tailcall.c:29" \
-  "#2.*main \\(\\) at ${optional_filepath}tailcall.c:37" \
-  "Backtrace stopped: not enough registers or memory available to unwind further" \
-  ]
+    # go into bar
+    gdb_test "record goto 4" ".*bar \\(\\) at ${optional_filepath}tailcall.c:24\r\n.*"
 
-# walk the backtrace
-gdb_test "up" "#1\[^\r\n\]*foo \\(\\) at ${optional_filepath}tailcall.c:29\r\n.*" "up to foo"
-gdb_test "up" "#2\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:37\r\n.*" "up to main"
-gdb_test "down" "#1\[^\r\n\]*foo \\(\\) at ${optional_filepath}tailcall.c:29\r\n.*" "down to foo"
+    # check the backtrace
+    gdb_test "backtrace" [multi_line \
+	"#0.*bar \\(\\) at ${optional_filepath}tailcall.c:24" \
+	"#1.*foo \\(\\) at ${optional_filepath}tailcall.c:29" \
+	"#2.*main \\(\\) at ${optional_filepath}tailcall.c:37" \
+	"Backtrace stopped: not enough registers or memory available to unwind further" \
+	]
 
-# test stepping into and out of tailcalls.
-gdb_test "finish" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:38\r\n.*" \
-    "finish.1"
-gdb_test "reverse-step" "\[^\r\n\]*bar \\(\\) at ${optional_filepath}tailcall.c:24\r\n.*" \
-    "reverse-step.1"
-gdb_test "reverse-finish" "\[^\r\n\]*foo \\(\\) at ${optional_filepath}tailcall.c:29\r\n.*" \
-    "reverse-finish.1"
-gdb_test "reverse-step" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:37\r\n.*" \
-    "reverse-step.2"
-gdb_test "next" "\[^\r\n\]*38.*" \
-    "next.1"
-gdb_test "reverse-next" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:37\r\n.*" \
-    "reverse-next.1"
-gdb_test "step" "\[^\r\n\]*foo \\(\\) at ${optional_filepath}tailcall.c:29\r\n.*" \
-    "step.1"
-gdb_test "finish" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:38\r\n.*" \
-    "finish.2"
-gdb_test "reverse-step" "\[^\r\n\]*bar \\(\\) at ${optional_filepath}tailcall.c:24\r\n.*" \
-    "reverse-step.3"
-gdb_test "finish" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:38\r\n.*" \
-    "finish.3"
+    # walk the backtrace
+    gdb_test "up" "#1\[^\r\n\]*foo \\(\\) at ${optional_filepath}tailcall.c:29\r\n.*" "up to foo"
+    gdb_test "up" "#2\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:37\r\n.*" "up to main"
+    gdb_test "down" "#1\[^\r\n\]*foo \\(\\) at ${optional_filepath}tailcall.c:29\r\n.*" "down to foo"
+
+    # test stepping into and out of tailcalls.
+    gdb_test "finish" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:38\r\n.*" \
+	"finish.1"
+    gdb_test "reverse-step" "\[^\r\n\]*bar \\(\\) at ${optional_filepath}tailcall.c:24\r\n.*" \
+	"reverse-step.1"
+    gdb_test "reverse-finish" "\[^\r\n\]*foo \\(\\) at ${optional_filepath}tailcall.c:29\r\n.*" \
+	"reverse-finish.1"
+    gdb_test "reverse-step" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:37\r\n.*" \
+	"reverse-step.2"
+    gdb_test "next" "\[^\r\n\]*38.*" \
+	"next.1"
+    gdb_test "reverse-next" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:37\r\n.*" \
+	"reverse-next.1"
+    gdb_test "step" "\[^\r\n\]*foo \\(\\) at ${optional_filepath}tailcall.c:29\r\n.*" \
+	"step.1"
+    gdb_test "finish" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:38\r\n.*" \
+	"finish.2"
+    gdb_test "reverse-step" "\[^\r\n\]*bar \\(\\) at ${optional_filepath}tailcall.c:24\r\n.*" \
+	"reverse-step.3"
+    gdb_test "finish" "\[^\r\n\]*main \\(\\) at ${optional_filepath}tailcall.c:38\r\n.*" \
+	"finish.3"
+}
diff --git a/gdb/testsuite/gdb.btrace/tsx.exp b/gdb/testsuite/gdb.btrace/tsx.exp
index d312b15027c..11e230c8547 100644
--- a/gdb/testsuite/gdb.btrace/tsx.exp
+++ b/gdb/testsuite/gdb.btrace/tsx.exp
@@ -15,7 +15,7 @@ 
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-require allow_btrace_pt_tests allow_tsx_tests
+require allow_btrace_pt_tests allow_tsx_tests allow_btrace_tests
 
 standard_testfile .c x86-tsx.S
 if [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" {debug}] {
diff --git a/gdb/testsuite/gdb.btrace/unknown_functions.exp b/gdb/testsuite/gdb.btrace/unknown_functions.exp
index b335e74c87a..618df4c9761 100644
--- a/gdb/testsuite/gdb.btrace/unknown_functions.exp
+++ b/gdb/testsuite/gdb.btrace/unknown_functions.exp
@@ -18,47 +18,53 @@ 
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 require allow_btrace_tests
-
 standard_testfile
 
 # We expect a specific function call history.  This gets messed up with
 # PIE on 32-bit.
 #
 # Also discard local symbols.
-if [prepare_for_testing "failed to prepare" $testfile $srcfile \
+if [build_executable "failed to prepare" $testfile $srcfile \
 	{ldflags=-Wl,-x nopie}] {
     return -1
 }
 
-if ![runto test] {
-    return -1
-}
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto test] {
+	continue
+    }
 
-# we want to see the full trace for this test
-gdb_test_no_output "set record function-call-history-size 0"
+    # we want to see the full trace for this test
+    gdb_test_no_output "set record function-call-history-size 0"
 
-# trace from one call of test to the next
-gdb_test_no_output "record btrace"
-gdb_continue_to_breakpoint "cont to test" ".*test.*"
+    # trace from one call of test to the next
+    gdb_test_no_output "record btrace ${method}"
+    gdb_continue_to_breakpoint "cont to test" ".*test.*"
 
-# show the flat branch trace
-gdb_test "record function-call-history 1" [multi_line \
-  "1\ttest" \
-  "2\t\\\?\\\?" \
-  "3\t\\\?\\\?" \
-  "4\t\\\?\\\?" \
-  "5\ttest" \
-  "6\tmain" \
-  "7\ttest" \
-  ] "flat"
+    # show the flat branch trace
+    gdb_test "record function-call-history 1" [multi_line \
+	"1\ttest" \
+	"2\t\\\?\\\?" \
+	"3\t\\\?\\\?" \
+	"4\t\\\?\\\?" \
+	"5\ttest" \
+	"6\tmain" \
+	"7\ttest" \
+	] "flat"
 
-# show the branch trace with calls indented
-gdb_test "record function-call-history /c 1" [multi_line \
-  "1\t  test" \
-  "2\t    \\\?\\\?" \
-  "3\t      \\\?\\\?" \
-  "4\t    \\\?\\\?" \
-  "5\t  test" \
-  "6\tmain" \
-  "7\t  test" \
-  ] "indented"
+    # show the branch trace with calls indented
+    gdb_test "record function-call-history /c 1" [multi_line \
+	"1\t  test" \
+	"2\t    \\\?\\\?" \
+	"3\t      \\\?\\\?" \
+	"4\t    \\\?\\\?" \
+	"5\t  test" \
+	"6\tmain" \
+	"7\t  test" \
+	] "indented"
+}
diff --git a/gdb/testsuite/gdb.btrace/vdso.exp b/gdb/testsuite/gdb.btrace/vdso.exp
index edbb222f7b6..cf01ed6fcd1 100644
--- a/gdb/testsuite/gdb.btrace/vdso.exp
+++ b/gdb/testsuite/gdb.btrace/vdso.exp
@@ -23,22 +23,29 @@ 
 require allow_btrace_tests
 
 standard_testfile
-if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
-    return -1
-}
 
-if ![runto_main] {
+if [build_executable "failed to prepare" $testfile $srcfile] {
     return -1
 }
 
-# capture the disassembly of gettimeofday while live debugging
-set live_gettimeofday [capture_command_output "disassemble gettimeofday" ""]
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
+
+    # capture the disassembly of gettimeofday while live debugging
+    set live_gettimeofday [capture_command_output "disassemble gettimeofday" ""]
 
-# trace the test code
-gdb_test_no_output "record btrace"
-gdb_test "stepi" ".*"
+    # trace the test code
+    gdb_test_no_output "record btrace ${method}"
+    gdb_test "stepi" ".*"
 
-with_test_prefix "replay" {
+    with_test_prefix "replay" {
 	# start replaying
 	gdb_test "record goto begin" ".*"
 	gdb_test "info record" "Replay in progress\.\[^\\\r\\\n\]*"
@@ -48,8 +55,9 @@  with_test_prefix "replay" {
 
 	# the two disassemblies must be identical
 	if ![string compare $live_gettimeofday $replay_gettimeofday]  {
-		pass "disassemble gettimeofday"
-	} else {
-		fail "disassemble gettimeofday"
+	    pass "disassemble gettimeofday"
+	} else 	{
+	    fail "disassemble gettimeofday"
 	}
+    }
 }
diff --git a/gdb/testsuite/gdb.python/py-record-btrace-threads.exp b/gdb/testsuite/gdb.python/py-record-btrace-threads.exp
index d7238790bc4..e673cc6b5ae 100644
--- a/gdb/testsuite/gdb.python/py-record-btrace-threads.exp
+++ b/gdb/testsuite/gdb.python/py-record-btrace-threads.exp
@@ -25,45 +25,52 @@  if { [gdb_compile_pthreads "$srcdir/$subdir/$srcfile" "$binfile" executable {deb
     untested "failed to prepare"
     return -1
 }
-clean_restart $testfile
 
-if { ![runto_main] } {
-    return -1
-}
+foreach_with_prefix method {"bts" "pt"} {
+    if { ![target_supports_btrace $method] } {
+	unsupported "target does not support record-btrace ${method}"
+	continue
+    }
 
-# set up breakpoints
-gdb_breakpoint $srcfile:[gdb_get_line_number "bp1" $srcfile]
-gdb_breakpoint $srcfile:[gdb_get_line_number "bp2" $srcfile]
+    clean_restart "${testfile}"
+    if ![runto_main] {
+	continue
+    }
 
-# record data
-gdb_continue_to_breakpoint "cont to bp.1" ".*bp1.*"
-gdb_test_no_output "record btrace"
-gdb_continue_to_breakpoint "cont to bp.2" ".*bp2.*"
+    # set up breakpoints
+    gdb_breakpoint $srcfile:[gdb_get_line_number "bp1" $srcfile]
+    gdb_breakpoint $srcfile:[gdb_get_line_number "bp2" $srcfile]
 
-# acquire the record objects for thread 1 and thread 2
-gdb_test "thread 1" ".*"
-gdb_test "record function-call-history" ".*" "fch thread 1"
-gdb_test_no_output "python rec1 = gdb.current_recording()"
-gdb_test "thread 2" ".*"
-gdb_test "record function-call-history" ".*" "fch thread 2"
-gdb_test_no_output "python rec2 = gdb.current_recording()"
+    # record data
+    gdb_continue_to_breakpoint "cont to bp.1" ".*bp1.*"
+    gdb_test_no_output "record btrace ${method}"
+    gdb_continue_to_breakpoint "cont to bp.2" ".*bp2.*"
 
-# Thread 1 is supposed to call func1 (), thread 2 is supposed to call func2 ().
-# Check that the function call history for the current thread contains a call
-# to the right function and does not contain a call to the wrong function.
-proc check_insn_for_thread { self other } {
-  with_test_prefix "checking thread $self" {
-    gdb_test_no_output "python fch = rec$self.function_call_history"
-    gdb_test_no_output "python f1calls = \{x for x in fch if x.symbol and x.symbol.name == \"func1\"\}"
-    gdb_test_no_output "python f2calls = \{x for x in fch if x.symbol and x.symbol.name == \"func2\"\}"
+    # acquire the record objects for thread 1 and thread 2
+    gdb_test "thread 1" ".*"
+    gdb_test "record function-call-history" ".*" "fch thread 1"
+    gdb_test_no_output "python rec1 = gdb.current_recording()"
+    gdb_test "thread 2" ".*"
+    gdb_test "record function-call-history" ".*" "fch thread 2"
+    gdb_test_no_output "python rec2 = gdb.current_recording()"
 
-    gdb_test "python print(not f${self}calls)" "False"
-    gdb_test "python print(not f${other}calls)" "True"
-  }
-}
+    # Thread 1 is supposed to call func1 (), thread 2 is supposed to call func2 ().
+    # Check that the function call history for the current thread contains a call
+    # to the right function and does not contain a call to the wrong function.
+    proc check_insn_for_thread { self other } {
+	with_test_prefix "checking thread $self" {
+	    gdb_test_no_output "python fch = rec$self.function_call_history"
+	    gdb_test_no_output "python f1calls = \{x for x in fch if x.symbol and x.symbol.name == \"func1\"\}"
+	    gdb_test_no_output "python f2calls = \{x for x in fch if x.symbol and x.symbol.name == \"func2\"\}"
+
+	    gdb_test "python print(not f${self}calls)" "False"
+	    gdb_test "python print(not f${other}calls)" "True"
+	}
+    }
 
-foreach_with_prefix thread { 1 2 } {
-  gdb_test "thread $thread"
-  check_insn_for_thread 1 2
-  check_insn_for_thread 2 1
+    foreach_with_prefix thread { 1 2 } {
+	gdb_test "thread $thread"
+	check_insn_for_thread 1 2
+	check_insn_for_thread 2 1
+    }
 }
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index fe4ac7d2719..62eadc9696f 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -4008,68 +4008,29 @@  gdb_caching_proc allow_avx512fp16_tests {} {
     return $allow_avx512fp16_tests
 }
 
-# Run a test on the target to see if it supports btrace hardware.  Return 1 if so,
-# 0 if it does not.  Based on 'check_vmx_hw_available' from the GCC testsuite.
+# Check if btrace is supported on the target.  Return 1 if
+# so, 0 if it does not.
 
 gdb_caching_proc allow_btrace_tests {} {
-    global srcdir subdir gdb_prompt inferior_exited_re
-
-    set me "allow_btrace_tests"
     if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
-	verbose "$me:  target does not support btrace, returning 0" 2
-	return 0
-    }
-
-    # Compile a test program.
-    set src { int main() { return 0; } }
-    if {![gdb_simple_compile $me $src executable]} {
+	verbose "target_supports_btrace:  target does not support btrace, returning 0" 2
 	return 0
     }
 
-    # No error message, compilation succeeded so now run it via gdb.
-
-    gdb_exit
-    gdb_start
-    gdb_reinitialize_dir $srcdir/$subdir
-    gdb_load $obj
-    if ![runto_main] {
+    if { ![allow_btrace_bts_tests] && ![allow_btrace_pt_tests] } {
 	return 0
     }
-    # In case of an unexpected output, we return 2 as a fail value.
-    set allow_btrace_tests 2
-    gdb_test_multiple "record btrace" "check btrace support" {
-        -re "You can't do that when your target is.*\r\n$gdb_prompt $" {
-	    set allow_btrace_tests 0
-        }
-        -re "Target does not support branch tracing.*\r\n$gdb_prompt $" {
-	    set allow_btrace_tests 0
-        }
-        -re "Could not enable branch tracing.*\r\n$gdb_prompt $" {
-	    set allow_btrace_tests 0
-        }
-        -re "^record btrace\r\n$gdb_prompt $" {
-	    set allow_btrace_tests 1
-        }
-    }
-    gdb_exit
-    remote_file build delete $obj
-
-    verbose "$me:  returning $allow_btrace_tests" 2
-    return $allow_btrace_tests
+    return 1
 }
 
-# Run a test on the target to see if it supports btrace pt hardware.
+# Run a test on the target to see if it supports btrace input method.
 # Return 1 if so, 0 if it does not.  Based on 'check_vmx_hw_available'
 # from the GCC testsuite.
 
-gdb_caching_proc allow_btrace_pt_tests {} {
+proc check_btrace_method_support {method} {
     global srcdir subdir gdb_prompt inferior_exited_re
 
-    set me "allow_btrace_pt_tests"
-    if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
-	verbose "$me:  target does not support btrace, returning 1" 2
-	return 0
-    }
+    set me "check_btrace_${method}_support"
 
     # Compile a test program.
     set src { int main() { return 0; } }
@@ -4087,31 +4048,62 @@  gdb_caching_proc allow_btrace_pt_tests {} {
 	return 0
     }
     # In case of an unexpected output, we return 2 as a fail value.
-    set allow_btrace_pt_tests 2
-    gdb_test_multiple "record btrace pt" "check btrace pt support" {
-        -re "You can't do that when your target is.*\r\n$gdb_prompt $" {
-	    set allow_btrace_pt_tests 0
-        }
-        -re "Target does not support branch tracing.*\r\n$gdb_prompt $" {
-	    set allow_btrace_pt_tests 0
-        }
-        -re "Could not enable branch tracing.*\r\n$gdb_prompt $" {
-	    set allow_btrace_pt_tests 0
-        }
-        -re "support was disabled at compile time.*\r\n$gdb_prompt $" {
-	    set allow_btrace_pt_tests 0
-        }
-        -re "^record btrace pt\r\n$gdb_prompt $" {
-	    set allow_btrace_pt_tests 1
-        }
+    set supports_method 2
+    gdb_test_multiple "record btrace ${method}" "check btrace ${method} support" {
+	-re -wrap "You can't do that when your target is.*" {
+	    set supports_method 0
+	}
+	-re -wrap "Target does not support branch tracing.*" {
+	    set supports_method 0
+	}
+	-re -wrap "Could not enable branch tracing.*" {
+	    set supports_method 0
+	}
+	-re -wrap "support was disabled at compile time.*" {
+	    set supports_method 0
+	}
+	-re -wrap "" {
+	    set supports_method 1
+	}
     }
     gdb_exit
     remote_file build delete $obj
 
-    verbose "$me:  returning $allow_btrace_pt_tests" 2
-    return $allow_btrace_pt_tests
+    verbose "$me:  returning $supports_method" 2
+    return $supports_method
 }
 
+# Run a test on the target to see if it supports btrace 'bts' method.  Return
+# 1 if so, 0 if it does not.
+
+gdb_caching_proc allow_btrace_bts_tests {} {
+    return [check_btrace_method_support "bts"]
+}
+
+# Run a test on the target to see if it supports btrace 'pt' method.  Return
+# 1 if so, 0 if it does not.  Based on 'check_vmx_hw_available' from the GCC
+# testsuite.
+
+gdb_caching_proc allow_btrace_pt_tests {} {
+    return [check_btrace_method_support "pt"]
+}
+
+# Wrapper function to check if input btrace method is supported.  Returns 1
+# if it is supported otherwise returns 0.
+
+proc target_supports_btrace {method} {
+    if {[string match "pt" "${method}"]} {
+	return [allow_btrace_pt_tests]
+    } elseif {[string match "bts" "${method}"]} {
+	return [allow_btrace_bts_tests]
+    }
+
+    verbose -log "warning: unknown btrace recording method '${method}'"
+    # Skip test for unknown method name.
+    return 0
+}
+
+
 # Run a test on the target to see if it supports Aarch64 SVE hardware.
 # Return 1 if so, 0 if it does not.  Note this causes a restart of GDB.