boost::asio запускает sigsegv в std::type_info::operator==

Итак, у меня есть приложение, использующее boost::asio. К сожалению, из-за сложности проекта я не могу поделиться его исходным кодом :(

Приложение использует библиотеку asio от boost для создания некоторых веб-сервисов. Однако при попытке его использования в std::type_info::operator== есть sigsegv, который, насколько мне известно, должен работать.

(gdb) backtrace
#0  0x0000000000457b79 in std::type_info::operator== (
this=0x7ffff6dadf61 <typeinfo for boost::asio::detail::typeid_wrapper<boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >+1>, __arg=...)
at /usr/include/c++/4.8.2/typeinfo:123
#1  0x00007ffff6961911 in boost::asio::detail::service_registry::keys_match (key1=..., key2=...) at /usr/include/boost/asio/detail/impl/service_registry.ipp:94
#2  0x00007ffff69619a1 in boost::asio::detail::service_registry::do_use_service (this=0x6bd3c0, key=..., 
factory=0x7ffff6988ba8 <boost::asio::detail::service_registry::create<boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >(boost::asio::io_service&)>)
at /usr/include/boost/asio/detail/impl/service_registry.ipp:114
#3  0x00007ffff69842b6 in boost::asio::detail::service_registry::use_service<boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > > (this=0x6bd3c0)
at /usr/include/boost/asio/detail/impl/service_registry.hpp:48

Остальная часть обратной трассировки опущена, так как я не думаю, что это все равно поможет. При дальнейшем копании в том, что печатает GDB, вот что я получаю:

(gdb) frame 0
#0  0x0000000000457b79 in std::type_info::operator== (
this=0x7ffff6dadf61 <typeinfo for boost::asio::detail::typeid_wrapper<boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >+1>, __arg=...)
at /usr/include/c++/4.8.2/typeinfo:123
123                   || (__name[0] != '*' &&
(gdb) list
118             : __builtin_strcmp (__name, __arg.__name) < 0; }
119
120         bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT
121         {
122           return ((__name == __arg.__name)
123                   || (__name[0] != '*' &&
124                       __builtin_strcmp (__name, __arg.__name) == 0));
125         }
126       #else
127         // On some targets we can rely on type_info's NTBS being unique,
(gdb) print __name
$2 = 0xd000007ffff6afbc <Address 0xd000007ffff6afbc out of bounds>
(gdb) print __arg.__name
warning: can't find linker symbol for virtual table for `std::type_info' value
$3 = 0x7ffff6afbc60 <typeinfo name for boost::asio::detail::typeid_wrapper<boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >> "N5boost4asio6detail14typeid_wrapperINS0_22deadline_timer_serviceINS_10posix_time5ptimeENS0_11time_traitsIS5_EEEEEE"
(gdb) print __name[0]
Cannot access memory at address 0xd000007ffff6afbc
(gdb) frame 1
#1  0x00007ffff6961911 in boost::asio::detail::service_registry::keys_match (key1=..., key2=...) at /usr/include/boost/asio/detail/impl/service_registry.ipp:94
94          if (*key1.type_info_ == *key2.type_info_)
(gdb) list
89      {
90        if (key1.id_ && key2.id_)
91          if (key1.id_ == key2.id_)
92            return true;
93        if (key1.type_info_ && key2.type_info_)
94          if (*key1.type_info_ == *key2.type_info_)
95            return true;
96        return false;
97      }
98
(gdb) print key1.type_info_
$4 = (const std::type_info *) 0x7ffff6dadf61 <typeinfo for boost::asio::detail::typeid_wrapper<boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >+1>
(gdb) print *key1.type_info_
$5 = {_vptr.type_info = 0x6000000000006906, __name = 0xd000007ffff6afbc <Address 0xd000007ffff6afbc out of bounds>}
(gdb) print *key2.type_info_
warning: can't find linker symbol for virtual table for `std::type_info' value
$6 = warning: can't find linker symbol for virtual table for `std::type_info' value
{_vptr.type_info = 0x6906d0 <_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3+16>, 
  __name = 0x7ffff6afbc60 <typeinfo name for boost::asio::detail::typeid_wrapper<boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >> "N5boost4asio6detail14typeid_wrapperINS0_22deadline_timer_serviceINS_10posix_time5ptimeENS0_11time_traitsIS5_EEEEEE"}
(gdb) print key2.type_info_
$7 = (const std::type_info *) 0x7ffff6dadf60 <typeinfo for boost::asio::detail::typeid_wrapper<boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >>

Единственная теория, которая у меня есть относительно того, почему это так работает, заключается в том, что приложение состоит из основного бинарного файла, который статически связан с необходимым libboost*.a, и может загружать файлы .so как плагины, каждый из которых также связан с одним и тем же libboost*.a. Это лучшее, что я могу предположить на данный момент.

Кто-нибудь знает, почему это так не работает, и может помочь мне с этим?


person user905747    schedule 10.02.2015    source источник
comment
Проблема, скорее всего, не в стандартной библиотеке или коде Boost, а в вашем коде и в том, как вы используете библиотеки. Создайте минимальный, полный и проверяемый пример и покажите нам, как вы используете Boost ASIO.   -  person Some programmer dude    schedule 10.02.2015
comment
Joachim, Одну вещь забыл добавить - приложение отлично работает, когда я его локально собираю. Это не удается, когда я использую версию с нашего сервера сборки. И моя локальная машина, и сервер сборки используют Centos 7 и не делают ничего, кроме запуска make-файла. Так что сомневаюсь, что это что-то с моей стороны.   -  person user905747    schedule 10.02.2015
comment
@ user905747 Это довольно смелое предположение. Возможно, это сработало случайно (стандартный пример: вы deleted что-то и получили к нему доступ позже. Это может все еще работать, даже воспроизводимо, в зависимости от системы и ее конфигурации). Вы проверяли, используете ли вы разные версии Boost и сравнивали выпуски?   -  person filmor    schedule 10.02.2015
comment
Если у вас неопределенное поведение, даже самая мелочь может заставить его работать. Как упоминает @filmor, проверяйте номера версий не только Boost, но и компилятора, компоновщика и почти любой другой библиотеки, которую вы используете, и, возможно, даже других явно не связанных пакетов.   -  person Some programmer dude    schedule 10.02.2015
comment
@ user905747 ты когда-нибудь это понимал? У меня похоже та же проблема stackoverflow.com/questions/32970935/   -  person NeomerArcana    schedule 11.10.2015


Ответы (1)


Похоже, служба не находит объект службы по идентификатору типа.

Это означает, что части библиотеки не были скомпилированы для совместимости.

Либо включите все общие объекты/библиотеки, которые вам нужны во время выполнения (убедитесь, что они загружены, а не системные), либо перекомпилируйте приложение с учетом версий библиотек в целевой системе.

(Даже различия в флагах компилятора могут привести к несовместимости ABI на некоторых платформах)

person sehe    schedule 10.02.2015