Add --with-static-standard-libraries to the top level

Message ID 87y307bidk.fsf@tromey.com
State New
Headers show
Series
  • Add --with-static-standard-libraries to the top level
Related show

Commit Message

Tom Tromey Aug. 5, 2019, 6:02 p.m.
gdb should normally not be linked with -static-libstdc++.  Currently
this has not caused problems, but it's incompatible with catching an
exception thrown from a shared library -- and a subsequent patch
changes gdb to do just this.

This patch adds a new --with-static-standard-libraries flag to the
top-level configure.  It defaults to "auto", which means enabled if
gcc is being built, and disabled otherwise.

Tom

2019-07-27  Tom Tromey  <tom@tromey.com>

	* configure: Rebuild.
	* configure.ac: Add --with-static-standard-libraries.

-- 
2.20.1

Comments

Jeff Law Aug. 8, 2019, 8:53 p.m. | #1
On 8/5/19 12:02 PM, Tom Tromey wrote:
> gdb should normally not be linked with -static-libstdc++.  Currently

> this has not caused problems, but it's incompatible with catching an

> exception thrown from a shared library -- and a subsequent patch

> changes gdb to do just this.

> 

> This patch adds a new --with-static-standard-libraries flag to the

> top-level configure.  It defaults to "auto", which means enabled if

> gcc is being built, and disabled otherwise.

> 

> Tom

> 

> 2019-07-27  Tom Tromey  <tom@tromey.com>

> 

> 	* configure: Rebuild.

> 	* configure.ac: Add --with-static-standard-libraries.

Deferring to Jon.

It might be worth reviewing:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56750

And this thread:

> https://gcc.gnu.org/ml/gcc-patches/2018-02/msg00403.html


While I NAK'd Aldy's patch in the email thread, if Jon thinks we should
have this capability I won't object.


jeff
Jonathan Wakely Aug. 13, 2019, 10:40 a.m. | #2
On 08/08/19 14:53 -0600, Jeff Law wrote:
>On 8/5/19 12:02 PM, Tom Tromey wrote:

>> gdb should normally not be linked with -static-libstdc++.  Currently

>> this has not caused problems, but it's incompatible with catching an

>> exception thrown from a shared library -- and a subsequent patch

>> changes gdb to do just this.

>>

>> This patch adds a new --with-static-standard-libraries flag to the

>> top-level configure.  It defaults to "auto", which means enabled if

>> gcc is being built, and disabled otherwise.

>>

>> Tom

>>

>> 2019-07-27  Tom Tromey  <tom@tromey.com>

>>

>> 	* configure: Rebuild.

>> 	* configure.ac: Add --with-static-standard-libraries.

>Deferring to Jon.

>

>It might be worth reviewing:

>

>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56750

>

>And this thread:

>

>> https://gcc.gnu.org/ml/gcc-patches/2018-02/msg00403.html

>

>While I NAK'd Aldy's patch in the email thread, if Jon thinks we should

>have this capability I won't object.


The new option (and its default value) seem reasonable to me. I don't
see why GDB should be forced to link to libstdc++.a just because GCC
wants to.

What I don't understand is why GDB crashes. It should still be able to
catch exceptions from a shared library even if linked to libstdc++.a,
unless the static libstdc++.a is somehow incompatible with the shared
libstdc++.so the shared lib linked to.

Is this on GNU/Linux, or something with a different linking model?
Tom Tromey Aug. 13, 2019, 3:18 p.m. | #3
Jonathan> What I don't understand is why GDB crashes. It should still be able to
Jonathan> catch exceptions from a shared library even if linked to libstdc++.a,
Jonathan> unless the static libstdc++.a is somehow incompatible with the shared
Jonathan> libstdc++.so the shared lib linked to.

Jonathan> Is this on GNU/Linux, or something with a different linking model?

GNU/Linux, Fedora 29 in particular.  I didn't look into why it fails but
the gcc docs specifically mention this problem:

'-static-libgcc'
[...]
     There are several situations in which an application should use the
     shared 'libgcc' instead of the static version.  The most common of
     these is when the application wishes to throw and catch exceptions
     across different shared libraries.  In that case, each of the
     libraries as well as the application itself should use the shared
     'libgcc'.


I was able to reproduce it with a simple test program:

    $ cd /tmp
    $ cat t.cc 
    void thrower() {
      throw 23;
    }
    $ g++ -fPIC -shared -o libt.so t.cc
    $ cat a.cc
    extern void thrower ();

    int main () {
      try {
        thrower ();
      } catch (...) {
      }
      return 0;
    }
    $ g++ -o a -static-libgcc -static-libstdc++ a.cc -L$(pwd) -lt
    $ LD_LIBRARY_PATH=$(pwd) ./a
    Aborted (core dumped)

