public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libstdc++: Fix stream initialization with static library [PR107701]
@ 2022-11-16  2:46 Patrick Palka
  2022-11-16  4:02 ` Patrick Palka
  2022-11-16 10:55 ` Jonathan Wakely
  0 siblings, 2 replies; 4+ messages in thread
From: Patrick Palka @ 2022-11-16  2:46 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Patrick Palka

When linking with a static library, the linker seems to exclude a
constituent .o object (including its global initializers) if nothing
from it is referenced by the program (unless e.g. --whole-archive is
used).  This behavior breaks iostream when linking with static libstdc++.a
(on systems that support init priorities) because we're defining the
global initializer for the standard stream objects in a separate TU
(ios_init.cc) from the stream objects definitions (globals_io.cc).

Thus in order to ensure that the global initializer for the standard
stream objects doesn't get wrongly dropped when statically linking,
we need to perform the initialization from the same TU that actually
defines the stream objects.

Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

	PR libstdc++/107701

libstdc++-v3/ChangeLog:

	* src/c++98/globals_io.cc: Include "io_base_init.h" here
	instead of ...
	* src/c++98/ios_init.cc: ... here.
	* testsuite/17_intro/static.cc: Run the test as well.
---
 libstdc++-v3/src/c++98/globals_io.cc      | 2 ++
 libstdc++-v3/src/c++98/ios_init.cc        | 2 --
 libstdc++-v3/testsuite/17_intro/static.cc | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/src/c++98/globals_io.cc b/libstdc++-v3/src/c++98/globals_io.cc
index 04fecb22aeb..bfd808b5bbd 100644
--- a/libstdc++-v3/src/c++98/globals_io.cc
+++ b/libstdc++-v3/src/c++98/globals_io.cc
@@ -69,6 +69,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   fake_wostream wclog;
 #endif
 
+#include "ios_base_init.h"
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
diff --git a/libstdc++-v3/src/c++98/ios_init.cc b/libstdc++-v3/src/c++98/ios_init.cc
index 4016fcab785..1b5132f1c2d 100644
--- a/libstdc++-v3/src/c++98/ios_init.cc
+++ b/libstdc++-v3/src/c++98/ios_init.cc
@@ -75,8 +75,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern wostream wclog;
 #endif
 
-#include "ios_base_init.h"
-
   ios_base::Init::Init()
   {
     if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0)
diff --git a/libstdc++-v3/testsuite/17_intro/static.cc b/libstdc++-v3/testsuite/17_intro/static.cc
index ffa7ecb7077..a0d6ed081f8 100644
--- a/libstdc++-v3/testsuite/17_intro/static.cc
+++ b/libstdc++-v3/testsuite/17_intro/static.cc
@@ -1,4 +1,4 @@
-// { dg-do link { target c++11 } }
+// { dg-do run { target c++11 } }
 // { dg-require-static-libstdcxx }
 // { dg-options "-static-libstdc++" }
 
-- 
2.38.1.436.geea7033409


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

* Re: [PATCH] libstdc++: Fix stream initialization with static library [PR107701]
  2022-11-16  2:46 [PATCH] libstdc++: Fix stream initialization with static library [PR107701] Patrick Palka
@ 2022-11-16  4:02 ` Patrick Palka
  2022-11-16 10:55 ` Jonathan Wakely
  1 sibling, 0 replies; 4+ messages in thread
From: Patrick Palka @ 2022-11-16  4:02 UTC (permalink / raw)
  To: Patrick Palka; +Cc: gcc-patches, libstdc++

On Tue, 15 Nov 2022, Patrick Palka wrote:

> When linking with a static library, the linker seems to exclude a
> constituent .o object (including its global initializers) if nothing
> from it is referenced by the program (unless e.g. --whole-archive is
> used).  This behavior breaks iostream when linking with static libstdc++.a
> (on systems that support init priorities) because we're defining the
> global initializer for the standard stream objects in a separate TU
> (ios_init.cc) from the stream objects definitions (globals_io.cc).
> 
> Thus in order to ensure that the global initializer for the standard
> stream objects doesn't get wrongly dropped when statically linking,
> we need to perform the initialization from the same TU that actually
> defines the stream objects.
> 
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

