public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite
@ 2019-05-14 15:12 Alan Hayward
  2019-05-14 15:12 ` [PATCH 1/9] Change file close behavior for tee_file Alan Hayward
                   ` (8 more replies)
  0 siblings, 9 replies; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite

Extended version of a previous series.
This series is intended to help with reproducing tests and extracting debug
information from them.

Firstly, this adds the ability to capture GDB debug when running the testsuite.
For example:
    make check GDB_DEBUG="infrun,remote,serial,jit,frame"
Debug output is saved to gdb.debug in the test directory, along with all of
the gdb output for the test.

Secondly, whenever a test is run, gdb.in and gdb.cmd files will be created
containing the input passed to gdb and the command line used to launch gdb.
This allows a user to quickly rerun a test outside of dejagnu - a script is
added to automate that process too.

Thirdly, GDBSERVER_DEBUG is extended to support the saving of gdbreply output
to a gdbserver.replay file.

I'll do a follow on patch for the NEWS file and look at updating the wiki with
examples.


Alan Hayward (9):
  Change file close behavior for tee_file
  Add debug redirect option
  testsuite: Add option to capture GDB debug
  testsuite: Disable some tests when logging
  testsuite: Record all gdb input to gdb.in
  testsuite: Create .cmd files for gdb and gdbserver
  testsuite: Add replay logging to GDBSERVER_DEBUG
  testsuite: Add script to quickly re-run tests
  testsuite: Remove TRANSCRIPT support

 gdb/cli/cli-interp.c                          |  54 +++--
 gdb/cli/cli-interp.h                          |  16 +-
 gdb/cli/cli-logging.c                         |  45 ++--
 gdb/disasm.c                                  |   4 +-
 gdb/interps.c                                 |   6 +-
 gdb/interps.h                                 |  10 +-
 gdb/mi/mi-common.h                            |  14 +-
 gdb/mi/mi-interp.c                            |  31 ++-
 gdb/testsuite/Makefile.in                     |   5 +-
 gdb/testsuite/README                          |  83 ++++---
 .../gdb.base/breakpoint-in-ro-region.exp      |   6 +
 gdb/testsuite/gdb.base/debug-expr.exp         |   6 +
 gdb/testsuite/gdb.base/foll-fork.exp          |   6 +
 gdb/testsuite/gdb.base/foll-vfork.exp         |   6 +
 .../gdb.base/fork-print-inferior-events.exp   |   6 +
 gdb/testsuite/gdb.base/gdb-sigterm.exp        |   6 +
 gdb/testsuite/gdb.base/gdbinit-history.exp    |   5 +
 gdb/testsuite/gdb.base/osabi.exp              |   6 +
 .../gdb.base/sss-bp-on-user-bp-2.exp          |   6 +
 gdb/testsuite/gdb.base/ui-redirect.exp        |  67 +++++-
 gdb/testsuite/gdb.gdb/unittest.exp            |   6 +
 gdb/testsuite/gdb.mi/mi-break.exp             |   9 +-
 gdb/testsuite/gdb.mi/mi-watch.exp             |   9 +-
 gdb/testsuite/gdb.mi/new-ui-mi-sync.exp       |   5 +
 .../gdb.mi/user-selected-context-sync.exp     |   5 +
 gdb/testsuite/gdb.python/python.exp           |   5 +-
 .../gdb.threads/check-libthread-db.exp        |   6 +
 ...al-while-stepping-over-bp-other-thread.exp |   6 +
 .../gdb.threads/stepi-random-signal.exp       |   6 +
 gdb/testsuite/lib/gdb.exp                     | 217 ++++++++++++------
 gdb/testsuite/lib/gdbserver-support.exp       |  72 +++++-
 gdb/testsuite/replaytest                      | 147 ++++++++++++
 gdb/ui-file.c                                 |  11 +-
 gdb/ui-file.h                                 |  15 +-
 34 files changed, 700 insertions(+), 207 deletions(-)
 create mode 100755 gdb/testsuite/replaytest

-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 3/9] testsuite: Add option to capture GDB debug
  2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
  2019-05-14 15:12 ` [PATCH 1/9] Change file close behavior for tee_file Alan Hayward
@ 2019-05-14 15:12 ` Alan Hayward
  2019-05-16 19:16   ` Tom Tromey
  2019-05-14 15:13 ` [PATCH 7/9] testsuite: Add replay logging to GDBSERVER_DEBUG Alan Hayward
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

Add both board option and environment variable which enables gdb
debug via a comma separated list and sends it to the file gdb.debug,
located in the output directory for the current test.  Document this.

Add support for the environment variable in the Makefile.

The testsuite can be run with gdb debug enabled in the following way:

	make check GDB_DEBUG="infrun,target,remote"

A Test with multiple invocations of GDB will all append debug to the
same log file.

gdb/testsuite/ChangeLog:

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* Makefile.in: Pass through GDB_DEBUG.
	* README (Testsuite Parameters): Add GDB_DEBUG.
        (gdb,debug): Add board setting.
 	* lib/gdb.exp (default_gdb_start): Start debugging.
 	(gdb_debug_enabled): New procedure.
 	(gdb_debug_init): Likewise.
---
 gdb/testsuite/Makefile.in |  5 +++-
 gdb/testsuite/README      | 16 ++++++++++++
 gdb/testsuite/lib/gdb.exp | 54 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/gdb/testsuite/Makefile.in b/gdb/testsuite/Makefile.in
index 8d46fe15be4..2beba053ee6 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 99d574511d2..43f35a9d4bd 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 8dea857d5ed..ba276ac9297 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -1746,6 +1746,8 @@ proc default_gdb_start { } {
 	    warning "Couldn't set the width to 0."
 	}
     }
+
+    gdb_debug_init
     return 0
 }
 
@@ -6409,6 +6411,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 { } {
-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/9] Change file close behavior for tee_file
  2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
@ 2019-05-14 15:12 ` Alan Hayward
  2019-05-16 18:57   ` Tom Tromey
  2019-05-14 15:12 ` [PATCH 3/9] testsuite: Add option to capture GDB debug Alan Hayward
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

Instead of using two bools to decide if the files should close when tee_file
is closed, make file one stay open and file two close.  This simplifies the
use cases for it.

Inline the make_logging_output into the calling functions (the logic here
looks ugly in order to simplify a later change).

Expand ui-redirect.exp to cover the changes, similar to mi-logging.exp.

gdb/ChangeLog:

2019-05-14  Alan Hayward  <alan.hayward@arm.com>
	    Tom Tromey  <tromey@adacore.com>

	* cli/cli-interp.c (cli_interp_base::set_logging): Create tee_file
	directly.
	* cli/cli-interp.h (make_logging_output): Remove declaration.
	* cli/cli-logging.c (make_logging_output): Remove function.
	* mi/mi-interp.c (mi_interp::set_logging): Create tee_file
	directly.
	* ui-file.c (tee_file::tee_file): Remove bools.
	(tee_file::~tee_file): Remove deletes.
	* ui-file.h (tee_file): Remove bools.

gdb/testsuite/ChangeLog:

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* gdb.base/ui-redirect.exp: Test redirection.
---
 gdb/cli/cli-interp.c                   | 38 +++++++++++++++-----------
 gdb/cli/cli-interp.h                   | 13 ---------
 gdb/cli/cli-logging.c                  | 18 ------------
 gdb/mi/mi-interp.c                     | 19 +++++++++----
 gdb/testsuite/gdb.base/ui-redirect.exp | 30 ++++++++++++++++----
 gdb/ui-file.c                          | 11 ++------
 gdb/ui-file.h                          | 15 ++++------
 7 files changed, 69 insertions(+), 75 deletions(-)

diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index fc4b39a9c2a..7876f910806 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -403,7 +403,7 @@ static saved_output_files saved_output;
 void
 cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
 {
-  if (logfile != NULL)
+  if (logfile != nullptr)
     {
       saved_output.out = gdb_stdout;
       saved_output.err = gdb_stderr;
@@ -411,16 +411,22 @@ cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
       saved_output.targ = gdb_stdtarg;
       saved_output.targerr = gdb_stdtargerr;
 
-      /* A raw pointer since ownership is transferred to
-	 gdb_stdout.  */
-      ui_file *output = make_logging_output (gdb_stdout,
-					     std::move (logfile),
-					     logging_redirect);
-      gdb_stdout = output;
-      gdb_stdlog = output;
-      gdb_stderr = output;
-      gdb_stdtarg = output;
-      gdb_stdtargerr = output;
+      /* If logging is being redirected, then grab logfile.  */
+      ui_file *logfile_p = nullptr;
+      if (logging_redirect)
+	logfile_p = logfile.release ();
+
+      /* If logging is not being redirected, then a tee containing both the
+	 logfile and stdout.  */
+      ui_file *tee = nullptr;
+      if (!logging_redirect)
+	tee = new tee_file (gdb_stdout, std::move (logfile));
+
+      gdb_stdout = logging_redirect ? logfile_p : tee;
+      gdb_stdlog = logging_redirect ? logfile_p : tee;
+      gdb_stderr = logging_redirect ? logfile_p : tee;
+      gdb_stdtarg = logging_redirect ? logfile_p : tee;
+      gdb_stdtargerr = logging_redirect ? logfile_p : tee;
     }
   else
     {
@@ -434,11 +440,11 @@ cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
       gdb_stdtarg = saved_output.targ;
       gdb_stdtargerr = saved_output.targerr;
 
-      saved_output.out = NULL;
-      saved_output.err = NULL;
-      saved_output.log = NULL;
-      saved_output.targ = NULL;
-      saved_output.targerr = NULL;
+      saved_output.out = nullptr;
+      saved_output.err = nullptr;
+      saved_output.log = nullptr;
+      saved_output.targ = nullptr;
+      saved_output.targerr = nullptr;
     }
 }
 
diff --git a/gdb/cli/cli-interp.h b/gdb/cli/cli-interp.h
index 77d73a23d04..0c2e73b6b38 100644
--- a/gdb/cli/cli-interp.h
+++ b/gdb/cli/cli-interp.h
@@ -33,19 +33,6 @@ public:
   bool supports_command_editing () override;
 };
 
-/* Make the output ui_file to use when logging is enabled.
-   CURR_OUTPUT is the stream where output is currently being sent to
-   (e.g., gdb_stdout for the CLI, raw output stream for the MI).
-   LOGFILE is the log file already opened by the caller.
-   LOGGING_REDIRECT is the value of the "set logging redirect"
-   setting.  If true, the resulting output is the logfile.  If false,
-   the output stream is a tee, with the log file as one of the
-   outputs.  Ownership of LOGFILE is transferred to the returned
-   output file, which is an owning pointer.  */
-extern ui_file *make_logging_output (ui_file *curr_output,
-				     ui_file_up logfile,
-				     bool logging_redirect);
-
 /* The CLI interpreter's set_logging_proc method.  Exported so other
    interpreters can reuse it.  */
 extern void cli_set_logging (struct interp *interp,
diff --git a/gdb/cli/cli-logging.c b/gdb/cli/cli-logging.c
index 3a5e14de3c7..670e7e24908 100644
--- a/gdb/cli/cli-logging.c
+++ b/gdb/cli/cli-logging.c
@@ -88,24 +88,6 @@ pop_output_files (void)
     current_uiout->redirect (NULL);
 }
 
-/* See cli-interp.h.  */
-
-ui_file *
-make_logging_output (ui_file *curr_output, ui_file_up logfile,
-		     bool logging_redirect)
-{
-  if (logging_redirect)
-    return logfile.release ();
-  else
-    {
-      /* Note that the "tee" takes ownership of the log file.  */
-      ui_file *out = new tee_file (curr_output, false,
-				   logfile.get (), true);
-      logfile.release ();
-      return out;
-    }
-}
-
 /* This is a helper for the `set logging' command.  */
 static void
 handle_redirections (int from_tty)
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index 4568d398d94..6a19bf02476 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -1286,18 +1286,27 @@ mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)
   if (logfile != NULL)
     {
       mi->saved_raw_stdout = mi->raw_stdout;
-      mi->raw_stdout = make_logging_output (mi->raw_stdout,
-					    std::move (logfile),
-					    logging_redirect);
 
+      /* If something is being redirected, then grab logfile.  */
+      ui_file *logfile_p = nullptr;
+      if (logging_redirect)
+	logfile_p = logfile.release ();
+
+      /* If something is not being redirected, then a tee containing both the
+	 logfile and stdout.  */
+      ui_file *tee = nullptr;
+      if (!logging_redirect)
+	tee = new tee_file (mi->raw_stdout, std::move (logfile));
+
+      mi->raw_stdout = logging_redirect ? logfile_p : tee;
     }
   else
     {
       delete mi->raw_stdout;
       mi->raw_stdout = mi->saved_raw_stdout;
-      mi->saved_raw_stdout = NULL;
+      mi->saved_raw_stdout = nullptr;
     }
-  
+
   mi->out->set_raw (mi->raw_stdout);
   mi->err->set_raw (mi->raw_stdout);
   mi->log->set_raw (mi->raw_stdout);
diff --git a/gdb/testsuite/gdb.base/ui-redirect.exp b/gdb/testsuite/gdb.base/ui-redirect.exp
index 1ebff790e57..f1d00b939da 100644
--- a/gdb/testsuite/gdb.base/ui-redirect.exp
+++ b/gdb/testsuite/gdb.base/ui-redirect.exp
@@ -34,8 +34,28 @@ gdb_test_multiple $test $test {
 }
 gdb_test_no_output "end"
 
-gdb_test_no_output "set logging file /dev/null"
-gdb_test "set logging on" "Copying output to /dev/null\\."
-gdb_test "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
-gdb_test "set logging off" "Done logging to /dev/null\\."
-gdb_test "help" "List of classes of commands:.*"
+with_test_prefix "logging" {
+    gdb_test_no_output "set logging file /dev/null"
+    gdb_test "set logging on" "Copying output to /dev/null\\."
+    gdb_test "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
+    gdb_test "set logging off" "Done logging to /dev/null\\."
+    gdb_test "help" "List of classes of commands:.*"
+}
+
+with_test_prefix "redirect" {
+    gdb_test "set logging redirect on"
+    gdb_test "set logging on" "Redirecting output to /dev/null\\."
+    gdb_test_no_output "save breakpoints /dev/null"
+    gdb_test "set logging off" "Done logging to /dev/null\\."
+    gdb_test "help" "List of classes of commands:.*"
+}
+
+with_test_prefix "redirect while already logging" {
+    gdb_test_no_output "set logging redirect off"
+    gdb_test "set logging on" "Copying output to /dev/null\\."
+    gdb_test "set logging redirect on" \
+    ".*warning: Currently logging .*Turn the logging off and on to make the new setting effective.*"
+    gdb_test "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
+    gdb_test "set logging off" "Done logging to /dev/null\\."
+    gdb_test "help" "List of classes of commands:.*"
+}
diff --git a/gdb/ui-file.c b/gdb/ui-file.c
index 4139b5deffc..24c914f442a 100644
--- a/gdb/ui-file.c
+++ b/gdb/ui-file.c
@@ -336,20 +336,13 @@ stderr_file::stderr_file (FILE *stream)
 
 \f
 
-tee_file::tee_file (ui_file *one, bool close_one,
-		    ui_file *two, bool close_two)
+tee_file::tee_file (ui_file *one, ui_file_up &&two)
   : m_one (one),
-    m_two (two),
-    m_close_one (close_one),
-    m_close_two (close_two)
+    m_two (std::move (two))
 {}
 
 tee_file::~tee_file ()
 {
-  if (m_close_one)
-    delete m_one;
-  if (m_close_two)
-    delete m_two;
 }
 
 void
diff --git a/gdb/ui-file.h b/gdb/ui-file.h
index 56f0c0f957c..39f56d5ea42 100644
--- a/gdb/ui-file.h
+++ b/gdb/ui-file.h
@@ -267,11 +267,9 @@ public:
 class tee_file : public ui_file
 {
 public:
-  /* Create a file which writes to both ONE and TWO.  CLOSE_ONE and
-     CLOSE_TWO indicate whether the original files should be closed
-     when the new file is closed.  */
-  tee_file (ui_file *one, bool close_one,
-	    ui_file *two, bool close_two);
+  /* Create a file which writes to both ONE and TWO.  ONE will remain
+     open when this object is destroyed; but TWO will be closed.  */
+  tee_file (ui_file *one, ui_file_up &&two);
   ~tee_file () override;
 
   void write (const char *buf, long length_buf) override;
@@ -284,10 +282,9 @@ public:
   void flush () override;
 
 private:
-  /* The two underlying ui_files, and whether they should each be
-     closed on destruction.  */
-  ui_file *m_one, *m_two;
-  bool m_close_one, m_close_two;
+  /* The two underlying ui_files.  */
+  ui_file *m_one;
+  ui_file_up m_two;
 };
 
 #endif
