【发布时间】: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