[Boost-bugs] [Boost C++ Libraries] #9465: Issues with kqueue_reactor, dynamic libraries and -fvisibility=hidden

Subject: [Boost-bugs] [Boost C++ Libraries] #9465: Issues with kqueue_reactor, dynamic libraries and -fvisibility=hidden
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-12-03 13:22:52


#9465: Issues with kqueue_reactor, dynamic libraries and -fvisibility=hidden
---------------------------------------------+----------------------------
 Reporter: avbica@… | Owner: chris_kohlhoff
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
  Version: Boost 1.54.0 | Severity: Problem
 Keywords: kqueu_reactor visibility hidden |
---------------------------------------------+----------------------------
 I've discovered a problem within a larger project for MacOS which uses
 multiple dynamic libraries and asio features (deadline_timers and tcp/udp
 sockets).

 After investigating the problem I've managed to reproduce it in the
 following minimal example:


 {{{
 ////////// Timer.hpp //////////

 #ifndef TIMER_HPP
 #define TIMER_HPP

 #include <boost/asio.hpp>
 #include <boost/thread.hpp>

 #define VISIBLE __attribute__ ((visibility ("default")))

 class VISIBLE Timer {
   public:
     Timer(boost::asio::io_service& service);
   private:
     void onTimeout(const boost::system::error_code& code);
     boost::asio::deadline_timer timer;
 };
 #endif // Timer_HPP


 ////////// Timer.cpp //////////

 #include <Timer.hpp>

 Timer::Timer(boost::asio::io_service& service) : timer(service) {
   timer.expires_from_now(boost::posix_time::seconds(1));
   timer.async_wait(boost::bind(&Timer::onTimeout, this, _1));
 }

 void Timer::onTimeout(const boost::system::error_code& code) {
   std::cout << "The callback from the dynamic library was called." <<
 std::endl;
 }


 ////////// main.cpp //////////

 #include <Timer.hpp>

 boost::asio::io_service service;

 void run() {
   service.run();
 }

 void onTimeout(const boost::system::error_code& code) {
   std::cout << "The callback from main was called." << std::endl;
 }

 int main() {
   Timer timer(service);
   boost::asio::deadline_timer deadline_timer(service);
   deadline_timer.expires_from_now(boost::posix_time::seconds(1));
   deadline_timer.async_wait(boost::bind(&onTimeout, _1));
   boost::thread t(boost::bind(&run));
   t.join();
   return 0;
 }

 }}}

 Timer.cpp is compiled into a dynamic library and used by main.cpp which is
 compiled as an executable.
 The environment: MacOS 10.8.5, Boost 1.54.0, clang 500.2.79

 The parameters which are passed to clang at compilation time are:


 {{{
 clang++ -ggdb -c Timer.cpp -I. -I/opt/local/include -fPIC
 -fvisibility=hidden
 }}}



 {{{
 clang++ -ggdb -o libTimer.dylib -dynamiclib Timer.o -L/opt/local/lib
 -lboost_thread-mt -lboost_system-mt -fvisibility=hidden
 }}}



 {{{
 clang++ -ggdb main.cpp -o runTest -I. -I/opt/local/include -L.
 -L/opt/local/lib -lboost_thread-mt -lboost_system-mt -lTimer
 fvisibility=hidden
 }}}


 The visibility is set to hidden at compilation time in order to expose
 only desired functions (e.g. the Timer class) from my library.
 The problem that arise is that the callback of the timer from main.cpp is
 never called.
 If I remove the visibility flag at compilation time the example works as
 it should (both timer callbacks are called).

 When I did further investigations I've observed that 2 kqueue_reactor
 instances are create when using hidden visibility and only one
 kqueue_reactor is created when visibility is set to default.

 When compiling the example on Linux using visibility set to hidden the
 example works as expected.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/9465>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:14 UTC