Modify

Ticket #4594 (closed Patches: fixed)

Opened 4 years ago

Last modified 22 months ago

Boost exception classes do not have GCC default visibility

Reported by: Jonathan Jones <jonathan.jones@…> Owned by: emildotchevski
Milestone: To Be Determined Component: exception
Version: Boost 1.47.0 Severity: Showstopper
Keywords: Cc: ejt@…

Description

All of the boost exception classes, including but not necessarily limited to:

  • boost::exception
  • boost::unknown_exception
  • boost::exception_detail::clone_base

do not have visibility attributes associated with them. This means that, when files are built using GCC with -fvisibility=hidden, classes derived from these types become uncatchable as these types when thrown across library boundaries.

Attachments

boost_visibility.tar Download (10.0 KB) - added by Jonathan Jones <jonathan.jones@…> 4 years ago.
Isolated reproduction code.
exception.patch Download (514 bytes) - added by Dimitrij Drus <dadrus@…> 3 years ago.
Patch for boost/exception/exception.hpp file
boost_visibility.2.tar Download (8.5 KB) - added by Jonathan Jones <jonathan.jones@…> 3 years ago.
Updated test case, including showing the fact that error_info/get_error_info also have symbol visibility issues.
thread_visibility.diff Download (2.1 KB) - added by Ethan Tira-Thompson <ejt@…> 3 years ago.
Patch to support visibility with thread module

Change History

Changed 4 years ago by Jonathan Jones <jonathan.jones@…>

Isolated reproduction code.

comment:1 Changed 4 years ago by Jonathan Jones <jonathan.jones@…>

Would it be possible to get an update as to the status of this bug?

comment:2 Changed 3 years ago by Vicente Botet <vicente.botet@…>

  • Type changed from Bugs to Patches

comment:3 Changed 3 years ago by emildotchevski

  • Status changed from new to closed
  • Resolution set to fixed

comment:4 Changed 3 years ago by Dimitrij Drus

I just moved to the 1.46.1 version of boost. It still lacks the visibility support for boost::exception. The trunk has corresponding adjustments, which however are not complete. Within the exception.hpp there is a forward declaration of the exception class. Without surrounding this forward declaration with GCC visibility pragmas too, the boost::exception can't be catched if throwed across the shared lib boundaries.

The behaviour was observed on Ubuntu 10.04 with gcc version 4.4.3.

comment:5 Changed 3 years ago by emildotchevski

Thanks for the feedback Dimitrij.

Have you verified that surrounding the forward declaration with visibility pragmas solves the problem? I don't have an easy way to test this so I'd appreciate a patch that is tested to work.

comment:6 Changed 3 years ago by Dimitrij Drus <dadrus@…>

Yes. Catching boost::exception thrown over the shared library boundaries is only possible after surrounding the forward declaration with the visibility pragmas. Patch is attached.

One can use the test attached by Jonathan to verify this. Jonathan, however, expects the class boost::exception_detail::clone_base be exported (surrounded with gcc visibility pragmas) too, that's why corresponding test cases fail.

Regards Dimitrij

Changed 3 years ago by Dimitrij Drus <dadrus@…>

Patch for boost/exception/exception.hpp file

comment:7 Changed 3 years ago by Dimitrij Drus <dadrus@…>

If one has troubles launching Jonathan's test, one should add -Wl,-rpath,'$ORIGIN' to the last line of the make file. In my case the libboost_visibility.so was not found without this modification.

I hope it is not too late to apply the path for the coming release.

Regards Dimitrij

Changed 3 years ago by Jonathan Jones <jonathan.jones@…>

Updated test case, including showing the fact that error_info/get_error_info also have symbol visibility issues.

comment:8 Changed 3 years ago by Jonathan Jones <jonathan.jones@…>

It's not enough to ensure that boost::exception, boost::exception_detail::clone_base, and boost::unknown_exception have default symbol visibility on GCC. It appears that boost::error_info also needs to be decorated with default visibility. Otherwise, calls to get_error_info on exceptions propagated across library boundaries will always return NULL, rendering boost::exception essentially useless.

comment:9 Changed 3 years ago by Dimitrij Drus <dadrus@…>

Why should one be interested in catching boost::exception_detail::clone_base? Its just an internal detail. Either one want catch an own exception or the boost one.

comment:10 Changed 3 years ago by Jonathan Jones <jonathan.jones@…>

