将 boost::signal 与 -D_GLIBCXX_DEBUG 编译器标志一起使用时出现段错误
我正在使用 g++ 进行构建,昨天 SO 上的一位乐于助人的人告诉我使用 -D_GLIBCXX_DEBUG
和 -D_GLIBCXX_DEBUG_PEDATIC
标志进行编译。我这样做了,昨天我花了大部分时间调整我的代码以符合这些标志。现在它抱怨我使用 boost::signal
,我不确定问题出在哪里。
我有一个类 Yarl
,它有一个函数 refresh()
,我想将其绑定到另一个类 EventHandler< 中的信号
sigRefresh
/code>:
class Yarl
{
private:
void refresh();
(...)
};
class EventHandler
{
public:
boost::signal<void()> sigRefresh;
(...)
}
然后,在 Yarl
的成员函数中,我有这样一段代码:
EventHandler eventHandler;
eventHandler.sigRefresh.connect(boost::bind(&Yarl::refresh, this));
在我开始使用这些标志进行编译之前,这段代码运行良好。现在我正在使用它们,我的程序在第二行出现段错误。
这是 gdb 的回溯:
#0 0x001eeee6 in __gnu_debug::_Safe_iterator_base::_M_detach_single() ()
from /usr/lib/libstdc++.so.6
#1 0x001f0555 in __gnu_debug::_Safe_sequence_base::_M_detach_all() ()
from /usr/lib/libstdc++.so.6
#2 0x0804e8a3 in ~_Safe_sequence_base (this=0x812cda4,
__in_chrg=<value optimized out>)
at /usr/include/c++/4.4/debug/safe_base.h:180
#3 0x08085af9 in __gnu_debug::_Safe_sequence<std::__debug::vector<boost::signals::trackable const*, std::allocator<boost::signals::trackable const*> > >::~_Safe_sequence() ()
#4 0x08085b44 in std::__debug::vector<boost::signals::trackable const*, std::allocator<boost::signals::trackable const*> >::~vector() ()
#5 0x080873ab in boost::signals::detail::slot_base::data_t::~data_t() ()
#6 0x080873e3 in void boost::checked_delete<boost::signals::detail::slot_base::data_t>(boost::signals::detail::slot_base::data_t*) ()
#7 0x0808802e in boost::detail::sp_counted_impl_p<boost::signals::detail::slot_base::data_t>::dispose() ()
#8 0x08083d04 in boost::detail::sp_counted_base::release (this=0x812ce30)
at /usr/local/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
#9 0x08083d76 in ~shared_count (this=0xbffff358,
__in_chrg=<value optimized out>)
at /usr/local/boost/smart_ptr/detail/shared_count.hpp:217
#10 0x08083f70 in ~shared_ptr (this=0xbffff354,
__in_chrg=<value optimized out>)
at /usr/local/boost/smart_ptr/shared_ptr.hpp:169
#11 0x080847f1 in ~slot_base (this=0xbffff354, __in_chrg=<value optimized out>)
at /usr/local/boost/signals/slot.hpp:27
#12 0x08084829 in ~slot (this=0xbffff354, __in_chrg=<value optimized out>)
at /usr/local/boost/signals/slot.hpp:105
#13 0x0808390f in yarl::Yarl::mainLoop (this=0xbffff3dc) at src/Yarl.cpp:408
#14 0x08083a96 in yarl::Yarl::startGame (this=0xbffff3dc) at src/Yarl.cpp:452
#15 0x08083abe in main () at src/Yarl.cpp:461
有人知道我应该修复什么吗?
编辑:我有一个小示例程序来说明这个问题,正如 Daniel Trebbien 所建议的。
这是头文件(test.hpp):
#include <boost/bind.hpp>
#include <boost/signal.hpp>
#include <iostream>
#include <tr1/memory>
namespace yarl
{
class Yarl
{
private:
void refresh();
public:
void hookSignal();
};
namespace events
{
class EventHandler
{
public:
boost::signal<void()> sigRefresh;
};
}
}
这是实现:
#include "test.hpp"
using namespace std;
namespace yarl
{
void Yarl::refresh()
{
cout << "in refresh" << endl;
}
void Yarl::hookSignal()
{
events::EventHandler eventHandler;
eventHandler.sigRefresh.connect(boost::bind(&Yarl::refresh, this));
eventHandler.sigRefresh();
}
}
int main()
{
yarl::Yarl y;
y.hookSignal();
}
和以前一样,这个示例程序在仅使用 -g
标志的 g++ 中编译时工作正常,但如果我添加 -D_GLIBCXX_DEBUG
和 -D_GLIBCXX_DEBUG_PEDATIC
,它在 eventHandler.sigRefresh.connect
行上出现段错误。
我用 -D_GLIBCXX_DEBUG
和 -D_GLIBCXX_DEBUG_PEDATIC
重新编译了 boost,它没有解决问题,但在编译时我注意到它做了一些奇怪的事情。我使用此命令使用 bjam 进行编译(根据 这个 boost教程):
sudo bjam --build-dir=. --toolset=gcc --variant=debug --cxxflags=-D_GLIBCXX_DEBUG,-D_GLIBCXX_DEBUG_PEDANTIC --layout=tagged stage
尽管有--variant=debug
标签,它仍然在编译发行版本。我也没有在输出中的任何地方看到任何提及我的调试标志的信息。难道是我编译错了?
I'm building with g++, and yesterday a helpful person on SO told me to compile with the -D_GLIBCXX_DEBUG
and -D_GLIBCXX_DEBUG_PEDANTIC
flags. I did so, and I spent most of yesterday tweaking my code to conform to these flags. Now it's complaining about my use of boost::signal
, and I'm not sure where the problem is.
I have a class Yarl
that has a function refresh()
that I want to bind to a signal sigRefresh
in another class EventHandler
:
class Yarl
{
private:
void refresh();
(...)
};
class EventHandler
{
public:
boost::signal<void()> sigRefresh;
(...)
}
Then, in a member function of Yarl
, I have this bit of code:
EventHandler eventHandler;
eventHandler.sigRefresh.connect(boost::bind(&Yarl::refresh, this));
Before I started compiling with those flags, this code ran fine. Now that I'm using them, my program segfaults at the second line.
Here's the backtrace from gdb:
#0 0x001eeee6 in __gnu_debug::_Safe_iterator_base::_M_detach_single() ()
from /usr/lib/libstdc++.so.6
#1 0x001f0555 in __gnu_debug::_Safe_sequence_base::_M_detach_all() ()
from /usr/lib/libstdc++.so.6
#2 0x0804e8a3 in ~_Safe_sequence_base (this=0x812cda4,
__in_chrg=<value optimized out>)
at /usr/include/c++/4.4/debug/safe_base.h:180
#3 0x08085af9 in __gnu_debug::_Safe_sequence<std::__debug::vector<boost::signals::trackable const*, std::allocator<boost::signals::trackable const*> > >::~_Safe_sequence() ()
#4 0x08085b44 in std::__debug::vector<boost::signals::trackable const*, std::allocator<boost::signals::trackable const*> >::~vector() ()
#5 0x080873ab in boost::signals::detail::slot_base::data_t::~data_t() ()
#6 0x080873e3 in void boost::checked_delete<boost::signals::detail::slot_base::data_t>(boost::signals::detail::slot_base::data_t*) ()
#7 0x0808802e in boost::detail::sp_counted_impl_p<boost::signals::detail::slot_base::data_t>::dispose() ()
#8 0x08083d04 in boost::detail::sp_counted_base::release (this=0x812ce30)
at /usr/local/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
#9 0x08083d76 in ~shared_count (this=0xbffff358,
__in_chrg=<value optimized out>)
at /usr/local/boost/smart_ptr/detail/shared_count.hpp:217
#10 0x08083f70 in ~shared_ptr (this=0xbffff354,
__in_chrg=<value optimized out>)
at /usr/local/boost/smart_ptr/shared_ptr.hpp:169
#11 0x080847f1 in ~slot_base (this=0xbffff354, __in_chrg=<value optimized out>)
at /usr/local/boost/signals/slot.hpp:27
#12 0x08084829 in ~slot (this=0xbffff354, __in_chrg=<value optimized out>)
at /usr/local/boost/signals/slot.hpp:105
#13 0x0808390f in yarl::Yarl::mainLoop (this=0xbffff3dc) at src/Yarl.cpp:408
#14 0x08083a96 in yarl::Yarl::startGame (this=0xbffff3dc) at src/Yarl.cpp:452
#15 0x08083abe in main () at src/Yarl.cpp:461
Anyone see what I should fix?
EDIT: I have a small sample program that illustrates the problem, as suggested by Daniel Trebbien.
Here's the header file (test.hpp):
#include <boost/bind.hpp>
#include <boost/signal.hpp>
#include <iostream>
#include <tr1/memory>
namespace yarl
{
class Yarl
{
private:
void refresh();
public:
void hookSignal();
};
namespace events
{
class EventHandler
{
public:
boost::signal<void()> sigRefresh;
};
}
}
and here's the implementation:
#include "test.hpp"
using namespace std;
namespace yarl
{
void Yarl::refresh()
{
cout << "in refresh" << endl;
}
void Yarl::hookSignal()
{
events::EventHandler eventHandler;
eventHandler.sigRefresh.connect(boost::bind(&Yarl::refresh, this));
eventHandler.sigRefresh();
}
}
int main()
{
yarl::Yarl y;
y.hookSignal();
}
As before, this sample program works fine when compiled in g++ with only a -g
flag, but if I add -D_GLIBCXX_DEBUG
and -D_GLIBCXX_DEBUG_PEDANTIC
, it segfaults on the eventHandler.sigRefresh.connect
line.
I recompiled boost with -D_GLIBCXX_DEBUG
and -D_GLIBCXX_DEBUG_PEDANTIC
, and it didn't fix the problem, but while it was compiling I noticed it was doing something odd. I compiled with bjam using this command (according to this boost tutorial):
sudo bjam --build-dir=. --toolset=gcc --variant=debug --cxxflags=-D_GLIBCXX_DEBUG,-D_GLIBCXX_DEBUG_PEDANTIC --layout=tagged stage
despite the --variant=debug
tag, it was still compiling the release versions. I also didn't see any mention of my debug flags anywhere in the output. Is it possible I compiled it wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我担心你会的。从个人经验来看,boost 对编译器标志的变化极其敏感。几年前,我正在开发的一个自由软件项目不得不停止使用
boost::system
和boost::filesystem
只是因为这些模块具有共享库,而这些库不是(由 Linux 发行商)使用与我们的代码完全相同的标志进行可靠编译。症状是一样的——正确的代码出现莫名其妙的崩溃。因此,我建议不要使用任何附带共享库的 Boost 模块。曾经。很伤心。
I'm afraid you do. From personal experience, boost is extremely sensitive to changes in compiler flags. A few years ago a free software project I was hacking on had to stop using
boost::system
andboost::filesystem
just because those modules have shared libraries that weren't reliably compiled (by the Linux distributors) with exactly the same flags as our code. The symptoms were just the same - inexplicable crashes on correct code.Because of this I have to recommend not using any Boost module that ships a shared library. Ever. It's sad.