diff --git a/gdb/testsuite/Makefile.in b/gdb/testsuite/Makefile.in
index 8d46fe15be..2beba053ee 100644
--- a/gdb/testsuite/Makefile.in
+++ b/gdb/testsuite/Makefile.in
@@ -52,6 +52,7 @@ RUNTESTFLAGS =
 
 FORCE_PARALLEL =
 
+GDB_DEBUG =
 GDBSERVER_DEBUG =
 
 # Default number of iterations that we will use to run the testsuite
@@ -164,15 +165,17 @@ check-read1:
 # status.
 TIMESTAMP = $(if $(TS),| $(srcdir)/print-ts.py $(if $(TS_FORMAT),$(TS_FORMAT),),)
 
+gdb_debug = $(if $(GDB_DEBUG),GDB_DEBUG=$(GDB_DEBUG) ; export GDB_DEBUG ;,)
 gdbserver_debug = $(if $(GDBSERVER_DEBUG),GDBSERVER_DEBUG=$(GDBSERVER_DEBUG) ; export GDBSERVER_DEBUG ;,)
 
+
 # All the hair to invoke dejagnu.  A given invocation can just append
 # $(RUNTESTFLAGS)
 DO_RUNTEST = \
 	rootme=`pwd`; export rootme; \
 	srcdir=${srcdir} ; export srcdir ; \
 	EXPECT=${EXPECT} ; export EXPECT ; \
-	EXEEXT=${EXEEXT} ; export EXEEXT ; $(gdbserver_debug) \
+	EXEEXT=${EXEEXT} ; export EXEEXT ;  $(gdb_debug) $(gdbserver_debug) \
         $(RPATH_ENVVAR)=$$rootme/../../expect:$$rootme/../../libstdc++:$$rootme/../../tk/unix:$$rootme/../../tcl/unix:$$rootme/../../bfd:$$rootme/../../opcodes:$$$(RPATH_ENVVAR); \
 	export $(RPATH_ENVVAR); \
 	if [ -f $${rootme}/../../expect/expect ] ; then  \
diff --git a/gdb/testsuite/README b/gdb/testsuite/README
index 99d574511d..43f35a9d4b 100644
--- a/gdb/testsuite/README
+++ b/gdb/testsuite/README
@@ -293,6 +293,15 @@ can do:
 
 	make check TS=1 TS_FORMAT='[%b %H:%S]'
 
+GDB_DEBUG
+
+When set gdb debug is sent to the file gdb.debug in the test output
+directory.  It should be set to a comma separated list of gdb debug
+components.
+For example, to turn on debugging for infrun and target, you can do:
+
+	make check GDB_DEBUG="infrun,target"
+
 GDBSERVER_DEBUG
 
 When set gdbserver debug is sent to the file gdbserver.debug in the test
@@ -508,6 +517,13 @@ gdb,nopie_flag
   The flag required to force the compiler to produce non-position-independent
   executables.
 
+gdb,debug
+
+  When set gdb debug is sent to the file gdb.debug in the test output
+  directory.  It should be set to a comma separated list of gdb debug
+  components. For example, to turn on debugging for infrun and target, set to
+  "infrun,target".
+
 gdbserver,debug
 
   When set gdbserver debug is sent to the file gdbserver.debug in the test
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index f0f43342e6..c5042ae28f 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -1716,6 +1716,8 @@ proc default_gdb_start { } {
 	    warning "Couldn't set the width to 0."
 	}
     }
+
+    gdb_debug_init
     return 0
 }
 
@@ -6362,6 +6364,58 @@ proc gdb_supported_languages {} {
 		opencl rust minimal ada]
 }
 
+# Check if debugging is enabled for gdb.
+
+proc gdb_debug_enabled { } {
+    global gdbdebug
+
+    # If not already read, get the debug setting from environment or board setting.
+    if {![info exists gdbdebug]} {
+	global env
+	if [info exists env(GDB_DEBUG)] {
+	    set gdbdebug $env(GDB_DEBUG)
+	} elseif [target_info exists gdb,debug] {
+	    set gdbdebug [target_info gdb,debug]
+	} else {
+	    return 0
+	}
+    }
+
+    # Ensure it not empty.
+    return [expr { $gdbdebug != "" }]
+}
+
+# Turn on debugging if enabled, or reset if already on.
+
+proc gdb_debug_init { } {
+
+    global gdb_prompt
+
+    if ![gdb_debug_enabled] {
+      return;
+    }
+
+    # First ensure logging is off.
+    send_gdb "set logging off\n"
+
+    set debugfile [standard_output_file gdb.debug]
+    send_gdb "set logging file $debugfile\n"
+
+    send_gdb "set logging debugredirect\n"
+
+    global gdbdebug
+    foreach entry [split $gdbdebug ,] {
+      send_gdb "set debug $entry 1\n"
+    }
+
+    # Now that everything is set, enable logging.
+    send_gdb "set logging on\n"
+    gdb_expect 10 {
+	-re "Copying output to $debugfile.*Redirecting debug output to $debugfile.*$gdb_prompt $" {}
+	timeout { warning "Couldn't set logging file" }
+    }
+}
+
 # Check if debugging is enabled for gdbserver.
 
 proc gdbserver_debug_enabled { } {