You aren't interested in catching it directly. However, the implementation of boost::current_exception re-throws the exception and catches it as exception_detail::clone_base to determine if it's "cloneable". If exception_detail::clone_base doesn't have default visibility, boost::current_exception doesn't work if the exception originated from a different library.

comment:11 Changed 3 years ago by mark.schisler@…

This bug is actually causing X-Code 4.01 and LLVM/GCC 4.2 to not link Boost 1.46.1 correctly with or without symbols hidden. I ended up with the following linker error.

ld: bad codegen, pointer diff in boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::runtime_error> >::rethrow() constto global weak symbol vtable for boost::exceptionfor architecture i386
collect2: ld returned 1 exit status

I'm not sure if it's a minimal solution or not, but I was able to resolve the problem by applying a fix similar to what was suggested by Jonathan. I enclosed exception/exception.hpp and exception/detail/exception_ptr.hpp in the following guards:

#if defined(__GNUC__) 
# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) 
#  pragma GCC visibility push (default) 
# endif
#endif

#if defined(__GNUC__) 
# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) 
#  pragma GCC visibility pop 
# endif
#endif

comment:12 Changed 3 years ago by Ethan Tira-Thompson <ejt@…>

  • Cc ejt@… added
  • Status changed from closed to reopened
  • Version changed from Boost 1.40.0 to Boost 1.47.0
  • Resolution fixed deleted

I confirm Mark's error, I see the same error also with Boost 1.47 (building Ogre3D on Xcode 4, gcc 4.2.1).

I notice some visibility stuff was added to exception.hpp, but this is not enough. Apparently, error_info_injector and clone_impl (in exception/exception.hpp) both need to be wrapped with visibility pragmas in order to fix that error.

Further, thread/exceptions.hpp also needs to be wrapped with visibility, or you will get:

ld: bad codegen, pointer diff in boost::thread_exception::thread_exception()to global weak symbol vtable for boost::thread_exceptionfor architecture i386

Changed 3 years ago by Ethan Tira-Thompson <ejt@…>

Patch to support visibility with thread module

comment:13 Changed 3 years ago by Ethan Tira-Thompson <ejt@…>

Also, I'm not confident about the current visibility settings in exception. Will there be further linkage issues for other projects which use different features of boost?

Perhaps the visibility pragmas should be wrapped around the all of the header contents for exception.hpp and exception_ptr.hpp as Mark suggested to ensure this isn't an ongoing issue. (This doesn't look to be an excessive amount of additional visible symbols, worth the margin of safety?)

comment:14 Changed 3 years ago by emildotchevski

I am against making all classes visible. There aren't that many types that need to be visible. The first thing we need is a formal test in libs/exception/test. Can someone help writing this, so I can see all failures that need to be fixed on various platforms?

comment:15 follow-up: ↓ 16 Changed 2 years ago by ian.esten@…

I was having this problem with a dylib using boost::thread that linked to another dylib using boost::thread. The thread_visibility.diff patch solved the problem for me.

comment:16 in reply to: ↑ 15 Changed 2 years ago by emildotchevski

I've committed only the Boost Exception part of thread_visibility.diff patch (that is, without the Boost Thread part of it.) Out of curiosity, do we really need the error_info_injector type to be visible? I don't understand why it is needed, but I haven't tested.

Anyone care to add a test program to verify that visibility settings work across different platforms?

comment:17 Changed 2 years ago by shreyas.bme@…

Hi,

I am getting following error. Please guide me.

Boost version: 1_45_0

/ERROR LOGS/

ld: bad codegen, pointer diff in boost::signals::connection::connection(boost::signals::connection const&)to global weak symbol boost::detail::spinlock_pool<1>::pool_ for architecture armv7 collect2: ld returned 1 exit status Command /Developer/Platforms?/iPhoneOS.platform/Developer/usr/bin/g++-4.2 failed with exit code 1

comment:18 Changed 2 years ago by emildotchevski

Um, this doesn't seem to have anything to do with ticket 4594?

comment:19 Changed 2 years ago by shreyas.bme@…

Nope. Do you know solution? Please let me know.

comment:20 Changed 22 months ago by emildotchevski

  • Status changed from reopened to closed
  • Resolution set to fixed

I'm closing this, please reopen if visibility on some platform(s) is a problem.

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.