diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 8c995e316a..e10e1c6c47 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2008-06-27 Pedro Alves + + * 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. + 2008-06-25 Jan Kratochvil * lib/gdb.exp (prepare_for_testing): Do not drop the OPTIONS argument. diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index e9b63f5711..72081a8db5 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -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 options} { 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. diff --git a/gdb/testsuite/lib/set_unbuffered_mode.c b/gdb/testsuite/lib/set_unbuffered_mode.c new file mode 100644 index 0000000000..aa9180155e --- /dev/null +++ b/gdb/testsuite/lib/set_unbuffered_mode.c @@ -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 . */ + +/* Force outputs to unbuffered mode. */ + +#include + +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); +}