-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 6/9] testsuite: Create .cmd files for gdb and gdbserver
  2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
                   ` (6 preceding siblings ...)
  2019-05-14 15:13 ` [PATCH 5/9] testsuite: Record all gdb input to gdb.in Alan Hayward
@ 2019-05-14 15:13 ` Alan Hayward
  2019-05-16 19:28   ` Tom Tromey
  2019-05-14 15:13 ` [PATCH 9/9] testsuite: Remove TRANSCRIPT support Alan Hayward
  8 siblings, 1 reply; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

When spawning gdb or gdbserver create a .cmd file in the test output
directory containing the full command line, ensuring the current gdb
instance is appened to the files so that they can be quickly matched
to the corresponding gdb.in file.

gdb/testsuite/ChangeLog:

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* lib/gdb.exp (default_gdb_spawn): Call gdb_write_cmd_file.
	(gdb_write_cmd_file): New procedure.
	* lib/gdbserver-support.exp (gdbserver_start): Call
	gdbserver_write_cmd_file.
	(gdbserver_write_cmd_file): New proedure.
---
 gdb/testsuite/lib/gdb.exp               | 10 ++++++++++
 gdb/testsuite/lib/gdbserver-support.exp | 11 +++++++++++
 2 files changed, 21 insertions(+)

diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 3815f86ffc8..cbf8d29ec12 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -1664,6 +1664,7 @@ proc default_gdb_spawn { } {
     set use_gdb_stub [target_info exists use_gdb_stub]
 
     verbose "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS"
+    gdb_write_cmd_file "$GDB $INTERNAL_GDBFLAGS $GDBFLAGS"
 
     if [info exists gdb_spawn_id] {
 	return 0
@@ -6540,5 +6541,14 @@ proc gdb_stdin_log_write { message {type standard} } {
     puts -nonewline $in_file "$message"
 }
 
+# Write the command line used to invocate gdb to the cmd file.
+
+proc gdb_write_cmd_file { cmdline } {
+    set logfile [standard_output_file_with_gdb_instance gdb.cmd]
+    set cmd_file [open $logfile w]
+    puts $cmd_file $cmdline
+    catch "close $cmd_file"
+}
+
 # Always load compatibility stuff.
 load_lib future.exp
diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp
index 164a1d1d3cd..54aa55771c1 100644
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -319,6 +319,8 @@ proc gdbserver_start { options arguments } {
 	    append gdbserver_command " $arguments"
 	}
 
+	gdbserver_write_cmd_file $gdbserver_command
+
 	global server_spawn_id
 	set server_spawn_id [remote_spawn target $gdbserver_command]
 
@@ -597,3 +599,12 @@ proc gdbserver_debug_enabled { } {
     return [expr { $gdbserverdebug == "debug" || $gdbserverdebug == "remote"
 		   || $gdbserverdebug == "all" }]
 }
+
+# Write the command line used to invocate gdbserver to the cmd file.
+
+proc gdbserver_write_cmd_file { cmdline } {
+    set logfile [standard_output_file_with_gdb_instance gdbserver.cmd]
+    set cmd_file [open $logfile w]
+    puts $cmd_file $cmdline
+    catch "close $cmd_file"
+}
-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 7/9] testsuite: Add replay logging to GDBSERVER_DEBUG
  2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
  2019-05-14 15:12 ` [PATCH 1/9] Change file close behavior for tee_file Alan Hayward
  2019-05-14 15:12 ` [PATCH 3/9] testsuite: Add option to capture GDB debug Alan Hayward
@ 2019-05-14 15:13 ` Alan Hayward
  2019-05-16 19:34   ` Tom Tromey
  2019-05-14 15:13 ` [PATCH 4/9] testsuite: Disable some tests when logging Alan Hayward
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

Add "replay" to the list of GDBSERVER_DEBUG options.  This will
cause a gdbserver.replay file to be written to the test output
directory.

At the same time switch this to a comma separated list in order
to easily handle all possible options.

The replay log is created by GDB, but has been added to
GDBSERVER_DEBUG as it is only required for gdbserver tests. To
enable it, the gdb_debug_init is overridden to allow the additional
checking, before calling the original function.

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

        * README (Testsuite Parameters): Add replay logging to
        GDBSERVER_DEBUG.
        (gdbserver,debug): Refer to GDBSERVER_DEBUG.
        * lib/gdbserver-support.exp (gdbserver_start): Treat gdbserverdebug
        as a comma separated list.
        (gdb_debug_init): Override procedure.
---
 gdb/testsuite/README                    | 21 +++++----
 gdb/testsuite/lib/gdbserver-support.exp | 59 ++++++++++++++++++++-----
 2 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/gdb/testsuite/README b/gdb/testsuite/README
index 43f35a9d4bd..98fc8d1b852 100644
--- a/gdb/testsuite/README
+++ b/gdb/testsuite/README
@@ -304,14 +304,16 @@ For example, to turn on debugging for infrun and target, you can do:
 
 GDBSERVER_DEBUG
 
-When set gdbserver debug is sent to the file gdbserver.debug in the test
-output directory.  Valid values are:
-	debug  - turn on gdbserver debug.
-	remote - turn on gdbserver remote debug.
-	all - turn on all the above debug options.
-For example, to turn on all gdbserver debugging, you can do:
+When set gdbserver debug is sent to the a file in the test output directory.
+It should be set to a comma separated list of the following options:
+	debug  - write gdbserver debug to gdbserver.debug.
+	remote - write gdbserver remote debug to gdbserver.debug.
+	replay - write a replay log to the file gdbserver.replay for use
+		 with gdbreplay.
+Alternatively, it can be set to "all" to turn on all the above
+For example, to turn on gdbserver debugging, you can do:
 
-	make check GDBSERVER_DEBUG=all
+	make check GDBSERVER_DEBUG="debug,replay"
 
 Race detection
 **************
@@ -527,10 +529,7 @@ gdb,debug
 gdbserver,debug
 
   When set gdbserver debug is sent to the file gdbserver.debug in the test
-  output directory.  Valid values are:
-  "debug"  - turn on gdbserver debug.
-  "remote" - turn on gdbserver remote debug.
-  "all" - turn on all the above debug options.
+  output directory.  For valid values see the entry for GDBSERVER_DEBUG.
 
 Testsuite Organization
 **********************
diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp
index 54aa55771c1..2ccc717ef60 100644
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -293,13 +293,23 @@ proc gdbserver_start { options arguments } {
 	# Enable debug if set.
 	if [gdbserver_debug_enabled] {
 	    global gdbserverdebug
-	    set debugfile [standard_output_file gdbserver.debug]
-	    if { $gdbserverdebug == "debug" } {
-		append gdbserver_command " --debug --debug-file=$debugfile"
-	    } elseif { $gdbserverdebug == "remote" } {
-		append gdbserver_command " --remote-debug --debug-file=$debugfile"
-	    } elseif { $gdbserverdebug == "all" } {
-		append gdbserver_command " --debug --remote-debug --debug-file=$debugfile"
+	    set enabled 0
+	    foreach entry [split $gdbserverdebug ,] {
+	      switch -- $entry {
+		"debug" {
+		  append gdbserver_command " --debug"
+		  set enabled 1
+		}
+		"remote" {
+		  append gdbserver_command " --remote-debug"
+		  set enabled 1
+		}
+	      }
+	    }
+	    # Ensure debugfile is only added if something has been enabled
+	    if { $enabled } {
+	      set debugfile [standard_output_file gdbserver.debug]
+	      append gdbserver_command " --debug-file=$debugfile"
 	    }
 	}
 
@@ -595,9 +605,13 @@ proc gdbserver_debug_enabled { } {
 	}
     }
 
-    # Only return success on valid values.
-    return [expr { $gdbserverdebug == "debug" || $gdbserverdebug == "remote"
-		   || $gdbserverdebug == "all" }]
+    # Expand the all option
+    if { $gdbserverdebug == "all" } {
+      set gdbserverdebug "debug,remote,replay"
+    }
+
+    # Ensure it is not empty.
+    return [expr { $gdbserverdebug != "" }]
 }
 
 # Write the command line used to invocate gdbserver to the cmd file.
@@ -608,3 +622,28 @@ proc gdbserver_write_cmd_file { cmdline } {
     puts $cmd_file $cmdline
     catch "close $cmd_file"
 }
+
+# Override gdb_debug_init so that we can set replay logging in GDB if required.
+# Backup the original function so we can call it afterwards
+
+rename gdb_debug_init _gdb_debug_init
+
+proc gdb_debug_init { } {
+    global gdbserverdebug
+    global gdb_prompt
+
+    if [gdbserver_debug_enabled] {
+      foreach entry [split $gdbserverdebug ,] {
+	if { $entry == "replay" } {
+	  set replayfile [standard_output_file_with_gdb_instance gdbserver.replay]
+          send_gdb "set remotelogfile $replayfile\n" optional
+	  gdb_expect 10 {
+	    -re "$gdb_prompt $" {}
+	  }
+	}
+      }
+    }
+
+    # Now call the standard debug init function
+    _gdb_debug_init
+}
-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 8/9] testsuite: Add script to quickly re-run tests
  2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
                   ` (3 preceding siblings ...)
  2019-05-14 15:13 ` [PATCH 4/9] testsuite: Disable some tests when logging Alan Hayward
@ 2019-05-14 15:13 ` Alan Hayward
  2019-05-14 15:13 ` [PATCH 2/9] Add debug redirect option Alan Hayward
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

Using the .cmd and .in files created by a test it is fairly simple
to manually re-run a test.  For gdbserver tests, the .replay log
can also be used.

Document the process required to do this.

In addition create a script to automate the process.

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* README (Re-running Tests Outside The Testsuite): New section.
	* lib/gdbserver-support.exp (gdbserver_run): Mark kill as optional.
	* replaytest: New test.
---
 gdb/testsuite/README                    |  23 ++++
 gdb/testsuite/lib/gdbserver-support.exp |   2 +-
 gdb/testsuite/replaytest                | 147 ++++++++++++++++++++++++
 3 files changed, 171 insertions(+), 1 deletion(-)
 create mode 100755 gdb/testsuite/replaytest

diff --git a/gdb/testsuite/README b/gdb/testsuite/README
index 98fc8d1b852..b5fbb456bee 100644
--- a/gdb/testsuite/README
+++ b/gdb/testsuite/README
@@ -95,6 +95,29 @@ example:
 
 The script will output its analysis report to the standard output.
 
+Re-running Tests Outside The Testsuite
+**************************************
+
+When running a test, the arguments used to run GDB are saved to gdb.cmd
+and any commands sent to GDB are saved to gdb.in.  As well as being a
+reference of the commands run, they can be used to manually re-run a test
+by giving the .in file as a batch file to a GDB launched with the arguments
+in the .cmd file.  For many tests you can use just the .in file:
+	$ gdb -x gdb.in
+
+Tests that run GDB multiple times will append .1, .2, .3 etc to the end
+of each .cmd and .in file.
+
+For tests requiring gdbserver, this can by executing the contents of
+gdbserver.cmd.  Alternatively, the gdbserver.replay file (created when
+running the test with GDBSERVER_DEBUG="replay") can be used with the
+gdbreplay test.
+
+This process can be automated with the "replaytest" script.
+For example:
+	$ replaytest gdb testsuite/outputs/gdb.base/store
+For more details see the documentation in the script.
+
 Running the Performance Tests
 *****************************
 
diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp
index 2ccc717ef60..ade99c0ea16 100644
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -484,7 +484,7 @@ proc gdbserver_run { child_args } {
     # Kill anything running before we try to start gdbserver, in case
     # we are sharing a serial connection.
     global gdb_prompt
-    send_gdb "kill\n"
+    send_gdb "kill\n" optional
     gdb_expect 120 {
 	-re "Kill the program being debugged. .y or n. $" {
 	    send_gdb "y\n"
diff --git a/gdb/testsuite/replaytest b/gdb/testsuite/replaytest
new file mode 100755
index 00000000000..4c11d9735f3
--- /dev/null
+++ b/gdb/testsuite/replaytest
@@ -0,0 +1,147 @@
+#!/bin/bash
+
+# Copyright (C) 2019 Free Software Foundation, Inc.
+#
+# This file is part of GDB.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#
+# This script uses GDB to replay previously run tests using the .in and
+# .cmd files from the output directory of a test.
+#
+# For example:
+#    $ replaytest gdb testsuite/outputs/gdb.base/store
+#
+#
+# For tests that have been runing using gdbserver (for example with
+# board file native-gdbserver), the test script should be run in two
+# terminals, using gdbserver and gdb modes.
+#
+# For example, in two different terminals:
+#    $ replaytest -b gdbserver testsuite/outputs/gdb.base/store
+#    $ replaytest -b gdb testsuite/outputs/gdb.base/store
+#
+# Alternatively, instead of running gdbserver, the gdbreplay tool can
+# be used instead. This uses the .replay file which is created when the
+# test is run with GDBSERVER_DEBUG="replay". gdbreplay must be in your
+# $PATH.
+#
+#
+# Tests that run GDB (and gdbserver) multiple times will create .1, .2
+# .3 etc files for each instance of GDB.  You can run a specified
+# instance using the -i flag
+#
+# For example:
+#    $ replaytest -b -i 23 gdb testsuite/outputs/gdb.base/infcall-nested-structs
+#
+# Note that to successfully run to the end of the test, the .in file must be
+# free from the answers to any interactive gdb prompts (for example the y from
+# a y/n question) or any command that causes gdb to report an error.
+#
+#
+# Usage: replaytest [-b] [-i instance] [-e] {gdb|gdbserver|replay} test_output_dir
+#
+#    -b : Run GDB in batch mode (ie: exit GDB at the end of the test).
+#    -i : Run the given instance of the test. Defaults to 0.
+#    -e : Don't run the test, just echo the command line instead.
+#
+#    test_output_dir : Directory containing all the test output files.
+#
+
+usage()
+{
+  echo "$0 [-b] [-i instance] [-e] {gdb|gdbserver|replay} test_output_dir"
+  exit 2
+}
+
+# Check file $1 exists, using test operator $2 (defaults to -e).
+check_exists()
+{
+  if [ ! ${2:-"-e"} "${1}" ]; then echo Error: Cannot find $1; exit 2; fi
+}
+
+# Run the given command in $1...n
+execute()
+{
+  if [ -n "$ECHO" ]
+  then
+    echo $@
+  else
+    # Pipe the command we want to run to a file then execute the file.  This
+    # ensures spaces within quoatation marks args get interpreted correctly.
+    OUTFILE=$(mktemp)
+    echo $@ > ${OUTFILE}
+    bash ${OUTFILE}
+    rm ${OUTFILE}
+  fi
+}
+
+# Parse command line
+while getopts bi:e line
+do
+  case $line in
+  b) EXTRA_GDBCMD="${EXTRA_GDBCMD} --batch";;
+  i) INSTANCE=".$OPTARG";;
+  e) ECHO=1;;
+  *) usage;;
+  esac
+done
+shift $(($OPTIND - 1))
+if [[ $# -ne 2 ]]; then usage; fi;
+MODE=$1
+TESTDIR=$2
+check_exists ${TESTDIR} -d
+
+
+case $MODE in
+
+"gdb") 
+  # Run the .in file through GDB by appending it to the end of the .cmd contents.
+  CMDFILE=${TESTDIR}/gdb.cmd${INSTANCE}
+  INFILE=${TESTDIR}/gdb.in${INSTANCE}
+  check_exists ${CMDFILE}
+  check_exists ${INFILE}
+  execute "$(cat $CMDFILE) ${EXTRA_GDBCMD} -x ${INFILE}"
+  ;;
+
+"gdbserver") 
+  # Run gdbserver using the .cmd file.
+  GDBSERVER_CMDFILE=${TESTDIR}/gdbserver.cmd${INSTANCE}
+  check_exists ${GDBSERVER_CMDFILE}
+  execute $(cat $GDBSERVER_CMDFILE)
+  ;;
+
+"replay") 
+  GDBSERVER_REPLAYFILE=${TESTDIR}/gdbserver.replay${INSTANCE}
+  check_exists ${GDBSERVER_REPLAYFILE}
+
+  # Extract the connection from the .cmd file.
+  GDBSERVER_CMDFILE=${TESTDIR}/gdbserver.cmd${INSTANCE}
+  check_exists ${GDBSERVER_CMDFILE}
+  GDBSERVER_HOST=$(grep -o '[^ ]*:[^ ]*' ${GDBSERVER_CMDFILE})
+
+  # Run the .replay file through gdbreplay.
+  execute gdbreplay ${GDBSERVER_REPLAYFILE} ${GDBSERVER_HOST}
+  ;;
+
+*)
+  echo "Unknown mode $MODE"
+  usage
+  ;;
+
+esac
+
+
+
-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 4/9] testsuite: Disable some tests when logging
  2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
                   ` (2 preceding siblings ...)
  2019-05-14 15:13 ` [PATCH 7/9] testsuite: Add replay logging to GDBSERVER_DEBUG Alan Hayward