thanks,
Tom
Jonathan Wakely Aug. 16, 2019, 5:23 p.m. | #4
On 13/08/19 09:18 -0600, Tom Tromey wrote:
>Jonathan> What I don't understand is why GDB crashes. It should still be able to

>Jonathan> catch exceptions from a shared library even if linked to libstdc++.a,

>Jonathan> unless the static libstdc++.a is somehow incompatible with the shared

>Jonathan> libstdc++.so the shared lib linked to.

>

>Jonathan> Is this on GNU/Linux, or something with a different linking model?

>

>GNU/Linux, Fedora 29 in particular.  I didn't look into why it fails but

>the gcc docs specifically mention this problem:

>

>'-static-libgcc'

>[...]

>     There are several situations in which an application should use the

>     shared 'libgcc' instead of the static version.  The most common of

>     these is when the application wishes to throw and catch exceptions

>     across different shared libraries.  In that case, each of the

>     libraries as well as the application itself should use the shared

>     'libgcc'.

>

>

>I was able to reproduce it with a simple test program:

>

>    $ cd /tmp

>    $ cat t.cc

>    void thrower() {

>      throw 23;

>    }

>    $ g++ -fPIC -shared -o libt.so t.cc

>    $ cat a.cc

>    extern void thrower ();

>

>    int main () {

>      try {

>        thrower ();

>      } catch (...) {

>      }

>      return 0;

>    }

>    $ g++ -o a -static-libgcc -static-libstdc++ a.cc -L$(pwd) -lt

>    $ LD_LIBRARY_PATH=$(pwd) ./a

>    Aborted (core dumped)


This works perfectly for me on F29, but I have no idea why I get
different results. I'll look into that separately.

Given that the problem does exist, I think being able to disable the
GCC build flags for non-GCC components in the build tree makes sense.
I'm not sure if Jeff deferring to me means I can approve the patch
(normally I can't approve top-level config stuff) but for whatever
it's worth, I approve the patch.
Tom Tromey Aug. 19, 2019, 3:47 p.m. | #5
>>>>> "Jonathan" == Jonathan Wakely <jwakely@redhat.com> writes:


Jonathan> Given that the problem does exist, I think being able to disable the
Jonathan> GCC build flags for non-GCC components in the build tree makes sense.
Jonathan> I'm not sure if Jeff deferring to me means I can approve the patch
Jonathan> (normally I can't approve top-level config stuff) but for whatever
Jonathan> it's worth, I approve the patch.

Thanks.  I understood his message as deferring to your judgment, so I am
going to check it in.

Tom

Patch

diff --git a/configure.ac b/configure.ac
index 854f71a34e5..7433badc217 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1602,6 +1602,19 @@  AC_ARG_WITH(stage1-libs,
 [stage1_libs=])
 AC_SUBST(stage1_libs)
 
+# Whether or not to use -static-libstdc++ and -static-libgcc.  The
+# default is yes if gcc is being built; no otherwise.  The reason for
+# this default is that gdb is sometimes linked against GNU Source
+# Highlight, which is a shared library that uses C++ exceptions.  In
+# this case, -static-libstdc++ will cause crashes.
+AC_ARG_WITH(static-standard-libraries,
+[AS_HELP_STRING([--with-static-standard-libraries],
+                [use -static-libstdc++ and -static-libgcc (default=auto)])],
+[], [with_static_standard_libraries=auto])
+if test "$with_static_standard_libraries" = auto; then
+  with_static_standard_libraries=$have_compiler
+fi
+
 # Linker flags to use for stage1 or when not bootstrapping.
 AC_ARG_WITH(stage1-ldflags,
 [AS_HELP_STRING([--with-stage1-ldflags=FLAGS], [linker flags for stage1])],
@@ -1614,7 +1627,8 @@  AC_ARG_WITH(stage1-ldflags,
  # In stage 1, default to linking libstdc++ and libgcc statically with GCC
  # if supported.  But if the user explicitly specified the libraries to use,
  # trust that they are doing what they want.
- if test "$stage1_libs" = "" -a "$have_static_libs" = yes; then
+ if test "$with_static_standard_libraries" = yes -a "$stage1_libs" = "" \
+     -a "$have_static_libs" = yes; then
    stage1_ldflags="-static-libstdc++ -static-libgcc"
  fi])
 AC_SUBST(stage1_ldflags)