Opened 8 years ago
Last modified 8 years ago
#11070 new Bugs
async_connect never calls back on mac with -fvisibility=hidden
Reported by: | blastrock | Owned by: | chris_kohlhoff |
---|---|---|---|
Milestone: | To Be Determined | Component: | asio |
Version: | Boost 1.55.0 | Severity: | Problem |
Keywords: | Cc: |
Description
See the attached file for a minimal code to reproduce. I have tested this on mac os yosemite with "Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)".
To test:
mkdir build cd build cmake .. make ./main
Result: The program never returns
Expected: The program finishes (possibly with a "connection refused" error)
What I do is to create a socket in the main binary (without using it) and do an async_connect in a library with hidden symbols.
This code works if I comment the -fvisibility=hidden line in the CMakeLists.txt or if I comment the socket creation in main().
This seems to be related to boost::asio::detail::service_registry::keys_match which compares service types. It relies on typeinfo to do that (unless BOOST_ASIO_NO_TYPEID is set).
For that to work, typeid_wrapper is forced to default visibility (see #pragma at boost/asio/detail/service_registry.hpp:32), but in recent mac os versions it seems that it is not enough anymore. It seems that a symbol Foo<T> is exported if and only if Foo AND T are set to default visibility. So, in this case, we have two typeinfos for the same type typeid_wrapper<stream_socket_service<ip::tcp>> and they are not merged at dynamic linking because the symbols are hidden.
One possible fix is to set default visibility to stream_socket_service and ip::tcp. This makes my example work, but it should be needed also for other services and protocols as well. I have made a patch for for this, but I don't know if this is the right way to fix it.
Attachments (2)
Change History (3)
by , 8 years ago
Attachment: | asiolock.tar.bz2 added |
---|
comment:1 by , 8 years ago
I found out this http://stackoverflow.com/questions/19496643/using-clang-fvisibility-hidden-and-typeinfo-and-type-erasure . It seems to be the exact problem that I saw here. It doesn't seem that it will be fixed in libc++, so something must be done in boost.
minimal code to reproduce