@ 2019-05-14 15:13 ` Alan Hayward
  2019-05-16 19:19   ` Tom Tromey
  2019-05-14 15:13 ` [PATCH 8/9] testsuite: Add script to quickly re-run tests Alan Hayward
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

Fix up all failures encountered when running the testsuite with
GDB_DEBUG="infrun".

Some tests rely on enabling debugging for various components.  With
debugging on, this will be lost to the debug file.

Disable separate tty for mi tests when debugging.  This currently
does not work.

disasm.c should send errors to the stderr instead of the logfile.

Note that enabling debug for other components might still cause
additional errors above what has been fixed here.

gdb/ChangeLog:

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* disasm.c (set_disassembler_options): Send errors to stderr.

gdb/testsuite/ChangeLog:

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* gdb.base/breakpoint-in-ro-region.exp: Disable when debugging.
	* gdb.base/debug-expr.exp: Likewise.
	* gdb.base/foll-fork.exp: Likewise.
	* gdb.base/foll-vfork.exp: Likewise.
	* gdb.base/fork-print-inferior-events.exp: Likewise.
	* gdb.base/gdb-sigterm.exp: Likewise.
	* gdb.base/gdbinit-history.exp: Likewise.
	* gdb.base/osabi.exp: Likewise.
	* gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
	* gdb.base/ui-redirect.exp: Likewise.
	* gdb.gdb/unittest.exp: Likewise.
	* gdb.mi/mi-break.exp: Disable separate-mi-tty when debugging.
	* gdb.mi/mi-watch.exp: Likewise.
	* gdb.mi/new-ui-mi-sync.exp: Likewise.
	* gdb.mi/user-selected-context-sync.exp: Likewise.
	* gdb.python/python.exp: Disable debug test when debugging.
	* gdb.threads/check-libthread-db.exp: Disable when debugging.
	* gdb.threads/signal-while-stepping-over-bp-other-thread.exp:
	Likewise.
	* gdb.threads/stepi-random-signal.exp: Likewise.
---
 gdb/disasm.c                                             | 4 ++--
 gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp       | 6 ++++++
 gdb/testsuite/gdb.base/debug-expr.exp                    | 6 ++++++
 gdb/testsuite/gdb.base/foll-fork.exp                     | 6 ++++++
 gdb/testsuite/gdb.base/foll-vfork.exp                    | 6 ++++++
 gdb/testsuite/gdb.base/fork-print-inferior-events.exp    | 6 ++++++
 gdb/testsuite/gdb.base/gdb-sigterm.exp                   | 6 ++++++
 gdb/testsuite/gdb.base/gdbinit-history.exp               | 5 +++++
 gdb/testsuite/gdb.base/osabi.exp                         | 6 ++++++
 gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp           | 6 ++++++
 gdb/testsuite/gdb.base/ui-redirect.exp                   | 5 +++++
 gdb/testsuite/gdb.gdb/unittest.exp                       | 6 ++++++
 gdb/testsuite/gdb.mi/mi-break.exp                        | 9 ++++++++-
 gdb/testsuite/gdb.mi/mi-watch.exp                        | 9 ++++++++-
 gdb/testsuite/gdb.mi/new-ui-mi-sync.exp                  | 5 +++++
 gdb/testsuite/gdb.mi/user-selected-context-sync.exp      | 5 +++++
 gdb/testsuite/gdb.python/python.exp                      | 5 ++++-
 gdb/testsuite/gdb.threads/check-libthread-db.exp         | 6 ++++++
 .../signal-while-stepping-over-bp-other-thread.exp       | 6 ++++++
 gdb/testsuite/gdb.threads/stepi-random-signal.exp        | 6 ++++++
 20 files changed, 114 insertions(+), 5 deletions(-)

diff --git a/gdb/disasm.c b/gdb/disasm.c
index 7c7a148935e..ed740c26e0f 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -943,7 +943,7 @@ set_disassembler_options (char *prospective_options)
   valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch);
   if (valid_options_and_args == NULL)
     {
-      fprintf_filtered (gdb_stdlog, _("\
+      fprintf_filtered (gdb_stderr, _("\
 'set disassembler-options ...' is not supported on this architecture.\n"));
       return;
     }
@@ -979,7 +979,7 @@ set_disassembler_options (char *prospective_options)
 	  break;
       if (valid_options->name[i] == NULL)
 	{
-	  fprintf_filtered (gdb_stdlog,
+	  fprintf_filtered (gdb_stderr,
 			    _("Invalid disassembler option value: '%s'.\n"),
 			    opt);
 	  return;
diff --git a/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp b/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
index 8655f54e038..a54d712f088 100644
--- a/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
+++ b/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
@@ -15,6 +15,12 @@
 
 # This file is part of the gdb testsuite
 
+# Test relies on checking gdb debug ouput. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 
 if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
diff --git a/gdb/testsuite/gdb.base/debug-expr.exp b/gdb/testsuite/gdb.base/debug-expr.exp
index 8885ec6b9b0..80bb75851e3 100644
--- a/gdb/testsuite/gdb.base/debug-expr.exp
+++ b/gdb/testsuite/gdb.base/debug-expr.exp
@@ -15,6 +15,12 @@
 
 # Test "set debug expr 1" on c expressions.
 
+# Test relies on checking gdb debug ouput. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    return 0
+}
+
 standard_testfile .c
 
 if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} {
diff --git a/gdb/testsuite/gdb.base/foll-fork.exp b/gdb/testsuite/gdb.base/foll-fork.exp
index 8884686928d..3befabbbf6c 100644
--- a/gdb/testsuite/gdb.base/foll-fork.exp
+++ b/gdb/testsuite/gdb.base/foll-fork.exp
@@ -20,6 +20,12 @@ if { ![istarget "*-*-linux*"] && ![istarget "*-*-openbsd*"] } then {
     continue
 }
 
+# Test relies on checking follow-fork ouput. Do not run if gdb debug is
+# enabled as it will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 
 if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp
index 96d8539bee8..ae0441d6a51 100644
--- a/gdb/testsuite/gdb.base/foll-vfork.exp
+++ b/gdb/testsuite/gdb.base/foll-vfork.exp
@@ -25,6 +25,12 @@ if {![istarget "*-linux*"]} then {
     continue
 }
 
+# Test relies on checking follow-fork ouput. Do not run if gdb debug is
+# enabled as it will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 
 set compile_options debug
diff --git a/gdb/testsuite/gdb.base/fork-print-inferior-events.exp b/gdb/testsuite/gdb.base/fork-print-inferior-events.exp
index 1c5a470bd6b..33f80eafb35 100644
--- a/gdb/testsuite/gdb.base/fork-print-inferior-events.exp
+++ b/gdb/testsuite/gdb.base/fork-print-inferior-events.exp
@@ -25,6 +25,12 @@ if { [use_gdb_stub] } {
     return
 }
 
+# Test relies on checking follow-fork ouput. Do not run if gdb debug is
+# enabled as it will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 
 if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {
diff --git a/gdb/testsuite/gdb.base/gdb-sigterm.exp b/gdb/testsuite/gdb.base/gdb-sigterm.exp
index 36d24fcc562..44fbbdc38a9 100644
--- a/gdb/testsuite/gdb.base/gdb-sigterm.exp
+++ b/gdb/testsuite/gdb.base/gdb-sigterm.exp
@@ -15,6 +15,12 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+# Test relies on checking gdb debug ouput. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 
 # The test program exits after a while, in case GDB crashes.  Make it
diff --git a/gdb/testsuite/gdb.base/gdbinit-history.exp b/gdb/testsuite/gdb.base/gdbinit-history.exp
index f4f0686ccc1..8710010cf7c 100644
--- a/gdb/testsuite/gdb.base/gdbinit-history.exp
+++ b/gdb/testsuite/gdb.base/gdbinit-history.exp
@@ -21,6 +21,11 @@
 # We cannot expect remote hosts to see environment variables set on the
 # local machine.
 
+# Do not run if gdb debug is enabled - it interferes with the command history.
+if [gdb_debug_enabled] {
+    continue
+}
+
 if { [is_remote host] } {
     unsupported "can't set environment variables on remote host"
     return -1
diff --git a/gdb/testsuite/gdb.base/osabi.exp b/gdb/testsuite/gdb.base/osabi.exp
index 50146311f7e..ed94ecf4ecc 100644
--- a/gdb/testsuite/gdb.base/osabi.exp
+++ b/gdb/testsuite/gdb.base/osabi.exp
@@ -15,6 +15,12 @@
 
 # This file is part of the gdb testsuite.
 
+# Test relies on checking gdb debug ouput. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 # Test that choosing "set osabi none" really requests a gdbarch with no osabi.
 
 proc test_set_osabi_none { } {
diff --git a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
index 898233afa44..b07a8fffbf1 100644
--- a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
+++ b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
@@ -31,6 +31,12 @@
 # 4 - The single-step finishes, and GDB removes the single-step
 #     breakpoint.
 
+# Test relies on checking gdb debug ouput. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 
 if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
diff --git a/gdb/testsuite/gdb.base/ui-redirect.exp b/gdb/testsuite/gdb.base/ui-redirect.exp
index e62d5e8341c..55bd495267c 100644
--- a/gdb/testsuite/gdb.base/ui-redirect.exp
+++ b/gdb/testsuite/gdb.base/ui-redirect.exp
@@ -13,6 +13,11 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+# Do not run if gdb debug is enabled as it will interfere with log redirect.
+if [gdb_debug_enabled] {
+    return 0
+}
+
 if { [prepare_for_testing "failed to prepare" ui-redirect start.c] } {
     return -1
 }
diff --git a/gdb/testsuite/gdb.gdb/unittest.exp b/gdb/testsuite/gdb.gdb/unittest.exp
index 09c603059f2..6f1f29a03f1 100644
--- a/gdb/testsuite/gdb.gdb/unittest.exp
+++ b/gdb/testsuite/gdb.gdb/unittest.exp
@@ -13,6 +13,12 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+# Do not run if gdb debug is enabled as maintenance output will be
+# redirected to the log files.
+if [gdb_debug_enabled] {
+    continue
+}
+
 set do_xml_test [expr ![gdb_skip_xml_test]]
 
 gdb_start
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
index 365e4faa81d..c517ce886fa 100644
--- a/gdb/testsuite/gdb.mi/mi-break.exp
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -429,6 +429,13 @@ proc test_break {mi_mode} {
     test_explicit_breakpoints
 }
 
-foreach_with_prefix mi-mode {"main" "separate"} {
+if [gdb_debug_enabled] {
+  # gdb debug doesn't work for separate-mi-tty.
+  set modes {"main"}
+} else {
+  set modes {"main" "separate"}
+}
+
+foreach_with_prefix mi-mode $modes {
     test_break ${mi-mode}
 }
diff --git a/gdb/testsuite/gdb.mi/mi-watch.exp b/gdb/testsuite/gdb.mi/mi-watch.exp
index e7c59c8fb75..23cc178d71a 100644
--- a/gdb/testsuite/gdb.mi/mi-watch.exp
+++ b/gdb/testsuite/gdb.mi/mi-watch.exp
@@ -174,9 +174,16 @@ proc test_watchpoint_all {mi_mode type} {
     test_watchpoint_triggering
 }
 
+if [gdb_debug_enabled] {
+  # gdb debug doesn't work for separate-mi-tty.
+  set modes {"main"}
+} else {
+  set modes {"main" "separate"}
+}
+
 # Run the tests twice, once using software watchpoints, and another
 # with hardware watchpoints.
-foreach_with_prefix mi-mode {"main" "separate"} {
+foreach_with_prefix mi-mode $modes {
     foreach_with_prefix wp-type {"sw" "hw"} {
 	test_watchpoint_all ${mi-mode} ${wp-type}
     }
diff --git a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
index c9de792e28a..c2800224175 100644
--- a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
+++ b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
@@ -20,6 +20,11 @@
 # commands, MI should not process further commands until the inferior
 # stops again.  See PR gdb/20418.
 
+# Do not run if gdb debug is enabled as it doesn't work for separate-mi-tty.
+if [gdb_debug_enabled] {
+    return 0
+}
+
 load_lib mi-support.exp
 
 standard_testfile
diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
index 989bc56d35b..2a22e7261c7 100644
--- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
+++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
@@ -29,6 +29,11 @@
 # - Thread 3 of each inferior is either stopped at /* thread loop line */, if we
 #   are using all-stop, or running, if we are using non-stop.
 
+# Do not run if gdb debug is enabled as it doesn't work for separate-mi-tty.
+if [gdb_debug_enabled] {
+    return 0
+}
+
 load_lib mi-support.exp
 
 standard_testfile
diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp
index b62572ceb88..3b5d1a462c1 100644
--- a/gdb/testsuite/gdb.python/python.exp
+++ b/gdb/testsuite/gdb.python/python.exp
@@ -293,7 +293,10 @@ gdb_test "python print (sys.stdout)" ".*gdb.GdbOutputFile (instance|object) at.*
 gdb_test "python gdb.write(\"Foo\\n\")" "Foo" "test default write"
 gdb_test "python gdb.write(\"Error stream\\n\", stream=gdb.STDERR)" "Error stream" "test stderr write"
 gdb_test "python gdb.write(\"Normal stream\\n\", stream=gdb.STDOUT)" "Normal stream" "test stdout write"
-gdb_test "python gdb.write(\"Log stream\\n\", stream=gdb.STDLOG)" "Log stream" "test stdlog write"
+
+if ![gdb_debug_enabled] {
+  gdb_test "python gdb.write(\"Log stream\\n\", stream=gdb.STDLOG)" "Log stream" "test stdlog write"
+}
 
 # Turn on full stack printing for subsequent tests.
 gdb_py_test_silent_cmd "set python print-stack full" \
diff --git a/gdb/testsuite/gdb.threads/check-libthread-db.exp b/gdb/testsuite/gdb.threads/check-libthread-db.exp
index b569079f462..46234acf780 100644
--- a/gdb/testsuite/gdb.threads/check-libthread-db.exp
+++ b/gdb/testsuite/gdb.threads/check-libthread-db.exp
@@ -18,6 +18,12 @@ if {[target_info gdb_protocol] != "" || ![istarget *-linux*]} {
     continue
 }
 
+# Test relies on checking gdb debug ouput. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 
 if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
diff --git a/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp b/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp
index 7043a7a9f9f..a531528db0e 100644
--- a/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp
+++ b/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp
@@ -18,6 +18,12 @@
 # stop, when the thread that hit that breakpoint is not the stepped
 # thread.
 
+# Test relies on checking gdb debug ouput. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 set executable ${testfile}
 
diff --git a/gdb/testsuite/gdb.threads/stepi-random-signal.exp b/gdb/testsuite/gdb.threads/stepi-random-signal.exp
index ce93bed501a..f2c1a0ecc88 100644
--- a/gdb/testsuite/gdb.threads/stepi-random-signal.exp
+++ b/gdb/testsuite/gdb.threads/stepi-random-signal.exp
@@ -13,6 +13,12 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+# Test relies on checking gdb debug ouput. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 set executable ${testfile}
 
-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 5/9] testsuite: Record all gdb input to gdb.in
  2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
                   ` (5 preceding siblings ...)
  2019-05-14 15:13 ` [PATCH 2/9] Add debug redirect option Alan Hayward
@ 2019-05-14 15:13 ` Alan Hayward
  2019-05-16 19:25   ` Tom Tromey
  2019-05-14 15:13 ` [PATCH 6/9] testsuite: Create .cmd files for gdb and gdbserver Alan Hayward
  2019-05-14 15:13 ` [PATCH 9/9] testsuite: Remove TRANSCRIPT support Alan Hayward
  8 siblings, 1 reply; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

When debugging testsuite failures, it can be awkward parsing gdb.log to
obtain all the commands run in order to manually re-run the test.

This patch adds the functionality to save all gdb commands to the file gdb.in
when the testsuite is run. The file is saved in the directory for the test and
if gdb is restarted then .1, .2, .3 etc is added to the filename.

Once a test has been run, the .in file can be used to re-run the test in the
following way:

  gdb -x outputs/gdb.store/gdb.in outputs/gdb.store/store

The code works by intercepting send_gdb.  I've added a TYPE to ensure that any
commands that would destroy the playback are kept from the log (for example the
Y from an answer to a y/n question).

Adds library function standard_output_file_with_gdb_instance to open a file
postfixed with count of the gdb instance.  Ensure this count is reset when a new
.exp script is run.

I've re-run a random selection of .in files to check they do not error. Logs with
commands such as "attach <pid>" will not directly work when re-run.

gdb/testsuite/ChangeLog:

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* lib/gdb.exp (gdb_unload): Mark Y as an answer.
	(delete_breakpoints): Likewise.
	(gdb_run_cmd): Likewise.
	(gdb_start_cmd): Likewise.
	(gdb_starti_cmd): Likewise.
	(gdb_internal_error_resync): Likewise.
	(gdb_test_multiple): Likewise.
	(gdb_reinitialize_dir): Likewise.
	(default_gdb_exit): Likewise.
	(gdb_file_cmd): Mark kill as optional.
	(default_gdb_start): Call gdb_stdin_log_init.
	(send_gdb): Call gdb_stdin_log_write.
	(rerun_to_main): Mark Y as an answer.
	(gdb_stdin_log_init): New function.
	(gdb_stdin_log_write): Likewise.
---
 gdb/testsuite/lib/gdb.exp | 106 +++++++++++++++++++++++++++++++-------
 1 file changed, 88 insertions(+), 18 deletions(-)

diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index ba276ac9297..3815f86ffc8 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -167,11 +167,11 @@ proc gdb_unload {} {
 	-re "No executable file now\[^\r\n\]*\[\r\n\]" { exp_continue }
 	-re "No symbol file now\[^\r\n\]*\[\r\n\]" { exp_continue }
 	-re "A program is being debugged already.*Are you sure you want to change the file.*y or n. $" {
-	    send_gdb "y\n"
+	    send_gdb "y\n" answer
 	    exp_continue
 	}
 	-re "Discard symbol table from .*y or n.*$" {
-	    send_gdb "y\n"
+	    send_gdb "y\n" answer
 	    exp_continue
 	}
 	-re "$gdb_prompt $" {}
@@ -201,7 +201,7 @@ proc delete_breakpoints {} {
     set deleted 0
     gdb_test_multiple "delete breakpoints" "$msg" {
 	-re "Delete all breakpoints.*y or n.*$" {
-	    send_gdb "y\n"
+	    send_gdb "y\n" answer
 	    exp_continue
 	}
 	-re "$gdb_prompt $" {
@@ -307,7 +307,7 @@ proc gdb_run_cmd {args} {
 		    set start_attempt 0
 		}
 		-re "Line.* Jump anyway.*y or n. $" {
-		    send_gdb "y\n"
+		    send_gdb "y\n" answer
 		}
 		-re "The program is not being run.*$gdb_prompt $" {
 		    if { [gdb_reload] != 0 } {
@@ -335,7 +335,7 @@ proc gdb_run_cmd {args} {
 # may test for additional start-up messages.
    gdb_expect 60 {
 	-re "The program .* has been started already.*y or n. $" {
-	    send_gdb "y\n"
+	    send_gdb "y\n" answer
 	    exp_continue
 	}
 	-notransfer -re "Starting program: \[^\r\n\]*" {}
@@ -374,7 +374,7 @@ proc gdb_start_cmd {args} {
     # may test for additional start-up messages.
     gdb_expect 60 {
 	-re "The program .* has been started already.*y or n. $" {
-	    send_gdb "y\n"
+	    send_gdb "y\n" answer
 	    exp_continue
 	}
 	-notransfer -re "Starting program: \[^\r\n\]*" {
@@ -411,7 +411,7 @@ proc gdb_starti_cmd {args} {
     send_gdb "starti $args\n"
     gdb_expect 60 {
 	-re "The program .* has been started already.*y or n. $" {
-	    send_gdb "y\n"
+	    send_gdb "y\n" answer
 	    exp_continue
 	}
 	-re "Starting program: \[^\r\n\]*" {
@@ -673,11 +673,11 @@ proc gdb_internal_error_resync {} {
     while {$count < 10} {
 	gdb_expect {
 	    -re "Quit this debugging session\\? \\(y or n\\) $" {
-		send_gdb "n\n"
+		send_gdb "n\n" answer
 		incr count
 	    }
 	    -re "Create a core file of GDB\\? \\(y or n\\) $" {
-		send_gdb "n\n"
+		send_gdb "n\n" answer
 		incr count
 	    }
 	    -re "$gdb_prompt $" {
@@ -971,7 +971,7 @@ proc gdb_test_multiple { command message user_code } {
 	    set result -1
 	}
 	-re "\\((y or n|y or \\\[n\\\]|\\\[y\\\] or n)\\) " {
-	    send_gdb "n\n"
+	    send_gdb "n\n" answer
 	    gdb_expect -re "$gdb_prompt $"
 	    fail "$message (got interactive prompt)"
 	    set result -1
@@ -1451,7 +1451,7 @@ proc gdb_reinitialize_dir { subdir } {
     send_gdb "dir\n"
     gdb_expect 60 {
 	-re "Reinitialize source path to empty.*y or n. " {
-	    send_gdb "y\n"
+	    send_gdb "y\n" answer
 	    gdb_expect 60 {
 		-re "Source directories searched.*$gdb_prompt $" {
 		    send_gdb "dir $subdir\n"
@@ -1511,7 +1511,7 @@ proc default_gdb_exit {} {
 	send_gdb "quit\n"
 	gdb_expect 10 {
 	    -re "y or n" {
-		send_gdb "y\n"
+		send_gdb "y\n" answer
 		exp_continue
 	    }
 	    -re "DOSEXIT code" { }
@@ -1568,11 +1568,12 @@ proc gdb_file_cmd { arg } {
     }
 
     # The file command used to kill the remote target.  For the benefit
-    # of the testsuite, preserve this behavior.
-    send_gdb "kill\n"
+    # of the testsuite, preserve this behavior.  Mark as optional so it doesn't
+    # get written to the stdin log.
+    send_gdb "kill\n" optional
     gdb_expect 120 {
 	-re "Kill the program being debugged. .y or n. $" {
-	    send_gdb "y\n"
+	    send_gdb "y\n" answer
 	    verbose "\t\tKilling previous program being debugged"
 	    exp_continue
 	}
@@ -1599,7 +1600,7 @@ proc gdb_file_cmd { arg } {
 	    return 0
         }
         -re "Load new symbol table from \".*\".*y or n. $" {
-            send_gdb "y\n"
+            send_gdb "y\n" answer
             gdb_expect 120 {
                 -re "Reading symbols from.*$gdb_prompt $" {
                     verbose "\t\tLoaded $arg with new symbol table into $GDB"
@@ -1695,6 +1696,12 @@ proc default_gdb_start { } {
 	return 0
     }
 
+    # Keep track of the number of times GDB has been launched.
+    global gdb_instances
+    incr gdb_instances
+
+    gdb_stdin_log_init
+
     set res [gdb_spawn]
     if { $res != 0} {
 	return $res
@@ -3965,11 +3972,15 @@ proc gdb_compile_objc {source dest type options} {
     }
 }
 
-proc send_gdb { string } {
+# Send a command to GDB.
+# For options for TYPE see gdb_stdin_log_write
+
+proc send_gdb { string {type standard}} {
     global suppress_flag
     if { $suppress_flag } {
 	return "suppressed"
     }
+    gdb_stdin_log_write $string $type
     return [remote_send host "$string"]
 }
 
@@ -4635,6 +4646,20 @@ proc standard_output_file {basename} {
     return [file join $dir $basename]
 }
 
+# Turn BASENAME into a full file name in the standard output directory.  If
+# GDB has been launched more than once then append the count, starting with
+# a ".1" postfix.
+
+proc standard_output_file_with_gdb_instance {basename} {
+    global gdb_instances
+    set count [expr $gdb_instances - 1 ]
+
+    if {$count == 0} {
+      return [standard_output_file $basename]
+    }
+    return [standard_output_file ${basename}.${count}]
+}
+
 # Return the name of a file in our standard temporary directory.
 
 proc standard_temp_file {basename} {
@@ -4829,6 +4854,10 @@ proc gdb_init { test_file_name } {
     set gdbserver_reconnect_p 1
     unset gdbserver_reconnect_p
 
+    # Reset GDB number of instances
+    global gdb_instances
+    set gdb_instances 0
+
     return [default_gdb_init $test_file_name]
 }
 
@@ -5097,7 +5126,7 @@ proc rerun_to_main {} {
     send_gdb "run\n"
     gdb_expect {
       -re "The program .* has been started already.*y or n. $" {
-	  send_gdb "y\n"
+	  send_gdb "y\n" answer
 	  exp_continue
       }
       -re "Starting program.*$gdb_prompt $"\
@@ -6470,5 +6499,46 @@ proc gdbserver_debug_enabled { } {
     return 0
 }
 
+# Open the file for logging gdb input
+
+proc gdb_stdin_log_init { } {
+    global in_file
+
+    if {[info exists in_file]} {
+      # Close existing file.
+      catch "close $in_file"
+    }
+
+    set logfile [standard_output_file_with_gdb_instance gdb.in]
+    set in_file [open $logfile w]
+}
+
+# Write to the file for logging gdb input.
+# TYPE can be one of the following:
+# STANDARD : Default. Standard message written to the log
+# ANSWER : Answer to a question (eg "Y"). Not written the log.
+# OPTIONAL : Optional message. Not written to the log.
+
+proc gdb_stdin_log_write { message {type standard} } {
+
+    global in_file
+    if {![info exists in_file]} {
+      return
+    }
+
+    # Check message types.
+    switch -regexp -- $type {
+        "answer" {
+            return
+        }
+        "optional" {
+            return
+        }
+    }
+
+    #Write to the log
+    puts -nonewline $in_file "$message"
+}
+
 # Always load compatibility stuff.
 load_lib future.exp
-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 2/9] Add debug redirect option
  2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
                   ` (4 preceding siblings ...)
  2019-05-14 15:13 ` [PATCH 8/9] testsuite: Add script to quickly re-run tests Alan Hayward
@ 2019-05-14 15:13 ` Alan Hayward
  2019-05-16 19:12   ` Tom Tromey
  2019-05-14 15:13 ` [PATCH 5/9] testsuite: Record all gdb input to gdb.in Alan Hayward
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

