#4594 closed Patches (fixed)
Boost exception classes do not have GCC default visibility
Reported by: | Owned by: | Emil Dotchevski | |
---|---|---|---|
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 (4)
Change History (27)
by , 12 years ago
Attachment: | boost_visibility.tar added |
---|
comment:2 by , 12 years ago
Type: | Bugs → Patches |
---|
comment:3 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:4 by , 11 years ago
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 by , 11 years ago
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 by , 11 years ago
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
comment:7 by , 11 years ago
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
by , 11 years ago
Attachment: | boost_visibility.2.tar added |
---|
Updated test case, including showing the fact that error_info/get_error_info also have symbol visibility issues.
comment:8 by , 11 years ago
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 by , 11 years ago
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 by , 11 years ago
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 by , 11 years ago
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 by , 11 years ago
Cc: | added |
---|---|
Resolution: | fixed |
Status: | closed → reopened |
Version: | Boost 1.40.0 → Boost 1.47.0 |
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
by , 11 years ago
Attachment: | thread_visibility.diff added |
---|
Patch to support visibility with thread module
comment:13 by , 11 years ago
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 by , 11 years ago
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?
follow-up: 16 comment:15 by , 11 years ago
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 by , 11 years ago
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 by , 11 years ago
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:20 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
I'm closing this, please reopen if visibility on some platform(s) is a problem.
comment:21 by , 8 years ago
Hello everyone,
hope you had a good weekend, I am afraid the problem is back, moving from LLVM xcode 4.4.1 to Apple LLVM 6.0 (10.9), I got it again, but I think I am not the only one.
"boost::exception_detail::error_info_injector <boost::gregorian::bad_month>::error_info_injector(boost::exception_detail::error_info_injector<boost::gregorian::bad_month> const&) to global weak symbol vtable for boost::exception_detail::error_info_injector<boost::gregorian::bad_month> means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings."
the mysterious thin, and I think I need to question Ted Kremenek, because with the previous LD/compiler everything was fine according to their static analyzer, moving to the next version tool makes it incompatible, weak symbols that's just a convention how you stored them, Kremenek should use its magic wand and give solution.r
comment:22 by , 5 years ago
Hi:
i worked with boost1_58_0,it accors some error by compiled.please give me some suggest,thanks.
errors:
boost/asio/handler_type.hpp:20 boost/asio/detail/push_options.hpp:71:11: error :'pragma' is not allowed here
#pragma GCC visibility push(default)
boost/asio/detail/pop_options.hpp:71:11: error :expected decalration before end of line
Isolated reproduction code.