使用带有-D_GLIBCXX_DEBUG编译器标志的boost :: signal时的segfault [英] segfault when using boost::signal with -D_GLIBCXX_DEBUG compiler flag

查看:124
本文介绍了使用带有-D_GLIBCXX_DEBUG编译器标志的boost :: signal时的segfault的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

我有一个类Yarl,它具有要与另一个类EventHandler中的信号sigRefresh绑定的函数refresh():

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;
    (...)
}

然后,在Yarl的成员函数中,我有这段代码:

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.

这是gdb的回溯记录:

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?

正如Daniel Trebbien所建议的,我有一个小的示例程序来说明问题.

I have a small sample program that illustrates the problem, as suggested by Daniel Trebbien.

这是头文件(test.hpp):

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;
        };
    }
}

这是实现:

#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行上进行段错误.

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.

我用-D_GLIBCXX_DEBUG-D_GLIBCXX_DEBUG_PEDANTIC重新编译了boost,它并不能解决问题,但是在编译时我注意到它在做些奇怪的事情.我使用此命令使用bjam进行了编译(根据

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

尽管使用--variant=debug标签,但

仍在编译发行版本.我也没有在输出中的任何地方看到我的调试标志的任何提及.我可能编译错了吗?

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?

推荐答案

对于发布代码和调试代码,我是否必须具有不同的boost编译版本?

Do I have to have differently compiled versions of boost for release code and debug code?

恐怕你愿意.根据个人经验,boost对编译器标志的更改非常敏感.几年前,我黑客入侵的一个免费软件项目不得不停止使用boost::systemboost::filesystem,只是因为这些模块具有共享库,这些库没有(由Linux发行商)可靠地编译,并且具有与我们的代码完全相同的标志.症状是相同的-正确的代码导致莫名其妙的崩溃.

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 and boost::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.

因此,我必须建议不要使用附带共享库的任何Boost模块.曾经.真伤心.

Because of this I have to recommend not using any Boost module that ships a shared library. Ever. It's sad.

这篇关于使用带有-D_GLIBCXX_DEBUG编译器标志的boost :: signal时的segfault的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