[PATCH 2/2] testsuite/lib/set_unbuffered_mode.c: Use constructor priority

Pedro Alves <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
On native Windows, we link in testsuite/lib/set_unbuffered_mode.c to
all executables.  That file has a constructor function that disables
output buffering.  We want that constructor to run before the
constructors of global C++ objects, in case those objects print to
output.

Currently, that is done by relying on the link order of object files
on the link line affecting the global ctor order.  On Windows, with
gcc and clang targeting the GNU ABI, constructors are run in reverse
link order.  I.e., the constructors from the last objfile on the link
line run first.

That is not true if we compile with clang targeting the MSVC ABI,
though.  There, global ctors run on link line order.  Like on Linux.

This can instead be handled by setting a constructor priority.
Constructors with a priority run before the global C++ objects'
constructors.  The GCC feature to allow specifying a constructor with
a priority only appeared in GCC 4.3, released in 2008, and I added
this set_unbuffered_mode feature to GDB also in 2008, so back then it
was too early to rely on the priority feature.

It's 2025 now, and I think we can safely assume nobody is testing on
Windows with such an old compiler.

So this patch gives an explicit priority to the
testsuite/lib/set_unbuffered_mode.c constructor, and tweaks the
comments in testsuite/lib/gdb.exp to no longer talk about controlling
ctor order with link order.

Tested with both GCC and Clang.

Change-Id: Ia5f8972f2ef45f070e63cb0a1b0aa9918957ea8e
---
 gdb/testsuite/lib/gdb.exp               | 9 ++++-----
 gdb/testsuite/lib/set_unbuffered_mode.c | 7 +++++--
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 6fb04869605..fecb9af4883 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -7046,13 +7046,12 @@ proc gdb_compile {source dest type options} {
 		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.
 	    # This object can only be added if standard libraries are
-	    # used. Thus, we need to disable it if -nostdlib option is used
+	    # used.  Thus, we need to disable it if -nostdlib option
+	    # is used.
 	    if {[lsearch -regexp $options "-nostdlib"] < 0 } {
+		# Use ldflags to avoid copying the object file to the
+		# host multiple times.
 		lappend options "ldflags=$gdb_saved_set_unbuffered_mode_obj"
 	    }
 	}
diff --git a/gdb/testsuite/lib/set_unbuffered_mode.c b/gdb/testsuite/lib/set_unbuffered_mode.c
index 6d69ccabaeb..3b5badcf780 100644
--- a/gdb/testsuite/lib/set_unbuffered_mode.c
+++ b/gdb/testsuite/lib/set_unbuffered_mode.c
@@ -19,8 +19,11 @@
 
 #include <stdio.h>
 
-static void __gdb_set_unbuffered_output (void) __attribute__ ((constructor));
-static void
+/* Use an explicit priority so that this runs before constructors of
+   namespace-scope C++ objects (which may output to stdout/stderr).
+   Lower priorities run first.  Constructor priorities from 0 to 100
+   are reserved for the implementation.  */
+static void __attribute__ ((constructor (101)))
 __gdb_set_unbuffered_output (void)
 {
   setvbuf (stdout, NULL, _IONBF, BUFSIZ);
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.