This is an archive of the discontinued LLVM Phabricator instance.

[Driver] Pass -lunwind along with compiler-rt when necessary on Linux
Needs RevisionPublic

Authored by mgorny on Oct 8 2016, 2:24 PM.

Details

Summary

Pass -lunwind when compiler-rt is used as the runtime library on regular
Linux (non-Android) and an unwinder is needed. This fixes building
C++ programs with '-rtlib=compiler-rt -stdlib=libc++' out-of-the-box,
and linking to compiler-rt when using '-static'. In both cases clang
did not pass any unwinder library so far.

This aims to match the current '-rtlib=libgcc' behavior which includes
the gcc unwinder library (libgcc_s or libgcc_eh) unconditionally.
However, -lunwind is added for C++ only if libc++ is used as
the standard C++ library since libstdc++ implicitly includes
the unwinder. Furthermore, -lunwind is only used for C++ and static
compiler-rt executables to avoid adding unnecessary dependencies for
regular C executables that could make bootstrap harder.

This was originally requested in D25008 by @EricWF in order to remove
the necessity of including -lunwind in the linker script. Most notably,
this allows us to reduce the risk of including two unwinder libraries in
a single linking action (libgcc_s via -rtlib, and libunwind via
the linker script).

The change is limited to Linux platform to avoid accidentally breaking
other platforms. Furthermore, some of them include -lunwind
unconditionally already.

Diff Detail

Event Timeline

mgorny updated this revision to Diff 74048.Oct 8 2016, 2:24 PM
mgorny retitled this revision from to [Driver] Pass -lunwind when using libc++ + compiler-rt.
mgorny updated this object.
mgorny added reviewers: ddunbar, EricWF, rsmith, phosek.
mgorny added a subscriber: cfe-commits.
joerg added a subscriber: joerg.Oct 8 2016, 2:35 PM

So, what's the test change that matches the difference in output this creates?

mgorny planned changes to this revision.Oct 8 2016, 3:31 PM

I knew this looked too easy ;-).

mgorny updated this revision to Diff 74064.Oct 9 2016, 2:52 AM
mgorny added a reviewer: joerg.

I've updated the NetBSD tests (@joerg, please confirm if it's desired), and added a Linux test for the case. AFAICS most of the other targets override the method, some of them adding -lunwind already. I'd rather not modify the other targets that I don't really know.

joerg edited edge metadata.Oct 9 2016, 5:08 AM

No, they are not desirable, in fact, they pretty much break clang. That's why I wanted to see the test diff...

joerg added a comment.Oct 9 2016, 5:10 AM

I don't agree with the motivation for this change, BTW. Whether -lunwind is needed or not is an implementation detail of the way the ABI implementation is linked. That's why libc++ is now a linker script, to hide this kinds of implementation details.

No, they are not desirable, in fact, they pretty much break clang. That's why I wanted to see the test diff...

Thank you for your feedback. However, I would really appreciate if you kindly said what you meant up front next time instead of requesting me to perform pointless work. You should note that your behavior as well as tone is strongly discouraging to contributors like me, and I doubt this is really of any benefit to anyone.

mgorny updated this revision to Diff 74115.Oct 10 2016, 3:37 AM
mgorny retitled this revision from [Driver] Pass -lunwind when using libc++ + compiler-rt to [Driver] Pass -lunwind when using libc++ + compiler-rt on Linux.
mgorny updated this object.
mgorny edited edge metadata.

I've updated the patch to apply to Linux toolchain only.

joerg added a comment.Oct 10 2016, 4:39 AM

It's difficult to say whether if one change to certain driver functions affect some target or not. That's one reason why the test change is so important.

Looking at the latest version, I still don't understand why the change for Linux is needed. libc++ should provide a linker script now and that should include -lunwind as appropriate.

It's difficult to say whether if one change to certain driver functions affect some target or not. That's one reason why the test change is so important.

Looking at the latest version, I still don't understand why the change for Linux is needed. libc++ should provide a linker script now and that should include -lunwind as appropriate.

Most importantly, the linker script can't predict which -rtlib will be used and therefore whether -lgcc_s or -lunwind should be used.

Hahnfeld added inline comments.
lib/Driver/ToolChains.cpp
4704 ↗(On Diff #74115)

As just written in D25008: This will probably result in problems if a system default libunwind.so.8 is installed...

mgorny added inline comments.Oct 24 2016, 5:59 AM
lib/Driver/ToolChains.cpp
4704 ↗(On Diff #74115)

I think this is the correct behavior in this case. Clang should work with whichever unwinder implementation is available, and if you want to change that, change the libunwind.so symlink.

However, I don't really think it's a good idea to have both unwinder libraries installed alongside, especially that they are sharing the same name.

Hahnfeld added inline comments.Oct 24 2016, 6:05 AM
lib/Driver/ToolChains.cpp
4704 ↗(On Diff #74115)

No, we can't: The nongnu libunwind is used by other system libraries that need and are tested against this version.

It's certainly not a good idea, but it's reality in many distros. Most of them don't ship LLVM's libunwind.

mgorny added inline comments.Oct 24 2016, 6:16 AM
lib/Driver/ToolChains.cpp
4704 ↗(On Diff #74115)

Well, IMO only sane solution to the problem is to have LLVM's libunwind renamed. Otherwise, using the two libraries is going always to be an unreliable, awful hackery with high risk that someone will accidentally end up with wrong one or -- even worse -- both of them in the same executable.

Hahnfeld added inline comments.Oct 24 2016, 6:27 AM
lib/Driver/ToolChains.cpp
4704 ↗(On Diff #74115)

Well, then the worse thing will happen with this patch if both libraries are installed...

ddunbar resigned from this revision.Jan 17 2017, 11:38 AM
mgorny updated this revision to Diff 85875.Jan 26 2017, 1:48 AM
mgorny retitled this revision from [Driver] Pass -lunwind when using libc++ + compiler-rt on Linux to [Driver] Pass -lunwind along with compiler-rt when necessary on Linux.
mgorny edited the summary of this revision. (Show Details)

Here's a v2. It turns out that you also need -lunwind when using to link C programs with -static -rtlib=compiler-rt. I've also disabled the changes for Android targets.

compnerd requested changes to this revision.Jan 26 2017, 6:42 PM
compnerd added a subscriber: compnerd.

This really needs a new driver flag (-unwinder?) similar to -rtlib, as there are multiple unwinders, and it is unclear which unwinder is the proper one on a given target. This has been something on my TODO list for a while. Mixing and matching undwinders is not really possible, and it is perfectly valid to use compiler-rt with the gcc unwinder on Linux.

This revision now requires changes to proceed.Jan 26 2017, 6:42 PM
mgorny added a comment.Mar 8 2017, 1:29 PM

@compnerd, I presume that the option would do nothing when using -rtlib=libgcc, correct? Or do we support combining libgcc with another unwinder?