Currently, when logging is enabled, output will be sent to both a
logfile and standard terminal output.  The redirect option sends output
only to the logfile.  This includes all debug output.

Add the option to redirect debug output seperately to normal
output, using the cli command:

  set logging debugredirect on

By setting this and enabling logging, all output and debug will
be sent to the logfile.  The user will still see all output but
no debug output.

This causes a change in behaviour for anyone currently using
logging redirect, as now only output will be redirected.  Users
will have to issue the additional command above to also redirect
debug.

Expand ui-redirect.exp cover the changes.

gdb/ChangeLog:

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* cli/cli-interp.c (struct saved_output_files): Add saved entry.
	(cli_interp_base::set_logging): Check debug_redirect.
	* cli/cli-interp.h (set_logging): Add debug_redirect parameter.
	* cli/cli-logging.c (debug_redirect): Add static variable.
	(pop_output_files): Add default param.
	(handle_redirections): Print debug setting.
	(show_logging_command): Likewise.
	(_initialize_cli_logging): Add debugredirect command.
	* interps.c (current_interp_set_logging): Add debug_redirect
	parameter.
	* interps.h (set_logging): Add debug_redirect parameter.
	(current_interp_set_logging): Likewise.
	* mi/mi-common.h: Likewise.
	* mi/mi-interp.c (mi_interp::set_logging): Likewise.

gdb/testsuite/ChangeLog:

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* gdb.base/ui-redirect.exp: Add debug redirect tests.
---
 gdb/cli/cli-interp.c                   | 30 ++++++++++++--------
 gdb/cli/cli-interp.h                   |  3 +-
 gdb/cli/cli-logging.c                  | 27 ++++++++++++++++--
 gdb/interps.c                          |  6 ++--
 gdb/interps.h                          | 10 +++++--
 gdb/mi/mi-common.h                     | 14 ++++++++--
 gdb/mi/mi-interp.c                     | 20 ++++++++++----
 gdb/testsuite/gdb.base/ui-redirect.exp | 38 ++++++++++++++++++++++++--
 8 files changed, 116 insertions(+), 32 deletions(-)

diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index 7876f910806..52b36a3cbee 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -395,13 +395,15 @@ struct saved_output_files
   ui_file *log;
   ui_file *targ;
   ui_file *targerr;
+  ui_file *file_to_delete;
 };
 static saved_output_files saved_output;
 
 /* See cli-interp.h.  */
 
 void
-cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
+cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect,
+			      bool debug_redirect)
 {
   if (logfile != nullptr)
     {
@@ -411,28 +413,34 @@ cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
       saved_output.targ = gdb_stdtarg;
       saved_output.targerr = gdb_stdtargerr;
 
-      /* If logging is being redirected, then grab logfile.  */
+      /* If something is being redirected, then grab logfile.  */
       ui_file *logfile_p = nullptr;
-      if (logging_redirect)
-	logfile_p = logfile.release ();
+      if (logging_redirect || debug_redirect)
+	{
+	  logfile_p = logfile.get ();
+	  saved_output.file_to_delete = logfile_p;
+	}
 
-      /* If logging is not being redirected, then a tee containing both the
+      /* If something is not being redirected, then a tee containing both the
 	 logfile and stdout.  */
       ui_file *tee = nullptr;
-      if (!logging_redirect)
-	tee = new tee_file (gdb_stdout, std::move (logfile));
+      if (!logging_redirect || !debug_redirect)
+	{
+	  tee = new tee_file (gdb_stdout, std::move (logfile));
+	  saved_output.file_to_delete = tee;
+	}
 
       gdb_stdout = logging_redirect ? logfile_p : tee;
-      gdb_stdlog = logging_redirect ? logfile_p : tee;
+      gdb_stdlog = debug_redirect ? logfile_p : tee;
       gdb_stderr = logging_redirect ? logfile_p : tee;
       gdb_stdtarg = logging_redirect ? logfile_p : tee;
       gdb_stdtargerr = logging_redirect ? logfile_p : tee;
     }
   else
     {
-      /* Only delete one of the files -- they are all set to the same
-	 value.  */
-      delete gdb_stdout;
+      /* Delete the correct file.  If it's the tee then the logfile will also
+	 be deleted.  */
+      delete saved_output.file_to_delete;
 
       gdb_stdout = saved_output.out;
       gdb_stderr = saved_output.err;
diff --git a/gdb/cli/cli-interp.h b/gdb/cli/cli-interp.h
index 0c2e73b6b38..334a37accf8 100644
--- a/gdb/cli/cli-interp.h
+++ b/gdb/cli/cli-interp.h
@@ -28,7 +28,8 @@ public:
   explicit cli_interp_base (const char *name);
   virtual ~cli_interp_base () = 0;
 
-  void set_logging (ui_file_up logfile, bool logging_redirect) override;
+  void set_logging (ui_file_up logfile, bool logging_redirect,
+		    bool debug_redirect) override;
   void pre_command_loop () override;
   bool supports_command_editing () override;
 };
diff --git a/gdb/cli/cli-logging.c b/gdb/cli/cli-logging.c
index 670e7e24908..bef5f3939bd 100644
--- a/gdb/cli/cli-logging.c
+++ b/gdb/cli/cli-logging.c
@@ -62,6 +62,7 @@ show_logging_overwrite (struct ui_file *file, int from_tty,
 
 /* Value as configured by the user.  */
 static int logging_redirect;
+static int debug_redirect;
 
 static void
 set_logging_redirect (const char *args,
@@ -81,7 +82,7 @@ show_logging_redirect (struct ui_file *file, int from_tty,
 static void
 pop_output_files (void)
 {
-  current_interp_set_logging (NULL, false);
+  current_interp_set_logging (NULL, false, false);
 
   /* Stay consistent with handle_redirections.  */
   if (!current_uiout->is_mi_like_p ())
@@ -112,12 +113,20 @@ handle_redirections (int from_tty)
       else
 	fprintf_unfiltered (gdb_stdout, "Redirecting output to %s.\n",
 			    logging_filename);
+
+      if (!debug_redirect)
+	fprintf_unfiltered (gdb_stdout, "Copying debug output to %s.\n",
+			    logging_filename);
+      else
+	fprintf_unfiltered (gdb_stdout, "Redirecting debug output to %s.\n",
+			    logging_filename);
     }
 
   saved_filename = xstrdup (logging_filename);
 
   /* Let the interpreter do anything it needs.  */
-  current_interp_set_logging (std::move (log), logging_redirect);
+  current_interp_set_logging (std::move (log), logging_redirect,
+			      debug_redirect);
 
   /* Redirect the current ui-out object's output to the log.  Use
      gdb_stdout, not log, since the interpreter may have created a tee
@@ -185,6 +194,11 @@ show_logging_command (const char *args, int from_tty)
     printf_unfiltered (_("Output will be sent only to the log file.\n"));
   else
     printf_unfiltered (_("Output will be logged and displayed.\n"));
+
+  if (debug_redirect)
+    printf_unfiltered (_("Debug output will be sent only to the log file.\n"));
+  else
+    printf_unfiltered (_("Debug output will be logged and displayed.\n"));
 }
 
 void
@@ -213,6 +227,15 @@ If redirect is on, output will go only to the log file."),
 			   set_logging_redirect,
 			   show_logging_redirect,
 			   &set_logging_cmdlist, &show_logging_cmdlist);
+  add_setshow_boolean_cmd ("debugredirect", class_support,
+			   &debug_redirect, _("\
+Set the logging debug output mode."), _("\
+Show the logging debug output mode."), _("\
+If debug redirect is off, debug will go to both the screen and the log file.\n\
+If debug redirect is on, debug will go only to the log file."),
+			   set_logging_redirect,
+			   show_logging_redirect,
+			   &set_logging_cmdlist, &show_logging_cmdlist);
   add_setshow_filename_cmd ("file", class_support, &logging_filename, _("\
 Set the current logfile."), _("\
 Show the current logfile."), _("\
diff --git a/gdb/interps.c b/gdb/interps.c
index dfd6eb90655..372bd73bf80 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -255,13 +255,13 @@ set_top_level_interpreter (const char *name)
 }
 
 void
-current_interp_set_logging (ui_file_up logfile,
-			    bool logging_redirect)
+current_interp_set_logging (ui_file_up logfile, bool logging_redirect,
+			    bool debug_redirect)
 {
   struct ui_interp_info *ui_interp = get_current_interp_info ();
   struct interp *interp = ui_interp->current_interpreter;
 
-  interp->set_logging (std::move (logfile), logging_redirect);
+  interp->set_logging (std::move (logfile), logging_redirect, debug_redirect);
 }
 
 /* Temporarily overrides the current interpreter.  */
diff --git a/gdb/interps.h b/gdb/interps.h
index 1bdc56c8395..7cdb4d97e80 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -61,7 +61,8 @@ public:
   /* Provides a hook for interpreters to do any additional
      setup/cleanup that they might need when logging is enabled or
      disabled.  */
-  virtual void set_logging (ui_file_up logfile, bool logging_redirect) = 0;
+  virtual void set_logging (ui_file_up logfile, bool logging_redirect,
+			    bool debug_redirect) = 0;
 
   /* Called before starting an event loop, to give the interpreter a
      chance to e.g., print a prompt.  */
@@ -141,9 +142,12 @@ extern int current_interp_named_p (const char *name);
    interpreter should configure the output streams to send output only
    to the logfile.  If false, the interpreter should configure the
    output streams to send output to both the current output stream
-   (i.e., the terminal) and the log file.  */
+   (i.e., the terminal) and the log file.  DEBUG_REDIRECT is same as
+   LOGGING_REDIRECT, but for the value of "set logging debugredirect"
+   instead.  */
 extern void current_interp_set_logging (ui_file_up logfile,
-					bool logging_redirect);
+					bool logging_redirect,
+					bool debug_redirect);
 
 /* Returns the top-level interpreter.  */
 extern struct interp *top_level_interpreter (void);
diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h
index 4fb2d75c0e5..07b37b71441 100644
--- a/gdb/mi/mi-common.h
+++ b/gdb/mi/mi-common.h
@@ -66,7 +66,8 @@ public:
   void suspend () override;
   gdb_exception exec (const char *command_str) override;
   ui_out *interp_ui_out () override;
-  void set_logging (ui_file_up logfile, bool logging_redirect) override;
+  void set_logging (ui_file_up logfile, bool logging_redirect,
+		    bool debug_redirect) override;
   void pre_command_loop () override;
 
   /* MI's output channels */
@@ -79,9 +80,16 @@ public:
   /* Raw console output.  */
   struct ui_file *raw_stdout;
 
-  /* Save the original value of raw_stdout here when logging, so we
-     can restore correctly when done.  */
+  /* Raw logfile output.  */
+  struct ui_file *raw_stdlog;
+
+  /* Save the original value of raw_stdout and raw_stdlog here when logging, and
+     the file which we need to delete, so we can restore correctly when
+     done.  */
   struct ui_file *saved_raw_stdout;
+  struct ui_file *saved_raw_stdlog;
+  struct ui_file *saved_raw_file_to_delete;
+
 
   /* MI's builder.  */
   struct ui_out *mi_uiout;
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index 6a19bf02476..7592b32d9c6 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -1279,7 +1279,8 @@ mi_interp::interp_ui_out ()
    the consoles to use the supplied ui-file(s).  */
 
 void
-mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)
+mi_interp::set_logging (ui_file_up logfile, bool logging_redirect,
+			bool debug_redirect)
 {
   struct mi_interp *mi = this;
 
@@ -1289,20 +1290,27 @@ mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)
 
       /* If something is being redirected, then grab logfile.  */
       ui_file *logfile_p = nullptr;
-      if (logging_redirect)
-	logfile_p = logfile.release ();
+      if (logging_redirect || debug_redirect)
+	{
+	  logfile_p = logfile.get ();
+	  mi->saved_raw_file_to_delete = logfile_p;
+	}
 
       /* If something is not being redirected, then a tee containing both the
 	 logfile and stdout.  */
       ui_file *tee = nullptr;
-      if (!logging_redirect)
-	tee = new tee_file (mi->raw_stdout, std::move (logfile));
+      if (!logging_redirect || !debug_redirect)
+	{
+	  tee = new tee_file (mi->raw_stdout, std::move (logfile));
+	  mi->saved_raw_file_to_delete = tee;
+	}
 
       mi->raw_stdout = logging_redirect ? logfile_p : tee;
+      mi->raw_stdlog = debug_redirect ? logfile_p : tee;
     }
   else
     {
-      delete mi->raw_stdout;
+      delete mi->saved_raw_file_to_delete;
       mi->raw_stdout = mi->saved_raw_stdout;
       mi->saved_raw_stdout = nullptr;
     }
diff --git a/gdb/testsuite/gdb.base/ui-redirect.exp b/gdb/testsuite/gdb.base/ui-redirect.exp
index f1d00b939da..e62d5e8341c 100644
--- a/gdb/testsuite/gdb.base/ui-redirect.exp
+++ b/gdb/testsuite/gdb.base/ui-redirect.exp
@@ -34,9 +34,17 @@ gdb_test_multiple $test $test {
 }
 gdb_test_no_output "end"
 
+if ![runto_main] {
+    fail "can't run to main"
+    return -1
+}
+gdb_breakpoint "foo"
+gdb_breakpoint "bar"
+
 with_test_prefix "logging" {
     gdb_test_no_output "set logging file /dev/null"
-    gdb_test "set logging on" "Copying output to /dev/null\\."
+    gdb_test "set logging on" \
+    "Copying output to /dev/null.*Copying debug output to /dev/null\\."
     gdb_test "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
     gdb_test "set logging off" "Done logging to /dev/null\\."
     gdb_test "help" "List of classes of commands:.*"
@@ -44,7 +52,8 @@ with_test_prefix "logging" {
 
 with_test_prefix "redirect" {
     gdb_test "set logging redirect on"
-    gdb_test "set logging on" "Redirecting output to /dev/null\\."
+    gdb_test "set logging on" \
+    "Redirecting output to /dev/null.*Copying debug output to /dev/null\\."
     gdb_test_no_output "save breakpoints /dev/null"
     gdb_test "set logging off" "Done logging to /dev/null\\."
     gdb_test "help" "List of classes of commands:.*"
@@ -52,10 +61,33 @@ with_test_prefix "redirect" {
 
 with_test_prefix "redirect while already logging" {
     gdb_test_no_output "set logging redirect off"
-    gdb_test "set logging on" "Copying output to /dev/null\\."
+    gdb_test "set logging on" \
+    "Copying output to /dev/null.*Copying debug output to /dev/null\\."
     gdb_test "set logging redirect on" \
     ".*warning: Currently logging .*Turn the logging off and on to make the new setting effective.*"
     gdb_test "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
     gdb_test "set logging off" "Done logging to /dev/null\\."
     gdb_test "help" "List of classes of commands:.*"
+    gdb_test_no_output "set logging redirect off"
+}
+
+with_test_prefix "debugging" {
+    gdb_test "set debug infrun 1"
+    gdb_test "set logging on" \
+    "Copying output to /dev/null.*Copying debug output to /dev/null\\."
+    gdb_test "continue" "Continuing.*infrun:.*infrun:.*Breakpoint \[0-9\]+, foo.*"
+    gdb_test "set debug infrun 0"
+    gdb_test "set logging off" "Done logging to /dev/null\\."
+    gdb_test "help" "List of classes of commands:.*"
+}
+
+with_test_prefix "redirect debugging" {
+    gdb_test_no_output "set logging debugredirect on"
+    gdb_test "set debug infrun 1"
+    gdb_test "set logging on" \
+    "Copying output to /dev/null.*Redirecting debug output to /dev/null\\."
+    gdb_test "continue" "Continuing.*((?!infrun).).*Breakpoint \[0-9\]+, bar.*"
+    gdb_test "set debug infrun 0"
+    gdb_test "set logging off" "Done logging to /dev/null\\."
+    gdb_test "help" "List of classes of commands:.*"
 }
-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 9/9] testsuite: Remove TRANSCRIPT support
  2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
                   ` (7 preceding siblings ...)
  2019-05-14 15:13 ` [PATCH 6/9] testsuite: Create .cmd files for gdb and gdbserver Alan Hayward
@ 2019-05-14 15:13 ` Alan Hayward
  2019-05-16 19:38   ` Tom Tromey
  8 siblings, 1 reply; 22+ messages in thread
From: Alan Hayward @ 2019-05-14 15:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

TRANSCRIPT is superseeded by the .in, .cmd and .debug files, and
can be removed.

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* README (Running the Testsuite): Change example.
	(Testsuite Parameters): Remove TRANSCRIPT.
	* lib/gdb.exp: Remove TRANSCRIPT check.
---
 gdb/testsuite/README      | 23 ++-----------------
 gdb/testsuite/lib/gdb.exp | 47 ---------------------------------------
 2 files changed, 2 insertions(+), 68 deletions(-)

diff --git a/gdb/testsuite/README b/gdb/testsuite/README
index b5fbb456bee..a2baaee38eb 100644
--- a/gdb/testsuite/README
+++ b/gdb/testsuite/README
@@ -13,14 +13,14 @@ There are two ways to run the testsuite and pass additional parameters
 to DejaGnu.  The first is to do `make check' in the main build
 directory and specifying the makefile variable `RUNTESTFLAGS':
 
-	 make check RUNTESTFLAGS='TRANSCRIPT=y gdb.base/a2-run.exp'
+	 make check RUNTESTFLAGS='GDB=/usr/bin/gdb gdb.base/a2-run.exp'
 
 The second is to cd to the testsuite directory and invoke the DejaGnu
 `runtest' command directly.
 
 	cd testsuite
 	make site.exp
-	runtest TRANSCRIPT=y
+	runtest GDB=/usr/bin/gdb
 
 (The `site.exp' file contains a handful of useful variables like host
 and target triplets, and pathnames.)
@@ -147,25 +147,6 @@ Testsuite Parameters
 The following parameters are DejaGNU variables that you can set to
 affect the testsuite run globally.
 
-TRANSCRIPT
-
-You may find it useful to have a transcript of the commands that the
-testsuite sends to GDB, for instance if GDB crashes during the run,
-and you want to reconstruct the sequence of commands.
-
-If the DejaGNU variable TRANSCRIPT is set (to any value), each
-invocation of GDB during the test run will get a transcript file
-written into the DejaGNU output directory.  The file will have the
-name transcript.<n>, where <n> is an integer.  The first line of the
-file shows the invocation command with all the options passed to it,
-while subsequent lines are the GDB commands.  A `make check' might
-look like this:
-
-      make check RUNTESTFLAGS=TRANSCRIPT=y
-
-The transcript may not be complete, as for instance tests of command
-completion may show only partial command lines.
-
 GDB
 
 By default, the testsuite exercises the GDB in the build directory,
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index cbf8d29ec12..3ff4040d373 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -5953,53 +5953,6 @@ proc relative_filename {root full} {
     return [eval file join [lrange $full_split $len end]]
 }
 
-# Log gdb command line and script if requested.
-if {[info exists TRANSCRIPT]} {
-  rename send_gdb real_send_gdb
-  rename remote_spawn real_remote_spawn
-  rename remote_close real_remote_close
-
-  global gdb_transcript
-  set gdb_transcript ""
-
-  global gdb_trans_count
-  set gdb_trans_count 1
-
-  proc remote_spawn {args} {
-    global gdb_transcript gdb_trans_count outdir
-
-    if {$gdb_transcript != ""} {
-      close $gdb_transcript
-    }
-    set gdb_transcript [open [file join $outdir transcript.$gdb_trans_count] w]
-    puts $gdb_transcript [lindex $args 1]
-    incr gdb_trans_count
-
-    return [uplevel real_remote_spawn $args]
-  }
-
-  proc remote_close {args} {
-    global gdb_transcript
-
-    if {$gdb_transcript != ""} {
-      close $gdb_transcript
-      set gdb_transcript ""
-    }
-
-    return [uplevel real_remote_close $args]
-  }
-
-  proc send_gdb {args} {
-    global gdb_transcript
-
-    if {$gdb_transcript != ""} {
-      puts -nonewline $gdb_transcript [lindex $args 0]
-    }
-
-    return [uplevel real_send_gdb $args]
-  }
-}
-
 # If GDB_PARALLEL exists, then set up the parallel-mode directories.
 if {[info exists GDB_PARALLEL]} {
     if {[is_remote host]} {
-- 
2.20.1 (Apple Git-117)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 1/9] Change file close behavior for tee_file
  2019-05-14 15:12 ` [PATCH 1/9] Change file close behavior for tee_file Alan Hayward
@ 2019-05-16 18:57   ` Tom Tromey
  0 siblings, 0 replies; 22+ messages in thread
From: Tom Tromey @ 2019-05-16 18:57 UTC (permalink / raw)
  To: Alan Hayward; +Cc: gdb-patches, nd

>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:

Alan> Instead of using two bools to decide if the files should close when tee_file
Alan> is closed, make file one stay open and file two close.  This simplifies the
Alan> use cases for it.

Alan> Inline the make_logging_output into the calling functions (the logic here
Alan> looks ugly in order to simplify a later change).

Alan> Expand ui-redirect.exp to cover the changes, similar to mi-logging.exp.

Thanks, this is ok.

Tom

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/9] Add debug redirect option
  2019-05-14 15:13 ` [PATCH 2/9] Add debug redirect option Alan Hayward
@ 2019-05-16 19:12   ` Tom Tromey
  2019-05-17 13:21     ` Alan Hayward
  0 siblings, 1 reply; 22+ messages in thread
From: Tom Tromey @ 2019-05-16 19:12 UTC (permalink / raw)
  To: Alan Hayward; +Cc: gdb-patches, nd

>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:

Alan> Currently, when logging is enabled, output will be sent to both a
Alan> logfile and standard terminal output.  The redirect option sends output
Alan> only to the logfile.  This includes all debug output.

Alan> Add the option to redirect debug output seperately to normal
Alan> output, using the cli command:

Alan>   set logging debugredirect on

I think this needs a documentation patch.

Alan> +      delete saved_output.file_to_delete;

It would be good to set saved_output.file_to_delete to NULL here -- the
other members are set to NULL just below this.

Alan> -      delete mi->raw_stdout;
Alan> +      delete mi->saved_raw_file_to_delete;

Here too, I think.

Tom

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 3/9] testsuite: Add option to capture GDB debug
  2019-05-14 15:12 ` [PATCH 3/9] testsuite: Add option to capture GDB debug Alan Hayward
@ 2019-05-16 19:16   ` Tom Tromey
  0 siblings, 0 replies; 22+ messages in thread
From: Tom Tromey @ 2019-05-16 19:16 UTC (permalink / raw)
  To: Alan Hayward; +Cc: gdb-patches, nd

>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:

Alan> Add both board option and environment variable which enables gdb
Alan> debug via a comma separated list and sends it to the file gdb.debug,
Alan> located in the output directory for the current test.  Document this.

Alan> Add support for the environment variable in the Makefile.

Alan> The testsuite can be run with gdb debug enabled in the following way:

Alan> 	make check GDB_DEBUG="infrun,target,remote"

Alan> A Test with multiple invocations of GDB will all append debug to the
Alan> same log file.

Thank you, this looks good to me.

Tom

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 4/9] testsuite: Disable some tests when logging
  2019-05-14 15:13 ` [PATCH 4/9] testsuite: Disable some tests when logging Alan Hayward
@ 2019-05-16 19:19   ` Tom Tromey
  2019-05-17 14:36     ` Alan Hayward
  0 siblings, 1 reply; 22+ messages in thread
From: Tom Tromey @ 2019-05-16 19:19 UTC (permalink / raw)
  To: Alan Hayward; +Cc: gdb-patches, nd

>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:

Alan> Fix up all failures encountered when running the testsuite with
Alan> GDB_DEBUG="infrun".

Alan> Some tests rely on enabling debugging for various components.  With
Alan> debugging on, this will be lost to the debug file.

Alan> Disable separate tty for mi tests when debugging.  This currently
Alan> does not work.

Alan> disasm.c should send errors to the stderr instead of the logfile.

I wonder if it should error(), but this isn't something you need to
worry about for this patch.

Alan> +# Test relies on checking gdb debug ouput. Do not run if gdb debug is

All these patches have the "ouput" typo, should be "output".

Alan> +if [gdb_debug_enabled] {
Alan> +    continue

I think these early returns should call "untested", see:

https://sourceware.org/gdb/wiki/GDBTestcaseCookbook#A.22untested.22_calls


Tom

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] testsuite: Record all gdb input to gdb.in
  2019-05-14 15:13 ` [PATCH 5/9] testsuite: Record all gdb input to gdb.in Alan Hayward
@ 2019-05-16 19:25   ` Tom Tromey
  2019-05-17 15:35     ` Alan Hayward
  0 siblings, 1 reply; 22+ messages in thread
From: Tom Tromey @ 2019-05-16 19:25 UTC (permalink / raw)
  To: Alan Hayward; +Cc: gdb-patches, nd

>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:

Alan> When debugging testsuite failures, it can be awkward parsing gdb.log to
Alan> obtain all the commands run in order to manually re-run the test.

Alan> This patch adds the functionality to save all gdb commands to the file gdb.in
Alan> when the testsuite is run. The file is saved in the directory for the test and
Alan> if gdb is restarted then .1, .2, .3 etc is added to the filename.

Thank you.  This seems very handy.

Alan> @@ -4829,6 +4854,10 @@ proc gdb_init { test_file_name } {
Alan>      set gdbserver_reconnect_p 1
Alan>      unset gdbserver_reconnect_p
 
Alan> +    # Reset GDB number of instances
Alan> +    global gdb_instances
Alan> +    set gdb_instances 0

Does this placement work even if a single runtest runs multiple .exp
files?  Like "runtest --directory gdb.cp"?

Alan> +# Write to the file for logging gdb input.
Alan> +# TYPE can be one of the following:
Alan> +# STANDARD : Default. Standard message written to the log
Alan> +# ANSWER : Answer to a question (eg "Y"). Not written the log.
Alan> +# OPTIONAL : Optional message. Not written to the log.

Normally the GNU style reserves upper-case in situations like this to
refer to the value of a variable.  For a string I would just use quotes,
like:

# "standard": Default.  ...

Tom

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 6/9] testsuite: Create .cmd files for gdb and gdbserver
  2019-05-14 15:13 ` [PATCH 6/9] testsuite: Create .cmd files for gdb and gdbserver Alan Hayward
@ 2019-05-16 19:28   ` Tom Tromey
  0 siblings, 0 replies; 22+ messages in thread
From: Tom Tromey @ 2019-05-16 19:28 UTC (permalink / raw)
  To: Alan Hayward; +Cc: gdb-patches, nd

>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:

Alan> When spawning gdb or gdbserver create a .cmd file in the test output
Alan> directory containing the full command line, ensuring the current gdb
Alan> instance is appened to the files so that they can be quickly matched

Typo in the commit message, should be "appended", but otherwise looks
good.  Thanks.

Tom

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 7/9] testsuite: Add replay logging to GDBSERVER_DEBUG
  2019-05-14 15:13 ` [PATCH 7/9] testsuite: Add replay logging to GDBSERVER_DEBUG Alan Hayward
@ 2019-05-16 19:34   ` Tom Tromey
  0 siblings, 0 replies; 22+ messages in thread
