boost::asio triggers a sigsegv in std::type_info::

2019-08-01 11:19发布

So, I've got an application that uses boost::asio. Due to complexity of the project, I cannot share it's source code, sadly :(

The application uses boost's asio lib to create some webservices. When attempting to use it, however, there's a sigsegv in std::type_info::operator==, which, as I'm aware, should rather work.

(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

The rest of backtrace ommited, as I don't think it would help anyway. When digging further into what GDB prints, that's what I get:

(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> > >>

The only theory I have as to why it works like that, is that the application consists of a main binary, which is statically linked to necessary libboost*.a, and it can load .so files as plugins, each also linked with the same libboost*.a. That's the best I can guess at this point.

Anybody has any idea as to why it fails like that, and could please help me with it?

1条回答
混吃等死
2楼-- · 2019-08-01 12:11

Looks like the service is not finding the service object by typeid.

This implies that parts of the library have not been compatibly compiled.

Either include all the shared objects/libraries that you require at runtime (and make sure they're loaded, and not the system ones) or recompile your application against the library versions on the target system.

(Even differences in compiler flags might cause ABI incompatibilities in some platforms)

查看更多
登录 后发表回答