v2 with more comment fixes/additions:

-- >8 --

Subject: [PATCH] libstdc++: Fix stream initialization with static library
 [PR107701]

When linking with a static library, the linker seems to discard a
constituent .o object (including its global initializers) if nothing
from it is referenced by the program (unless e.g. --whole-archive is
used).  This behavior breaks iostream when linking with static libstdc++.a
(on systems that support init priorities) because we define the global
initializer for the standard stream objects in a separate TU (ios_init.cc)
from the stream objects definitions (globals_io.cc).

Thus in order to ensure that the global initializer for the standard
stream objects doesn't get wrongly dropped when statically linking,
we need to perform the initialization from the same TU that actually
defines the stream objects.

Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

	PR libstdc++/107701

libstdc++-v3/ChangeLog:

	* include/std/iostream (__ioinit): Adjust comment.
	* src/c++98/globals_io.cc: Include "io_base_init.h" here
	instead of ...
	* src/c++98/ios_init.cc: ... here.
	* src/c++98/ios_base_init.h (__ioinit): Extend comment.
	* testsuite/17_intro/static.cc: Run the test as well.
---
 libstdc++-v3/include/std/iostream         | 2 +-
 libstdc++-v3/src/c++98/globals_io.cc      | 2 ++
 libstdc++-v3/src/c++98/ios_base_init.h    | 1 +
 libstdc++-v3/src/c++98/ios_init.cc        | 2 --
 libstdc++-v3/testsuite/17_intro/static.cc | 2 +-
 5 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/std/iostream b/libstdc++-v3/include/std/iostream
index ff78e1cfb87..0c62e9aeb7f 100644
--- a/libstdc++-v3/include/std/iostream
+++ b/libstdc++-v3/include/std/iostream
@@ -74,7 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // For construction of filebuffers for cout, cin, cerr, clog et. al.
   // When the init_priority attribute is usable, we do this initialization
-  // in the compiled library instead (src/c++98/ios_init.cc).
+  // in the compiled library instead (src/c++98/globals_io.cc).
 #if !__has_attribute(__init_priority__)
   static ios_base::Init __ioinit;
 #endif
diff --git a/libstdc++-v3/src/c++98/globals_io.cc b/libstdc++-v3/src/c++98/globals_io.cc
index 04fecb22aeb..bfd808b5bbd 100644
--- a/libstdc++-v3/src/c++98/globals_io.cc
+++ b/libstdc++-v3/src/c++98/globals_io.cc
@@ -69,6 +69,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   fake_wostream wclog;
 #endif
 
+#include "ios_base_init.h"
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
diff --git a/libstdc++-v3/src/c++98/ios_base_init.h b/libstdc++-v3/src/c++98/ios_base_init.h
index 1c71038f4a1..b600ec3298e 100644
--- a/libstdc++-v3/src/c++98/ios_base_init.h
+++ b/libstdc++-v3/src/c++98/ios_base_init.h
@@ -7,6 +7,7 @@
 // sufficiently early (so that it happens before any other global
 // constructor when statically linking with libstdc++.a), instead of
 // doing so in (each TU that includes) <iostream>.
+// This needs to be done in the same TU that defines the stream objects.
 #if __has_attribute(init_priority)
 static ios_base::Init __ioinit __attribute__((init_priority(90)));
 #endif
diff --git a/libstdc++-v3/src/c++98/ios_init.cc b/libstdc++-v3/src/c++98/ios_init.cc
index 4016fcab785..1b5132f1c2d 100644
--- a/libstdc++-v3/src/c++98/ios_init.cc
+++ b/libstdc++-v3/src/c++98/ios_init.cc
@@ -75,8 +75,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern wostream wclog;
 #endif
 
-#include "ios_base_init.h"
-
   ios_base::Init::Init()
   {
     if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0)
diff --git a/libstdc++-v3/testsuite/17_intro/static.cc b/libstdc++-v3/testsuite/17_intro/static.cc
index ffa7ecb7077..a0d6ed081f8 100644
--- a/libstdc++-v3/testsuite/17_intro/static.cc
+++ b/libstdc++-v3/testsuite/17_intro/static.cc
@@ -1,4 +1,4 @@
-// { dg-do link { target c++11 } }
+// { dg-do run { target c++11 } }
 // { dg-require-static-libstdcxx }
 // { dg-options "-static-libstdc++" }
 
