使用boost :: signal和-D_GLIBCXX_DEBUG编译器标志时的段错误

时间:2010-07-01 19:13:10

标签: c++ boost-signals segmentation-fault

我正在用g ++构建,昨天一位有帮助的人告诉我使用-D_GLIBCXX_DEBUG-D_GLIBCXX_DEBUG_PEDANTIC标志进行编译。我这样做了,昨天我花了大部分时间调整代码以符合这些标志。现在它抱怨我使用boost::signal,我不确定问题出在哪里。

我有一个类Yarl,其函数refresh()我要绑定到另一个类sigRefresh中的信号EventHandler

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_PEDANTIC,它就会eventHandler.sigRefresh.connect上的段错误线。


我使用-D_GLIBCXX_DEBUG-D_GLIBCXX_DEBUG_PEDANTIC重新编译了提升,并没有解决问题,但在编译时我注意到它做了一些奇怪的事情。我使用这个命令编译了bjam(根据this boost教程):

sudo bjam --build-dir=. --toolset=gcc --variant=debug --cxxflags=-D_GLIBCXX_DEBUG,-D_GLIBCXX_DEBUG_PEDANTIC --layout=tagged stage

尽管有--variant=debug标记,它仍在编译发布版本。我也没有在输出中的任何地方看到我的调试标志。我编译错了可能吗?

1 个答案:

答案 0 :(得分:1)

  

我是否必须为发布代码和调试代码提供不同编译版本的boost?

我害怕你这样做。从个人经验来看,boost对编译器标志的变化非常敏感。几年前,我正在攻击的一个免费软件项目不得不停止使用boost::systemboost::filesystem,因为这些模块的共享库没有被Linux发行商可靠地编译(完全相同)标志作为我们的代码。症状是一样的 - 在正确的代码上无法解释崩溃。

因此我不得不建议不使用任何提供共享库的Boost模块。永远。很遗憾。