From: Tom Tromey @ 2019-05-16 19:34 UTC (permalink / raw)
  To: Alan Hayward; +Cc: gdb-patches, nd

>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:

Alan> 2019-05-14  Alan Hayward  <alan.hayward@arm.com>

Alan>         * README (Testsuite Parameters): Add replay logging to
Alan>         GDBSERVER_DEBUG.
Alan>         (gdbserver,debug): Refer to GDBSERVER_DEBUG.
Alan>         * lib/gdbserver-support.exp (gdbserver_start): Treat gdbserverdebug
Alan>         as a comma separated list.
Alan>         (gdb_debug_init): Override procedure.

Thanks, this looks to me.

Tom

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 9/9] testsuite: Remove TRANSCRIPT support
  2019-05-14 15:13 ` [PATCH 9/9] testsuite: Remove TRANSCRIPT support Alan Hayward
@ 2019-05-16 19:38   ` Tom Tromey
  0 siblings, 0 replies; 22+ messages in thread
From: Tom Tromey @ 2019-05-16 19:38 UTC (permalink / raw)
  To: Alan Hayward; +Cc: gdb-patches, nd

>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:

Alan> TRANSCRIPT is superseeded by the .in, .cmd and .debug files, and
Alan> can be removed.

Alan> 2019-05-14  Alan Hayward  <alan.hayward@arm.com>

Alan> 	* README (Running the Testsuite): Change example.
Alan> 	(Testsuite Parameters): Remove TRANSCRIPT.
Alan> 	* lib/gdb.exp: Remove TRANSCRIPT check.

Thanks, this is ok.

Tom

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/9] Add debug redirect option
  2019-05-16 19:12   ` Tom Tromey
@ 2019-05-17 13:21     ` Alan Hayward
  2019-05-18 18:11       ` Tom Tromey
  0 siblings, 1 reply; 22+ messages in thread
From: Alan Hayward @ 2019-05-17 13:21 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, nd



> On 16 May 2019, at 20:12, Tom Tromey <tom@tromey.com> wrote:
> 
>>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:
> 
> Alan> Currently, when logging is enabled, output will be sent to both a
> Alan> logfile and standard terminal output.  The redirect option sends output
> Alan> only to the logfile.  This includes all debug output.
> 
> Alan> Add the option to redirect debug output seperately to normal
> Alan> output, using the cli command:
> 
> Alan>   set logging debugredirect on
> 
> I think this needs a documentation patch.

Agreed. I’ll raise a new patch next week along with the NEWS changes.

> 
> Alan> +      delete saved_output.file_to_delete;
> 
> It would be good to set saved_output.file_to_delete to NULL here -- the
> other members are set to NULL just below this.
> 

Done.

> Alan> -      delete mi->raw_stdout;
> Alan> +      delete mi->saved_raw_file_to_delete;
> 
> Here too, I think.

Done.

> 
> Tom

Thanks!
Pushed this with the two small changes from above.


diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2810fff012..0e79bd0e6b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,21 @@
-2019-05-14  Alan Hayward  <alan.hayward@arm.com>
+2019-05-17  Alan Hayward  <alan.hayward@arm.com>
+
+       * cli/cli-interp.c (struct saved_output_files): Add saved entry.
+       (cli_interp_base::set_logging): Check debug_redirect.
+       * cli/cli-interp.h (set_logging): Add debug_redirect parameter.
+       * cli/cli-logging.c (debug_redirect): Add static variable.
+       (pop_output_files): Add default param.
+       (handle_redirections): Print debug setting.
+       (show_logging_command): Likewise.
+       (_initialize_cli_logging): Add debugredirect command.
+       * interps.c (current_interp_set_logging): Add debug_redirect
+       parameter.
+       * interps.h (set_logging): Add debug_redirect parameter.
+       (current_interp_set_logging): Likewise.
+       * mi/mi-common.h: Likewise.
+       * mi/mi-interp.c (mi_interp::set_logging): Likewise.
+
+2019-05-17  Alan Hayward  <alan.hayward@arm.com>
            Tom Tromey  <tromey@adacore.com>

        * cli/cli-interp.c (cli_interp_base::set_logging): Create tee_file
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index 7876f91080..a8cf6172c1 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -395,13 +395,15 @@ struct saved_output_files
   ui_file *log;
   ui_file *targ;
   ui_file *targerr;
+  ui_file *file_to_delete;
 };
 static saved_output_files saved_output;

 /* See cli-interp.h.  */

 void
-cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
+cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect,
+                             bool debug_redirect)
 {
   if (logfile != nullptr)
     {
@@ -411,28 +413,34 @@ cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
       saved_output.targ = gdb_stdtarg;
       saved_output.targerr = gdb_stdtargerr;

-      /* If logging is being redirected, then grab logfile.  */
+      /* If something is being redirected, then grab logfile.  */
       ui_file *logfile_p = nullptr;
-      if (logging_redirect)
-       logfile_p = logfile.release ();
+      if (logging_redirect || debug_redirect)
+       {
+         logfile_p = logfile.get ();
+         saved_output.file_to_delete = logfile_p;
+       }

-      /* If logging is not being redirected, then a tee containing both the
+      /* If something is not being redirected, then a tee containing both the
         logfile and stdout.  */
       ui_file *tee = nullptr;
-      if (!logging_redirect)
-       tee = new tee_file (gdb_stdout, std::move (logfile));
+      if (!logging_redirect || !debug_redirect)
+       {
+         tee = new tee_file (gdb_stdout, std::move (logfile));
+         saved_output.file_to_delete = tee;
+       }

       gdb_stdout = logging_redirect ? logfile_p : tee;
-      gdb_stdlog = logging_redirect ? logfile_p : tee;
+      gdb_stdlog = debug_redirect ? logfile_p : tee;
       gdb_stderr = logging_redirect ? logfile_p : tee;
       gdb_stdtarg = logging_redirect ? logfile_p : tee;
       gdb_stdtargerr = logging_redirect ? logfile_p : tee;
     }
   else
     {
-      /* Only delete one of the files -- they are all set to the same
-        value.  */
-      delete gdb_stdout;
+      /* Delete the correct file.  If it's the tee then the logfile will also
+        be deleted.  */
+      delete saved_output.file_to_delete;

       gdb_stdout = saved_output.out;
       gdb_stderr = saved_output.err;
@@ -445,6 +453,7 @@ cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
       saved_output.log = nullptr;
       saved_output.targ = nullptr;
       saved_output.targerr = nullptr;
+      saved_output.file_to_delete = nullptr;
     }
 }

diff --git a/gdb/cli/cli-interp.h b/gdb/cli/cli-interp.h
index 0c2e73b6b3..334a37accf 100644
--- a/gdb/cli/cli-interp.h
+++ b/gdb/cli/cli-interp.h
@@ -28,7 +28,8 @@ public:
   explicit cli_interp_base (const char *name);
   virtual ~cli_interp_base () = 0;

-  void set_logging (ui_file_up logfile, bool logging_redirect) override;
+  void set_logging (ui_file_up logfile, bool logging_redirect,
+                   bool debug_redirect) override;
   void pre_command_loop () override;
   bool supports_command_editing () override;
 };
diff --git a/gdb/cli/cli-logging.c b/gdb/cli/cli-logging.c
index 670e7e2490..bef5f3939b 100644
--- a/gdb/cli/cli-logging.c
+++ b/gdb/cli/cli-logging.c
@@ -62,6 +62,7 @@ show_logging_overwrite (struct ui_file *file, int from_tty,

 /* Value as configured by the user.  */
 static int logging_redirect;
+static int debug_redirect;

 static void
 set_logging_redirect (const char *args,
@@ -81,7 +82,7 @@ show_logging_redirect (struct ui_file *file, int from_tty,
 static void
 pop_output_files (void)
 {
-  current_interp_set_logging (NULL, false);
+  current_interp_set_logging (NULL, false, false);

   /* Stay consistent with handle_redirections.  */
   if (!current_uiout->is_mi_like_p ())
@@ -112,12 +113,20 @@ handle_redirections (int from_tty)
       else
        fprintf_unfiltered (gdb_stdout, "Redirecting output to %s.\n",
                            logging_filename);
+
+      if (!debug_redirect)
+       fprintf_unfiltered (gdb_stdout, "Copying debug output to %s.\n",
+                           logging_filename);
+      else
+       fprintf_unfiltered (gdb_stdout, "Redirecting debug output to %s.\n",
+                           logging_filename);
     }

   saved_filename = xstrdup (logging_filename);

   /* Let the interpreter do anything it needs.  */
-  current_interp_set_logging (std::move (log), logging_redirect);
+  current_interp_set_logging (std::move (log), logging_redirect,
+                             debug_redirect);

   /* Redirect the current ui-out object's output to the log.  Use
      gdb_stdout, not log, since the interpreter may have created a tee
@@ -185,6 +194,11 @@ show_logging_command (const char *args, int from_tty)
     printf_unfiltered (_("Output will be sent only to the log file.\n"));
   else
     printf_unfiltered (_("Output will be logged and displayed.\n"));
+
+  if (debug_redirect)
+    printf_unfiltered (_("Debug output will be sent only to the log file.\n"));
+  else
+    printf_unfiltered (_("Debug output will be logged and displayed.\n"));
 }

 void
@@ -213,6 +227,15 @@ If redirect is on, output will go only to the log file."),
                           set_logging_redirect,
                           show_logging_redirect,
                           &set_logging_cmdlist, &show_logging_cmdlist);
+  add_setshow_boolean_cmd ("debugredirect", class_support,
+                          &debug_redirect, _("\
+Set the logging debug output mode."), _("\
+Show the logging debug output mode."), _("\
+If debug redirect is off, debug will go to both the screen and the log file.\n\
+If debug redirect is on, debug will go only to the log file."),
+                          set_logging_redirect,
+                          show_logging_redirect,
+                          &set_logging_cmdlist, &show_logging_cmdlist);
   add_setshow_filename_cmd ("file", class_support, &logging_filename, _("\
 Set the current logfile."), _("\
 Show the current logfile."), _("\
diff --git a/gdb/interps.c b/gdb/interps.c
index dfd6eb9065..372bd73bf8 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -255,13 +255,13 @@ set_top_level_interpreter (const char *name)
 }

 void
-current_interp_set_logging (ui_file_up logfile,
-                           bool logging_redirect)
+current_interp_set_logging (ui_file_up logfile, bool logging_redirect,
+                           bool debug_redirect)
 {
   struct ui_interp_info *ui_interp = get_current_interp_info ();
   struct interp *interp = ui_interp->current_interpreter;

-  interp->set_logging (std::move (logfile), logging_redirect);
+  interp->set_logging (std::move (logfile), logging_redirect, debug_redirect);
 }

 /* Temporarily overrides the current interpreter.  */
diff --git a/gdb/interps.h b/gdb/interps.h
index 1bdc56c839..7cdb4d97e8 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -61,7 +61,8 @@ public:
   /* Provides a hook for interpreters to do any additional
      setup/cleanup that they might need when logging is enabled or
      disabled.  */
-  virtual void set_logging (ui_file_up logfile, bool logging_redirect) = 0;
+  virtual void set_logging (ui_file_up logfile, bool logging_redirect,
+                           bool debug_redirect) = 0;

   /* Called before starting an event loop, to give the interpreter a
      chance to e.g., print a prompt.  */
@@ -141,9 +142,12 @@ extern int current_interp_named_p (const char *name);
    interpreter should configure the output streams to send output only
    to the logfile.  If false, the interpreter should configure the
    output streams to send output to both the current output stream
-   (i.e., the terminal) and the log file.  */
+   (i.e., the terminal) and the log file.  DEBUG_REDIRECT is same as
+   LOGGING_REDIRECT, but for the value of "set logging debugredirect"
+   instead.  */
 extern void current_interp_set_logging (ui_file_up logfile,
-                                       bool logging_redirect);
+                                       bool logging_redirect,
+                                       bool debug_redirect);

 /* Returns the top-level interpreter.  */
 extern struct interp *top_level_interpreter (void);
diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h
index 4fb2d75c0e..07b37b7144 100644
--- a/gdb/mi/mi-common.h
+++ b/gdb/mi/mi-common.h
@@ -66,7 +66,8 @@ public:
   void suspend () override;
   gdb_exception exec (const char *command_str) override;
   ui_out *interp_ui_out () override;
-  void set_logging (ui_file_up logfile, bool logging_redirect) override;
+  void set_logging (ui_file_up logfile, bool logging_redirect,
+                   bool debug_redirect) override;
   void pre_command_loop () override;

   /* MI's output channels */
@@ -79,9 +80,16 @@ public:
   /* Raw console output.  */
   struct ui_file *raw_stdout;

-  /* Save the original value of raw_stdout here when logging, so we
-     can restore correctly when done.  */
+  /* Raw logfile output.  */
+  struct ui_file *raw_stdlog;
+
+  /* Save the original value of raw_stdout and raw_stdlog here when logging, and
+     the file which we need to delete, so we can restore correctly when
+     done.  */
   struct ui_file *saved_raw_stdout;
+  struct ui_file *saved_raw_stdlog;
+  struct ui_file *saved_raw_file_to_delete;
+

   /* MI's builder.  */
   struct ui_out *mi_uiout;
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index 6a19bf0247..ad1a06cae0 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -1279,7 +1279,8 @@ mi_interp::interp_ui_out ()
    the consoles to use the supplied ui-file(s).  */

 void
-mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)
+mi_interp::set_logging (ui_file_up logfile, bool logging_redirect,
+                       bool debug_redirect)
 {
   struct mi_interp *mi = this;

@@ -1289,22 +1290,30 @@ mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)

       /* If something is being redirected, then grab logfile.  */
       ui_file *logfile_p = nullptr;
-      if (logging_redirect)
-       logfile_p = logfile.release ();
+      if (logging_redirect || debug_redirect)
+       {
+         logfile_p = logfile.get ();
+         mi->saved_raw_file_to_delete = logfile_p;
+       }

       /* If something is not being redirected, then a tee containing both the
         logfile and stdout.  */
       ui_file *tee = nullptr;
-      if (!logging_redirect)
-       tee = new tee_file (mi->raw_stdout, std::move (logfile));
+      if (!logging_redirect || !debug_redirect)
+       {
+         tee = new tee_file (mi->raw_stdout, std::move (logfile));
+         mi->saved_raw_file_to_delete = tee;
+       }

       mi->raw_stdout = logging_redirect ? logfile_p : tee;
+      mi->raw_stdlog = debug_redirect ? logfile_p : tee;
     }
   else
     {
-      delete mi->raw_stdout;
+      delete mi->saved_raw_file_to_delete;
       mi->raw_stdout = mi->saved_raw_stdout;
       mi->saved_raw_stdout = nullptr;
+      mi->saved_raw_file_to_delete = nullptr;
     }

   mi->out->set_raw (mi->raw_stdout);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 6d35156499..50888236af 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-05-17  Alan Hayward  <alan.hayward@arm.com>
+
+       * gdb.base/ui-redirect.exp: Add debug redirect tests.
+
 2019-05-17  Alan Hayward  <alan.hayward@arm.com>

        * gdb.base/ui-redirect.exp: Test redirection.
diff --git a/gdb/testsuite/gdb.base/ui-redirect.exp b/gdb/testsuite/gdb.base/ui-redirect.exp
index f1d00b939d..e62d5e8341 100644
--- a/gdb/testsuite/gdb.base/ui-redirect.exp
+++ b/gdb/testsuite/gdb.base/ui-redirect.exp
@@ -34,9 +34,17 @@ gdb_test_multiple $test $test {
 }
 gdb_test_no_output "end"

+if ![runto_main] {
+    fail "can't run to main"
+    return -1
+}
+gdb_breakpoint "foo"
+gdb_breakpoint "bar"
+
 with_test_prefix "logging" {
     gdb_test_no_output "set logging file /dev/null"
-    gdb_test "set logging on" "Copying output to /dev/null\\."
+    gdb_test "set logging on" \
+    "Copying output to /dev/null.*Copying debug output to /dev/null\\."
     gdb_test "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
     gdb_test "set logging off" "Done logging to /dev/null\\."
     gdb_test "help" "List of classes of commands:.*"
@@ -44,7 +52,8 @@ with_test_prefix "logging" {

 with_test_prefix "redirect" {
     gdb_test "set logging redirect on"
-    gdb_test "set logging on" "Redirecting output to /dev/null\\."
+    gdb_test "set logging on" \
+    "Redirecting output to /dev/null.*Copying debug output to /dev/null\\."
     gdb_test_no_output "save breakpoints /dev/null"
     gdb_test "set logging off" "Done logging to /dev/null\\."
     gdb_test "help" "List of classes of commands:.*"
@@ -52,10 +61,33 @@ with_test_prefix "redirect" {

 with_test_prefix "redirect while already logging" {
     gdb_test_no_output "set logging redirect off"
-    gdb_test "set logging on" "Copying output to /dev/null\\."
+    gdb_test "set logging on" \
+    "Copying output to /dev/null.*Copying debug output to /dev/null\\."
     gdb_test "set logging redirect on" \
     ".*warning: Currently logging .*Turn the logging off and on to make the new setting effective.*"
     gdb_test "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
     gdb_test "set logging off" "Done logging to /dev/null\\."
     gdb_test "help" "List of classes of commands:.*"
+    gdb_test_no_output "set logging redirect off"
+}
+
+with_test_prefix "debugging" {
+    gdb_test "set debug infrun 1"
+    gdb_test "set logging on" \
+    "Copying output to /dev/null.*Copying debug output to /dev/null\\."
+    gdb_test "continue" "Continuing.*infrun:.*infrun:.*Breakpoint \[0-9\]+, foo.*"
+    gdb_test "set debug infrun 0"
+    gdb_test "set logging off" "Done logging to /dev/null\\."
+    gdb_test "help" "List of classes of commands:.*"
+}
+
+with_test_prefix "redirect debugging" {
+    gdb_test_no_output "set logging debugredirect on"
+    gdb_test "set debug infrun 1"
+    gdb_test "set logging on" \
+    "Copying output to /dev/null.*Redirecting debug output to /dev/null\\."
+    gdb_test "continue" "Continuing.*((?!infrun).).*Breakpoint \[0-9\]+, bar.*"
+    gdb_test "set debug infrun 0"
+    gdb_test "set logging off" "Done logging to /dev/null\\."
+    gdb_test "help" "List of classes of commands:.*"
 }

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 4/9] testsuite: Disable some tests when logging
  2019-05-16 19:19   ` Tom Tromey
