Связывание libboost_log.so делает boost:: asio:: io_service:: run exit немедленно

Вот настройка:

boost1::asio::io_service         _ios;
boost::asio::ip::tcp::acceptor  _acceptor;`
...
_acceptor(_ios)
...
boost::system::error_code ec;
int rc = _ios.run(ec);

с gdb Я вижу, что вызов вызова вызова в boost:: asio:: impl:: io_service:: run
Вот немного повышения

повышение/ASIO/осущ/io_service.ipp:

std::size_t io_service::run(boost::system::error_code& ec)
{
  return impl_.run(ec);
}

Вот доказательство того, что impl_ является task_io_service для случая linux.

усиление/увеличение/ASIO/io_service.hpp

#if defined(BOOST_ASIO_HAS_IOCP)
namespace detail { typedef win_iocp_io_service io_service_impl; }
#else
namespace detail { typedef task_io_service io_service_impl; }
#endif

...

private:
  typedef detail::io_service_impl impl_type;
#if defined(BOOST_ASIO_HAS_IOCP)
  friend class detail::win_iocp_overlapped_ptr;
#endif

...

impl_type& impl_;

Если во время компиляции я не связываю -lboost_log, тогда вызов impl_run разрешен (через вызов plt stub, ld_trampoline.S dl-runtime_resolve и dl-runtime.c _dl_fixup) для boost:: asio:: detail:: impl:: task_io_service:: запускается в моем двоичном и run() начинает ждать работы, предоставляемой акцептором.

Если я активирую ссылку, через GDB я вижу, что этот вызов должен быть разрешен для символа libboost_log.so _ZN5boost4asio6detail15task_io_service3runERNS_6system10error_codeE и завершает работу почти сразу.

nm -D libboost_log.so подтверждает, что символ есть, и это не моя проблема связывания.

Почему этот символ task_io_service3run в libboost_log.so? Кажется, что это ошибка увеличения, не так ли? Существуют ли способы обеспечения предполагаемого разрешения метода?

Ответ 1

Вкратце, разрешение символа времени выполнения в Linux работает с точки зрения видимости символа. Если символ внешне отображается в одном или нескольких общих объектах, загружаемых вашим приложением, тогда компоновщик времени выполнения может выбирать любую из реализаций и использовать его во всех других общих объектах. Это очень похоже на процесс компоновки времени компиляции, и это позволяет удерживать несколько языковых правил (например, если адрес функции должен давать один и тот же адрес, где бы в программе этот адрес не был сделан).

Boost.Log действительно использует Boost.ASIO для реализации некоторых своих функций (в частности, для системного syslog-сети). Boost.ASIO отмечает свои символы как внешне видимые, поэтому они экспортируются из общего объекта Boost.Log.

Теперь Boost.ASIO не использует пространство имен ABI или любой другой метод, чтобы сделать имена символов разными в зависимости от версии библиотеки или конфигурации. Это означает, что любое приложение или библиотека, использующая Boost.Log и Boost.ASIO, должна использовать ту же версию Boost.ASIO, которая была настроена так же, как и при создании Boost.Log. В противном случае из-за несовместимости ABI вы можете наблюдать все виды undefined поведения в вашем Boost.Log использовании Boost.ASIO. Я подозреваю, что это может быть причиной того, что у вас могут быть проблемы.

Убедитесь, что вы используете ту же версию Boost.ASIO при создании кода и Boost.Log. Убедитесь, что все макросы определены одинаково в обоих случаях. Проверьте, используете ли вы какие-либо связанные с ABI компиляторы.