This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC/gdb/testsuite] Another way to avoid the windows native tty troubles


A Saturday 14 June 2008 01:15:45, Pierre Muller wrote:

>   Several answers concerned the reasons of the tty problems,
> but I was mainly interested in getting
> more reliable testsuite results for windows targets.
>   Lots of tests fail simply because the programs think that
> they are not on a terminal and thus use full buffering, which is
> incompatible with the testsuite logic.
>
> But, as Pedro said, individual files are not the right location to
> fix this.
>
>   I finally came up with a different idea, that seems to work
> now quite well.
>
>   The idea is simply to add an object that call setbuf(stdout,NULL)
> in a function that is added to the ctor section.
>   The source
> gdb.arch/cygwin-ctor.c is simply:
> $ cat ../gdb.arch/cygwin-ctor.c
>
> #include <stdio.h>
>
> void
> disableoutbuffer ()
> {
>   setbuf (stdout, 0);
> }
>
> asm (".section .ctor");
> asm(" .long     _disableoutbuffer");
>
> <<< End of cygwin-ctor.c file >>>

Pierre, this is exactly how we have fixed this issue for our
internal mingw testing.  I apologize for not telling you about it
before, and not sparring you the trouble.

We have the attached patch installed in our tree for a few
months now, and never seen a problem with it -- and we use
the same tree for linux testing too.  It works OK in remote
host testing too, and avoids as much as possible interfering
with test flags, and also avoids compiling the magic
object more than once per testsuite run.

> This file can be compile with gcc as cygwin-ctor.o
> or with gcc -mno-cygwin as mingw-ctor.o (allowing to
> use it for mingw tests, even if those still have lots of other problems).
>

>   The gdb_compile procedure change is rather simple,
> but it could probably be made more universal by converting this into
> a target info property that would be set in site.exp file for instance.

That's the reason I didn't submit this patch right away.  On the one
hand, this is a problem with the test environment, e.g., using ssh
to test mingw.  I'm not sure if running tests under MSFT's
telnetd/cmd.exe would still have this problem or not.  OTOH, cygwin
inferiors in a cygwin superior don't recognize they are running
under a tty, because GDB invokes them with CreateProcess, so
this is a GDB/Cygwin problem, not a test environment problem.

All in all, my opinion is that this is hitting everyone that tests
on Windows, so deserves to go into common GDB testsuite code.

What do others think?

-- 
Pedro Alves
	gdb/testsuite/
	* lib/gdb.exp (gdb_saved_set_unbuffered_mode_obj): New global.
	(gdb_compile): If target is *-*-cygwin* or *-*-mingw*, and we're
	compiling an executable, link in an object that forces unbuffered
	output.
	* lib/set_unbuffered_mode.c: New file.

---
 gdb/testsuite/lib/gdb.exp               |   45 ++++++++++++++++++++++++++++++++
 gdb/testsuite/lib/set_unbuffered_mode.c |   28 +++++++++++++++++++
 2 files changed, 73 insertions(+)

Index: src/gdb/testsuite/lib/set_unbuffered_mode.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/testsuite/lib/set_unbuffered_mode.c	2008-06-16 03:55:22.000000000 +0100
@@ -0,0 +1,28 @@
+/* Copyright (C) 2008 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/>.  */
+
+/* Force outputs to unbuffered mode.  */
+
+#include <stdio.h>
+
+static int __gdb_set_unbuffered_output (void) __attribute__ ((constructor));
+static int
+__gdb_set_unbuffered_output (void)
+{
+  setvbuf (stdout, NULL, _IONBF, BUFSIZ);
+  setvbuf (stderr, NULL, _IONBF, BUFSIZ);
+}
Index: src/gdb/testsuite/lib/gdb.exp
===================================================================
--- src.orig/gdb/testsuite/lib/gdb.exp	2008-05-05 17:27:45.000000000 +0100
+++ src/gdb/testsuite/lib/gdb.exp	2008-06-16 03:55:22.000000000 +0100
@@ -1536,11 +1536,18 @@ proc gdb_wrapper_init { args } {
     set gdb_wrapper_initialized 1
 }
 
+# Some targets need to always link a special object in.  Save its path here.
+global gdb_saved_set_unbuffered_mode_obj
+set gdb_saved_set_unbuffered_mode_obj ""
+
 proc gdb_compile {source dest type options} {
     global GDB_TESTCASE_OPTIONS;
     global gdb_wrapper_file;
     global gdb_wrapper_flags;
     global gdb_wrapper_initialized;
+    global srcdir
+    global objdir
+    global gdb_saved_set_unbuffered_mode_obj
 
     set outdir [file dirname $dest]
 
@@ -1627,6 +1634,44 @@ proc gdb_compile {source dest type optio
 	set options [lreplace $options $nowarnings $nowarnings $flag]
     }
 
+    if { $type == "executable" } {
+	if { ([istarget "*-*-mingw*"]
+	      || [istarget "*-*-cygwin*"])} {
+	    # Force output to unbuffered mode, by linking in an object file
+	    # with a global contructor that calls setvbuf.
+	    #
+	    # Compile the special object seperatelly for two reasons:
+	    #  1) Insulate it from $options.
+	    #  2) Avoid compiling it for every gdb_compile invocation,
+	    #  which is time consuming, especially if we're remote
+	    #  host testing.
+	    #
+	    if { $gdb_saved_set_unbuffered_mode_obj == "" } {
+		verbose "compiling gdb_saved_set_unbuffered_obj"
+		set unbuf_src ${srcdir}/lib/set_unbuffered_mode.c
+		set unbuf_obj ${objdir}/set_unbuffered_mode.o
+
+		set result [gdb_compile "${unbuf_src}" "${unbuf_obj}" object {nowarnings}]
+		if { $result != "" } {
+		    return $result
+		}
+
+		set gdb_saved_set_unbuffered_mode_obj ${objdir}/set_unbuffered_mode_saved.o
+		# Link a copy of the output object, because the
+		# original may be automatically deleted.
+		remote_exec host "cp -f $unbuf_obj $gdb_saved_set_unbuffered_mode_obj"
+	    } else {
+		verbose "gdb_saved_set_unbuffered_obj already compiled"
+	    }
+
+	    # Rely on the internal knowledge that the global ctors are ran in
+	    # reverse link order.  In that case, we can use ldflags to
+	    # avoid copying the object file to the host multiple
+	    # times.
+	    lappend options "ldflags=$gdb_saved_set_unbuffered_mode_obj"
+	}
+    }
+
     set result [target_compile $source $dest $type $options];
 
     # Prune uninteresting compiler (and linker) output.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]