-- 
2.38.1.436.geea7033409


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

* Re: [PATCH] libstdc++: Fix stream initialization with static library [PR107701]
  2022-11-16  2:46 [PATCH] libstdc++: Fix stream initialization with static library [PR107701] Patrick Palka
  2022-11-16  4:02 ` Patrick Palka
@ 2022-11-16 10:55 ` Jonathan Wakely
  2022-11-16 12:40   ` Jonathan Wakely
  1 sibling, 1 reply; 4+ messages in thread
From: Jonathan Wakely @ 2022-11-16 10:55 UTC (permalink / raw)
  To: Patrick Palka; +Cc: gcc-patches, libstdc++

On Wed, 16 Nov 2022 at 02:46, Patrick Palka via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> When linking with a static library, the linker seems to exclude a
> constituent .o object (including its global initializers) if nothing
> from it is referenced by the program (unless e.g. --whole-archive is
> used).  This behavior breaks iostream when linking with static libstdc++.a
> (on systems that support init priorities) because we're defining the
> global initializer for the standard stream objects in a separate TU
> (ios_init.cc) from the stream objects definitions (globals_io.cc).
>
> Thus in order to ensure that the global initializer for the standard
> stream objects doesn't get wrongly dropped when statically linking,
> we need to perform the initialization from the same TU that actually
> defines the stream objects.
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

OK, thanks.

I'm a little nervous that future improvements to --gc-sections or LTO
could cause the same problem, but I think we're OK for now.


>
>         PR libstdc++/107701
>
> libstdc++-v3/ChangeLog:
>
>         * src/c++98/globals_io.cc: Include "io_base_init.h" here
>         instead of ...
>         * src/c++98/ios_init.cc: ... here.
>         * testsuite/17_intro/static.cc: Run the test as well.
> ---
>  libstdc++-v3/src/c++98/globals_io.cc      | 2 ++
>  libstdc++-v3/src/c++98/ios_init.cc        | 2 --
>  libstdc++-v3/testsuite/17_intro/static.cc | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/libstdc++-v3/src/c++98/globals_io.cc b/libstdc++-v3/src/c++98/globals_io.cc
> index 04fecb22aeb..bfd808b5bbd 100644
> --- a/libstdc++-v3/src/c++98/globals_io.cc
> +++ b/libstdc++-v3/src/c++98/globals_io.cc
> @@ -69,6 +69,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>    fake_wostream wclog;
>  #endif
>
> +#include "ios_base_init.h"
> +
>  _GLIBCXX_END_NAMESPACE_VERSION
>  } // namespace
>
> diff --git a/libstdc++-v3/src/c++98/ios_init.cc b/libstdc++-v3/src/c++98/ios_init.cc
> index 4016fcab785..1b5132f1c2d 100644
> --- a/libstdc++-v3/src/c++98/ios_init.cc
> +++ b/libstdc++-v3/src/c++98/ios_init.cc
> @@ -75,8 +75,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>    extern wostream wclog;
>  #endif
>
> -#include "ios_base_init.h"
> -
>    ios_base::Init::Init()
>    {
>      if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0)
> diff --git a/libstdc++-v3/testsuite/17_intro/static.cc b/libstdc++-v3/testsuite/17_intro/static.cc
> index ffa7ecb7077..a0d6ed081f8 100644
> --- a/libstdc++-v3/testsuite/17_intro/static.cc
> +++ b/libstdc++-v3/testsuite/17_intro/static.cc
> @@ -1,4 +1,4 @@
> -// { dg-do link { target c++11 } }
> +// { dg-do run { target c++11 } }
>  // { dg-require-static-libstdcxx }
>  // { dg-options "-static-libstdc++" }
>
> --
> 2.38.1.436.geea7033409
>


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

* Re: [PATCH] libstdc++: Fix stream initialization with static library [PR107701]
  2022-11-16 10:55 ` Jonathan Wakely
