【问题标题】:boost::asio triggers a sigsegv in std::type_info::operator==boost::asio 在 std::type_info::operator== 中触发一个 sigsegv
【发布时间】:2015-04-10 05:01:48
【问题描述】:

所以,我有一个使用 boost::asio 的应用程序。由于项目的复杂性,我不能分享它的源代码,很遗憾:(

应用程序使用 boost 的 asio lib 来创建一些 web 服务。然而,当尝试使用它时,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。这是我目前能猜到的最好的了。

任何人都知道它为什么会这样失败,并且可以帮助我吗?

【问题讨论】:

  • 问题很可能不在于标准库或 Boost 代码,而在于您的代码以及您如何使用这些库。请创建一个Minimal, Complete, and Verifiable Example 并向我们展示您如何使用 Boost ASIO。
  • Joachim,我忘了补充一件事 - 当我在本地构建应用程序时,它可以完美运行。当我使用来自我们的构建服务器的版本时,它会失败。我的本地机器和构建服务器都在使用 Centos 7,除了触发一个 makefile 之外什么都不做。所以我怀疑这是我这边的事情。
  • @user905747 这是一个相当大胆的假设。也许它会意外工作(标准示例:您 deleted 某事并稍后访问它。这可能仍然有效,甚至可以重现,具体取决于系统及其配置)。您是否检查过您是否使用了不同的 Boost 版本并比较了这些版本?
  • 如果你有undefined behavior,即使是最小的东西也可能让它看起来有效。正如@filmor 所提到的,请检查版本号,不仅是 Boost,还有编译器、链接器以及您使用的几乎所有其他库,甚至可能是其他明显不相关的包。
  • @user905747 你有没有想过这个问题?我遇到了同样的问题stackoverflow.com/questions/32970935/…

标签: c++11 boost boost-asio segmentation-fault typeinfo


【解决方案1】:

服务似乎没有通过 typeid 找到服务对象。

这意味着库的某些部分没有被兼容编译。

要么包含您在运行时需要的所有共享对象/库(并确保它们已加载,而不是系统的),要么针对目标系统上的库版本重新编译您的应用程序.

(即使编译器标志的差异可能在某些平台上也会导致 ABI 不兼容)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多