@ 2019-05-17 14:36     ` Alan Hayward
  0 siblings, 0 replies; 22+ messages in thread
From: Alan Hayward @ 2019-05-17 14:36 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, nd



> On 16 May 2019, at 20:19, Tom Tromey <tom@tromey.com> wrote:
> 
>>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:
> 
> Alan> Fix up all failures encountered when running the testsuite with
> Alan> GDB_DEBUG="infrun".
> 
> Alan> Some tests rely on enabling debugging for various components.  With
> Alan> debugging on, this will be lost to the debug file.
> 
> Alan> Disable separate tty for mi tests when debugging.  This currently
> Alan> does not work.
> 
> Alan> disasm.c should send errors to the stderr instead of the logfile.
> 
> I wonder if it should error(), but this isn't something you need to
> worry about for this patch.

Sounds reasonable.

> 
> Alan> +# Test relies on checking gdb debug ouput. Do not run if gdb debug is
> 
> All these patches have the "ouput" typo, should be "output”.

Doh! Fixed.

> 
> Alan> +if [gdb_debug_enabled] {
> Alan> +    continue
> 
> I think these early returns should call "untested", see:
> 
> https://sourceware.org/gdb/wiki/GDBTestcaseCookbook#A.22untested.22_calls
> 

Makes sense. Fixed these all up to be:

if [gdb_debug_enabled] {
    untested "debug is enabled"
    return 0
}


Pushed with the above changes:


diff --git a/gdb/disasm.c b/gdb/disasm.c
index 7c7a148935..ed740c26e0 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -943,7 +943,7 @@ set_disassembler_options (char *prospective_options)
   valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch);
   if (valid_options_and_args == NULL)
     {
-      fprintf_filtered (gdb_stdlog, _("\
+      fprintf_filtered (gdb_stderr, _("\
 'set disassembler-options ...' is not supported on this architecture.\n"));
       return;
     }
@@ -979,7 +979,7 @@ set_disassembler_options (char *prospective_options)
          break;
       if (valid_options->name[i] == NULL)
        {
-         fprintf_filtered (gdb_stdlog,
+         fprintf_filtered (gdb_stderr,
                            _("Invalid disassembler option value: '%s'.\n"),
                            opt);
          return;
diff --git a/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp b/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
index 8655f54e03..9099df0a08 100644
--- a/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
+++ b/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
@@ -15,6 +15,13 @@

 # This file is part of the gdb testsuite

+# Test relies on checking gdb debug output. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 standard_testfile

 if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
diff --git a/gdb/testsuite/gdb.base/debug-expr.exp b/gdb/testsuite/gdb.base/debug-expr.exp
index 8885ec6b9b..6da591b9ca 100644
--- a/gdb/testsuite/gdb.base/debug-expr.exp
+++ b/gdb/testsuite/gdb.base/debug-expr.exp
@@ -15,6 +15,13 @@

 # Test "set debug expr 1" on c expressions.

+# Test relies on checking gdb debug output. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 standard_testfile .c

 if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} {
diff --git a/gdb/testsuite/gdb.base/foll-fork.exp b/gdb/testsuite/gdb.base/foll-fork.exp
index 8884686928..9f27c4c962 100644
--- a/gdb/testsuite/gdb.base/foll-fork.exp
+++ b/gdb/testsuite/gdb.base/foll-fork.exp
@@ -20,6 +20,13 @@ if { ![istarget "*-*-linux*"] && ![istarget "*-*-openbsd*"] } then {
     continue
 }

+# Test relies on checking follow-fork output. Do not run if gdb debug is
+# enabled as it will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 standard_testfile

 if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp
index 96d8539bee..7bfebb2a91 100644
--- a/gdb/testsuite/gdb.base/foll-vfork.exp
+++ b/gdb/testsuite/gdb.base/foll-vfork.exp
@@ -25,6 +25,13 @@ if {![istarget "*-linux*"]} then {
     continue
 }

+# Test relies on checking follow-fork output. Do not run if gdb debug is
+# enabled as it will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 standard_testfile

 set compile_options debug
diff --git a/gdb/testsuite/gdb.base/fork-print-inferior-events.exp b/gdb/testsuite/gdb.base/fork-print-inferior-events.exp
index 1c5a470bd6..2befdd8ede 100644
--- a/gdb/testsuite/gdb.base/fork-print-inferior-events.exp
+++ b/gdb/testsuite/gdb.base/fork-print-inferior-events.exp
@@ -25,6 +25,13 @@ if { [use_gdb_stub] } {
     return
 }

+# Test relies on checking follow-fork output. Do not run if gdb debug is
+# enabled as it will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 standard_testfile

 if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {
diff --git a/gdb/testsuite/gdb.base/gdb-sigterm.exp b/gdb/testsuite/gdb.base/gdb-sigterm.exp
index 36d24fcc56..f0a26c6085 100644
--- a/gdb/testsuite/gdb.base/gdb-sigterm.exp
+++ b/gdb/testsuite/gdb.base/gdb-sigterm.exp
@@ -15,6 +15,13 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.

+# Test relies on checking gdb debug output. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 standard_testfile

 # The test program exits after a while, in case GDB crashes.  Make it
diff --git a/gdb/testsuite/gdb.base/gdbinit-history.exp b/gdb/testsuite/gdb.base/gdbinit-history.exp
index f4f0686ccc..b45e7116d9 100644
--- a/gdb/testsuite/gdb.base/gdbinit-history.exp
+++ b/gdb/testsuite/gdb.base/gdbinit-history.exp
@@ -21,6 +21,12 @@
 # We cannot expect remote hosts to see environment variables set on the
 # local machine.

+# Do not run if gdb debug is enabled - it interferes with the command history.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 if { [is_remote host] } {
     unsupported "can't set environment variables on remote host"
     return -1
diff --git a/gdb/testsuite/gdb.base/osabi.exp b/gdb/testsuite/gdb.base/osabi.exp
index 50146311f7..f4418cac65 100644
--- a/gdb/testsuite/gdb.base/osabi.exp
+++ b/gdb/testsuite/gdb.base/osabi.exp
@@ -15,6 +15,13 @@

 # This file is part of the gdb testsuite.

+# Test relies on checking gdb debug output. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 # Test that choosing "set osabi none" really requests a gdbarch with no osabi.

 proc test_set_osabi_none { } {
diff --git a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
index 898233afa4..d25ad794cb 100644
--- a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
+++ b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
@@ -31,6 +31,13 @@
 # 4 - The single-step finishes, and GDB removes the single-step
 #     breakpoint.

+# Test relies on checking gdb debug output. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 standard_testfile

 if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
diff --git a/gdb/testsuite/gdb.base/ui-redirect.exp b/gdb/testsuite/gdb.base/ui-redirect.exp
index e62d5e8341..4507ac51a2 100644
--- a/gdb/testsuite/gdb.base/ui-redirect.exp
+++ b/gdb/testsuite/gdb.base/ui-redirect.exp
@@ -13,6 +13,12 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.

+# Do not run if gdb debug is enabled as it will interfere with log redirect.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 if { [prepare_for_testing "failed to prepare" ui-redirect start.c] } {
     return -1
 }
diff --git a/gdb/testsuite/gdb.gdb/unittest.exp b/gdb/testsuite/gdb.gdb/unittest.exp
index 09c603059f..e6ec628049 100644
--- a/gdb/testsuite/gdb.gdb/unittest.exp
+++ b/gdb/testsuite/gdb.gdb/unittest.exp
@@ -13,6 +13,13 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.

+# Do not run if gdb debug is enabled as maintenance output will be
+# redirected to the log files.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 set do_xml_test [expr ![gdb_skip_xml_test]]

 gdb_start
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
index 365e4faa81..c517ce886f 100644
--- a/gdb/testsuite/gdb.mi/mi-break.exp
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -429,6 +429,13 @@ proc test_break {mi_mode} {
     test_explicit_breakpoints
 }

-foreach_with_prefix mi-mode {"main" "separate"} {
+if [gdb_debug_enabled] {
+  # gdb debug doesn't work for separate-mi-tty.
+  set modes {"main"}
+} else {
+  set modes {"main" "separate"}
+}
+
+foreach_with_prefix mi-mode $modes {
     test_break ${mi-mode}
 }
diff --git a/gdb/testsuite/gdb.mi/mi-watch.exp b/gdb/testsuite/gdb.mi/mi-watch.exp
index e7c59c8fb7..23cc178d71 100644
--- a/gdb/testsuite/gdb.mi/mi-watch.exp
+++ b/gdb/testsuite/gdb.mi/mi-watch.exp
@@ -174,9 +174,16 @@ proc test_watchpoint_all {mi_mode type} {
     test_watchpoint_triggering
 }

+if [gdb_debug_enabled] {
+  # gdb debug doesn't work for separate-mi-tty.
+  set modes {"main"}
+} else {
+  set modes {"main" "separate"}
+}
+
 # Run the tests twice, once using software watchpoints, and another
 # with hardware watchpoints.
-foreach_with_prefix mi-mode {"main" "separate"} {
+foreach_with_prefix mi-mode $modes {
     foreach_with_prefix wp-type {"sw" "hw"} {
        test_watchpoint_all ${mi-mode} ${wp-type}
     }
diff --git a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
index c9de792e28..5560a8be96 100644
--- a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
+++ b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
@@ -20,6 +20,12 @@
 # commands, MI should not process further commands until the inferior
 # stops again.  See PR gdb/20418.

+# Do not run if gdb debug is enabled as it doesn't work for separate-mi-tty.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 load_lib mi-support.exp

 standard_testfile
diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
index 989bc56d35..621b4c5163 100644
--- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
+++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
@@ -29,6 +29,12 @@
 # - Thread 3 of each inferior is either stopped at /* thread loop line */, if we
 #   are using all-stop, or running, if we are using non-stop.

+# Do not run if gdb debug is enabled as it doesn't work for separate-mi-tty.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 load_lib mi-support.exp

 standard_testfile
diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp
index b62572ceb8..3b5d1a462c 100644
--- a/gdb/testsuite/gdb.python/python.exp
+++ b/gdb/testsuite/gdb.python/python.exp
@@ -293,7 +293,10 @@ gdb_test "python print (sys.stdout)" ".*gdb.GdbOutputFile (instance|object) at.*
 gdb_test "python gdb.write(\"Foo\\n\")" "Foo" "test default write"
 gdb_test "python gdb.write(\"Error stream\\n\", stream=gdb.STDERR)" "Error stream" "test stderr write"
 gdb_test "python gdb.write(\"Normal stream\\n\", stream=gdb.STDOUT)" "Normal stream" "test stdout write"
-gdb_test "python gdb.write(\"Log stream\\n\", stream=gdb.STDLOG)" "Log stream" "test stdlog write"
+
+if ![gdb_debug_enabled] {
+  gdb_test "python gdb.write(\"Log stream\\n\", stream=gdb.STDLOG)" "Log stream" "test stdlog write"
+}

 # Turn on full stack printing for subsequent tests.
 gdb_py_test_silent_cmd "set python print-stack full" \
diff --git a/gdb/testsuite/gdb.threads/check-libthread-db.exp b/gdb/testsuite/gdb.threads/check-libthread-db.exp
index b569079f46..6baa4910d3 100644
--- a/gdb/testsuite/gdb.threads/check-libthread-db.exp
+++ b/gdb/testsuite/gdb.threads/check-libthread-db.exp
@@ -18,6 +18,13 @@ if {[target_info gdb_protocol] != "" || ![istarget *-linux*]} {
     continue
 }

+# Test relies on checking gdb debug output. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 standard_testfile

 if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
diff --git a/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp b/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp
index 7043a7a9f9..9fb3762934 100644
--- a/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp
+++ b/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp
@@ -18,6 +18,12 @@
 # stop, when the thread that hit that breakpoint is not the stepped
 # thread.

+# Test relies on checking gdb debug output. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    continue
+}
+
 standard_testfile
 set executable ${testfile}

diff --git a/gdb/testsuite/gdb.threads/stepi-random-signal.exp b/gdb/testsuite/gdb.threads/stepi-random-signal.exp
index ce93bed501..fd593c38e4 100644
--- a/gdb/testsuite/gdb.threads/stepi-random-signal.exp
+++ b/gdb/testsuite/gdb.threads/stepi-random-signal.exp
@@ -13,6 +13,13 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.

+# Test relies on checking gdb debug output. Do not run if gdb debug is
+# enabled as any debug will be redirected to the log.
+if [gdb_debug_enabled] {
+    untested "debug is enabled"
+    return 0
+}
+
 standard_testfile
 set executable ${testfile}


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] testsuite: Record all gdb input to gdb.in
  2019-05-16 19:25   ` Tom Tromey