@ 2022-11-16 12:40   ` Jonathan Wakely
  0 siblings, 0 replies; 4+ messages in thread
From: Jonathan Wakely @ 2022-11-16 12:40 UTC (permalink / raw)
  To: Patrick Palka; +Cc: gcc-patches, libstdc++

On Wed, 16 Nov 2022 at 10:55, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On Wed, 16 Nov 2022 at 02:46, Patrick Palka via Libstdc++
> <libstdc++@gcc.gnu.org> wrote:
> >
> > When linking with a static library, the linker seems to exclude a
> > constituent .o object (including its global initializers) if nothing
> > from it is referenced by the program (unless e.g. --whole-archive is
> > used).  This behavior breaks iostream when linking with static libstdc++.a
> > (on systems that support init priorities) because we're defining the
> > global initializer for the standard stream objects in a separate TU
> > (ios_init.cc) from the stream objects definitions (globals_io.cc).
> >
> > Thus in order to ensure that the global initializer for the standard
> > stream objects doesn't get wrongly dropped when statically linking,
> > we need to perform the initialization from the same TU that actually
> > defines the stream objects.
> >
> > Tested on x86_64-pc-linux-gnu, does this look OK for trunk?
>
> OK, thanks.

Oops, I missed the v2. That's definitely better with the improve comments.

OK for v2.


>
> I'm a little nervous that future improvements to --gc-sections or LTO
> could cause the same problem, but I think we're OK for now.
>
>
> >
> >         PR libstdc++/107701
> >
> > libstdc++-v3/ChangeLog:
> >
> >         * src/c++98/globals_io.cc: Include "io_base_init.h" here
> >         instead of ...
> >         * src/c++98/ios_init.cc: ... here.
> >         * testsuite/17_intro/static.cc: Run the test as well.
> > ---
> >  libstdc++-v3/src/c++98/globals_io.cc      | 2 ++
> >  libstdc++-v3/src/c++98/ios_init.cc        | 2 --
> >  libstdc++-v3/testsuite/17_intro/static.cc | 2 +-
> >  3 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/libstdc++-v3/src/c++98/globals_io.cc b/libstdc++-v3/src/c++98/globals_io.cc
> > index 04fecb22aeb..bfd808b5bbd 100644
> > --- a/libstdc++-v3/src/c++98/globals_io.cc
> > +++ b/libstdc++-v3/src/c++98/globals_io.cc
> > @@ -69,6 +69,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >    fake_wostream wclog;
> >  #endif
> >
> > +#include "ios_base_init.h"
> > +
> >  _GLIBCXX_END_NAMESPACE_VERSION
> >  } // namespace
> >
> > diff --git a/libstdc++-v3/src/c++98/ios_init.cc b/libstdc++-v3/src/c++98/ios_init.cc
> > index 4016fcab785..1b5132f1c2d 100644
> > --- a/libstdc++-v3/src/c++98/ios_init.cc
> > +++ b/libstdc++-v3/src/c++98/ios_init.cc
> > @@ -75,8 +75,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >    extern wostream wclog;
> >  #endif
> >
> > -#include "ios_base_init.h"
> > -
> >    ios_base::Init::Init()
> >    {
> >      if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0)
> > diff --git a/libstdc++-v3/testsuite/17_intro/static.cc b/libstdc++-v3/testsuite/17_intro/static.cc
> > index ffa7ecb7077..a0d6ed081f8 100644
> > --- a/libstdc++-v3/testsuite/17_intro/static.cc
> > +++ b/libstdc++-v3/testsuite/17_intro/static.cc
> > @@ -1,4 +1,4 @@
> > -// { dg-do link { target c++11 } }
> > +// { dg-do run { target c++11 } }
> >  // { dg-require-static-libstdcxx }
> >  // { dg-options "-static-libstdc++" }
> >
> > --
> > 2.38.1.436.geea7033409
> >


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

end of thread, other threads:[~2022-11-16 12:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-16  2:46 [PATCH] libstdc++: Fix stream initialization with static library [PR107701] Patrick Palka
2022-11-16  4:02 ` Patrick Palka
2022-11-16 10:55 ` Jonathan Wakely
2022-11-16 12:40   ` Jonathan Wakely

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).