@ 2019-05-17 15:35     ` Alan Hayward
  0 siblings, 0 replies; 22+ messages in thread
From: Alan Hayward @ 2019-05-17 15:35 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, nd



> On 16 May 2019, at 20:24, Tom Tromey <tom@tromey.com> wrote:
> 
>>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:
> 
> Alan> When debugging testsuite failures, it can be awkward parsing gdb.log to
> Alan> obtain all the commands run in order to manually re-run the test.
> 
> Alan> This patch adds the functionality to save all gdb commands to the file gdb.in
> Alan> when the testsuite is run. The file is saved in the directory for the test and
> Alan> if gdb is restarted then .1, .2, .3 etc is added to the filename.
> 
> Thank you.  This seems very handy.
> 
> Alan> @@ -4829,6 +4854,10 @@ proc gdb_init { test_file_name } {
> Alan>      set gdbserver_reconnect_p 1
> Alan>      unset gdbserver_reconnect_p
> 
> Alan> +    # Reset GDB number of instances
> Alan> +    global gdb_instances
> Alan> +    set gdb_instances 0
> 
> Does this placement work even if a single runtest runs multiple .exp
> files?  Like "runtest --directory gdb.cp”?

I’ve just tried this and it works fine.

> 
> Alan> +# Write to the file for logging gdb input.
> Alan> +# TYPE can be one of the following:
> Alan> +# STANDARD : Default. Standard message written to the log
> Alan> +# ANSWER : Answer to a question (eg "Y"). Not written the log.
> Alan> +# OPTIONAL : Optional message. Not written to the log.
> 
> Normally the GNU style reserves upper-case in situations like this to
> refer to the value of a variable.  For a string I would just use quotes,
> like:
> 
> # "standard": Default.  …

Done.

> 
> Tom


And pushed with above change:


diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index ba276ac929..d00f1cefd3 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -167,11 +167,11 @@ proc gdb_unload {} {
        -re "No executable file now\[^\r\n\]*\[\r\n\]" { exp_continue }
        -re "No symbol file now\[^\r\n\]*\[\r\n\]" { exp_continue }
        -re "A program is being debugged already.*Are you sure you want to change the file.*y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -re "Discard symbol table from .*y or n.*$" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -re "$gdb_prompt $" {}
@@ -201,7 +201,7 @@ proc delete_breakpoints {} {
     set deleted 0
     gdb_test_multiple "delete breakpoints" "$msg" {
        -re "Delete all breakpoints.*y or n.*$" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -re "$gdb_prompt $" {
@@ -307,7 +307,7 @@ proc gdb_run_cmd {args} {
                    set start_attempt 0
                }
                -re "Line.* Jump anyway.*y or n. $" {
-                   send_gdb "y\n"
+                   send_gdb "y\n" answer
                }
                -re "The program is not being run.*$gdb_prompt $" {
                    if { [gdb_reload] != 0 } {
@@ -335,7 +335,7 @@ proc gdb_run_cmd {args} {
 # may test for additional start-up messages.
    gdb_expect 60 {
        -re "The program .* has been started already.*y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -notransfer -re "Starting program: \[^\r\n\]*" {}
@@ -374,7 +374,7 @@ proc gdb_start_cmd {args} {
     # may test for additional start-up messages.
     gdb_expect 60 {
        -re "The program .* has been started already.*y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -notransfer -re "Starting program: \[^\r\n\]*" {
@@ -411,7 +411,7 @@ proc gdb_starti_cmd {args} {
     send_gdb "starti $args\n"
     gdb_expect 60 {
        -re "The program .* has been started already.*y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -re "Starting program: \[^\r\n\]*" {
@@ -673,11 +673,11 @@ proc gdb_internal_error_resync {} {
     while {$count < 10} {
        gdb_expect {
            -re "Quit this debugging session\\? \\(y or n\\) $" {
-               send_gdb "n\n"
+               send_gdb "n\n" answer
                incr count
            }
            -re "Create a core file of GDB\\? \\(y or n\\) $" {
-               send_gdb "n\n"
+               send_gdb "n\n" answer
                incr count
            }
            -re "$gdb_prompt $" {
@@ -971,7 +971,7 @@ proc gdb_test_multiple { command message user_code } {
            set result -1
        }
        -re "\\((y or n|y or \\\[n\\\]|\\\[y\\\] or n)\\) " {
-           send_gdb "n\n"
+           send_gdb "n\n" answer
            gdb_expect -re "$gdb_prompt $"
            fail "$message (got interactive prompt)"
            set result -1
@@ -1451,7 +1451,7 @@ proc gdb_reinitialize_dir { subdir } {
     send_gdb "dir\n"
     gdb_expect 60 {
        -re "Reinitialize source path to empty.*y or n. " {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            gdb_expect 60 {
                -re "Source directories searched.*$gdb_prompt $" {
                    send_gdb "dir $subdir\n"
@@ -1511,7 +1511,7 @@ proc default_gdb_exit {} {
        send_gdb "quit\n"
        gdb_expect 10 {
            -re "y or n" {
-               send_gdb "y\n"
+               send_gdb "y\n" answer
                exp_continue
            }
            -re "DOSEXIT code" { }
@@ -1568,11 +1568,12 @@ proc gdb_file_cmd { arg } {
     }

     # The file command used to kill the remote target.  For the benefit
-    # of the testsuite, preserve this behavior.
-    send_gdb "kill\n"
+    # of the testsuite, preserve this behavior.  Mark as optional so it doesn't
+    # get written to the stdin log.
+    send_gdb "kill\n" optional
     gdb_expect 120 {
        -re "Kill the program being debugged. .y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            verbose "\t\tKilling previous program being debugged"
            exp_continue
        }
@@ -1599,7 +1600,7 @@ proc gdb_file_cmd { arg } {
            return 0
         }
         -re "Load new symbol table from \".*\".*y or n. $" {
-            send_gdb "y\n"
+            send_gdb "y\n" answer
             gdb_expect 120 {
                 -re "Reading symbols from.*$gdb_prompt $" {
                     verbose "\t\tLoaded $arg with new symbol table into $GDB"
@@ -1695,6 +1696,12 @@ proc default_gdb_start { } {
        return 0
     }

+    # Keep track of the number of times GDB has been launched.
+    global gdb_instances
+    incr gdb_instances
+
+    gdb_stdin_log_init
+
     set res [gdb_spawn]
     if { $res != 0} {
        return $res
@@ -3965,11 +3972,15 @@ proc gdb_compile_objc {source dest type options} {
     }
 }

-proc send_gdb { string } {
+# Send a command to GDB.
+# For options for TYPE see gdb_stdin_log_write
+
+proc send_gdb { string {type standard}} {
     global suppress_flag
     if { $suppress_flag } {
        return "suppressed"
     }
+    gdb_stdin_log_write $string $type
     return [remote_send host "$string"]
 }

@@ -4635,6 +4646,20 @@ proc standard_output_file {basename} {
     return [file join $dir $basename]
 }

+# Turn BASENAME into a full file name in the standard output directory.  If
+# GDB has been launched more than once then append the count, starting with
+# a ".1" postfix.
+
+proc standard_output_file_with_gdb_instance {basename} {
+    global gdb_instances
+    set count [expr $gdb_instances - 1 ]
+
+    if {$count == 0} {
+      return [standard_output_file $basename]
+    }
+    return [standard_output_file ${basename}.${count}]
+}
+
 # Return the name of a file in our standard temporary directory.

 proc standard_temp_file {basename} {
@@ -4829,6 +4854,10 @@ proc gdb_init { test_file_name } {
     set gdbserver_reconnect_p 1
     unset gdbserver_reconnect_p

+    # Reset GDB number of instances
+    global gdb_instances
+    set gdb_instances 0
+
     return [default_gdb_init $test_file_name]
 }

@@ -5097,7 +5126,7 @@ proc rerun_to_main {} {
     send_gdb "run\n"
     gdb_expect {
       -re "The program .* has been started already.*y or n. $" {
-         send_gdb "y\n"
+         send_gdb "y\n" answer
          exp_continue
       }
       -re "Starting program.*$gdb_prompt $"\
@@ -6470,5 +6499,46 @@ proc gdbserver_debug_enabled { } {
     return 0
 }

+# Open the file for logging gdb input
+
+proc gdb_stdin_log_init { } {
+    global in_file
+
+    if {[info exists in_file]} {
+      # Close existing file.
+      catch "close $in_file"
+    }
+
+    set logfile [standard_output_file_with_gdb_instance gdb.in]
+    set in_file [open $logfile w]
+}
+
+# Write to the file for logging gdb input.
+# TYPE can be one of the following:
+# "standard" : Default. Standard message written to the log
+# "answer" : Answer to a question (eg "Y"). Not written the log.
+# "optional" : Optional message. Not written to the log.
+
+proc gdb_stdin_log_write { message {type standard} } {
+
+    global in_file
+    if {![info exists in_file]} {
+      return
+    }
+
+    # Check message types.
+    switch -regexp -- $type {
+        "answer" {
+            return
+        }
+        "optional" {
+            return
+        }
+    }
+
+    #Write to the log
+    puts -nonewline $in_file "$message"
+}
+
 # Always load compatibility stuff.
 load_lib future.exp




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/9] Add debug redirect option
  2019-05-17 13:21     ` Alan Hayward
@ 2019-05-18 18:11       ` Tom Tromey
  0 siblings, 0 replies; 22+ messages in thread
From: Tom Tromey @ 2019-05-18 18:11 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Tom Tromey, gdb-patches, nd

>>>>> "Alan" == Alan Hayward <Alan.Hayward@arm.com> writes:

>> I think this needs a documentation patch.

Alan> Agreed. I’ll raise a new patch next week along with the NEWS changes.

Alan> Pushed this with the two small changes from above.

It's best to land the documentation patch with the code change -- not to
wait until later.  The reason for this is that sometimes other events
intervene, and then we're left with an undocumented feature.  It's
similar to the situation with writing tests.

In this case, no need to back things out.  Just write the doc patch; and
in the future please do it as a unit.

thanks,
Tom

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2019-05-18 18:11 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-14 15:12 [PATCH 0/9] Create gdb.debug, gdb.cmd and gdb.in files when running the testsuite Alan Hayward
2019-05-14 15:12 ` [PATCH 1/9] Change file close behavior for tee_file Alan Hayward
2019-05-16 18:57   ` Tom Tromey
2019-05-14 15:12 ` [PATCH 3/9] testsuite: Add option to capture GDB debug Alan Hayward
2019-05-16 19:16   ` Tom Tromey
2019-05-14 15:13 ` [PATCH 7/9] testsuite: Add replay logging to GDBSERVER_DEBUG Alan Hayward
2019-05-16 19:34   ` Tom Tromey
2019-05-14 15:13 ` [PATCH 4/9] testsuite: Disable some tests when logging Alan Hayward
2019-05-16 19:19   ` Tom Tromey
2019-05-17 14:36     ` Alan Hayward
2019-05-14 15:13 ` [PATCH 8/9] testsuite: Add script to quickly re-run tests Alan Hayward
2019-05-14 15:13 ` [PATCH 2/9] Add debug redirect option Alan Hayward
2019-05-16 19:12   ` Tom Tromey
2019-05-17 13:21     ` Alan Hayward
2019-05-18 18:11       ` Tom Tromey
2019-05-14 15:13 ` [PATCH 5/9] testsuite: Record all gdb input to gdb.in Alan Hayward
2019-05-16 19:25   ` Tom Tromey
2019-05-17 15:35     ` Alan Hayward
2019-05-14 15:13 ` [PATCH 6/9] testsuite: Create .cmd files for gdb and gdbserver Alan Hayward
2019-05-16 19:28   ` Tom Tromey
2019-05-14 15:13 ` [PATCH 9/9] testsuite: Remove TRANSCRIPT support Alan Hayward
2019-05-16 19:38   ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).