boost :: smart_pointer中的seg fault

时间:2015-03-19 14:11:49

标签: c++ multithreading boost

我遇到了以下分段错误:

Program terminated with signal 11, Segmentation fault.
#0  0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
145             dispose();
Missing separate debuginfos, use: debuginfo-install boost-filesystem-   1.41.0-11.el6_1.2.x86_64 boost-program-options-1.41.0-11.el6_1.2.x86_64 boost-system-1.41.0-11.el6_1.2.x86_64 bzip2-libs-1.0.5-7.el6_0.x86_64 glibc-2.12-1.80.el6.x86_64 libgcc-4.4.6-4.el6.x86_64 libstdc++-4.4.6-4.el6.x86_64 lzo-2.03-3.1.el6.x86_64
(gdb) bt
#0  0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
#1  boost::detail::shared_count::~shared_count (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/shared_count.hpp:217
#2  0x00007f13fad83dab in boost::detail::set_tss_data(void const*, boost::shared_ptr<boost::detail::tss_cleanup_function>, void*, bool) ()
 from /usr/local/lib/libboost_thread.so.1.40.0
#3  0x000000000042e191 in boost::thread_specific_ptr<infrastructure::tfeed::sequenced_data_queue_element_t::mem_prealloc>::release (this=<value optimized out>)
at /usr/local/include/boost/thread/tss.hpp:95
#4  0x000000000042ed43 in  infrastructure::tfeed::sequenced_data_queue_element_t::operator new (size=16)
at ../../../infrastructure/include/tfeed/tfeed_multicast_defs.h:120

另外,我在另一个帖子中遇到了类似的seg错误:

(gdb) thread 5
[Switching to thread 5 (Thread 0x7f122e1fe700 (LWP 7547))]
#0   0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
145             dispose();
(gdb) bt
#0  0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
#1  boost::detail::shared_count::~shared_count (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/shared_count.hpp:217
#2  0x00007f13fad83dab in boost::detail::set_tss_data(void const*, boost::shared_ptr<boost::detail::tss_cleanup_function>, void*, bool) ()
from /usr/local/lib/libboost_thread.so.1.40.0
#3  0x000000000042e591 in release (q_elem=<value optimized out>) at /usr/local/include/boost/thread/tss.hpp:95
#4  infrastructure::tfeed::sequenced_data_queue_element_t::operator delete (q_elem=<value optimized out>)
at ../../../infrastructure/include/tfeed/tfeed_multicast_defs.h:144

/usr/local/include/boost/thread/tss.hpp:95处使用boost的特定于线程的指针时发生了这种情况(下面的set_tss_data()调用)

    T* release()
    {
        T* const temp=get();
                   detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
        return temp;
    }

并进一步了解sp_counted_base_gcc_x86.hpp(在dispose()处)

void release() // nothrow
{
    if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
    {
        dispose();
        weak_release();
    }
}

我正在使用特定于线程的指针,同时对数据结构进行专门的new和delete调用(sequenced_data_queue_element_t)。因为这个new和delete是从多个线程调用的:

  class sequenced_data_queue_element_t
  {
    public:
    sequenced_data_queue_element_t() {
    }
   ~sequenced_data_queue_element_t() {
        delete data;
    }

unsigned char* data;
uint32_t data_len;


typedef struct mem_prealloc
{
    struct mem_prealloc* next;
} mem_prealloc_t;

static boost::thread_specific_ptr<mem_prealloc_t> mem_prealloc_q_head;

static void* operator new(size_t size)
{
    mem_prealloc_t* q_elem;
    if (UNLIKELY(mem_prealloc_q_head.get() == NULL))
    {
        /* allocate PREALLOC_BATCH elems at a time */
        for (int i=0; i < MEM_PREALLOC_BATCH; i++)
        {
            q_elem = (mem_prealloc_t*)malloc(size);
            q_elem->next = mem_prealloc_q_head.release();
            mem_prealloc_q_head.reset(q_elem);
            cur_mem_prealloced += size;
        }
    }

    q_elem = mem_prealloc_q_head.release();
    mem_prealloc_q_head.reset(q_elem->next);
    return (void*)q_elem;
}

static void operator delete(void* q_elem)
{
   /* C++ guarantees that an object's destructor 
    * is automatically called just before delete executes. */
  /* next reuses the first pointer of sequenced_data_element_t */
    ((mem_prealloc_t*)q_elem)->next = mem_prealloc_q_head.release();
    mem_prealloc_q_head.reset((mem_prealloc_t*)q_elem);

    if (cur_mem_prealloced > MEM_PREALLOC_MAX_BYTES)
    {
        for (int i=0; i < MEM_PREALLOC_BATCH; i++)
        {
            mem_prealloc_t* qelem = mem_prealloc_q_head.release();
            mem_prealloc_q_head.reset(qelem->next);
            free(qelem);
            cur_mem_prealloced -= sizeof(sequenced_data_queue_element_t);
            if (mem_prealloc_q_head.get() == NULL)
                break;
        }
    }
}

};

cur_mem_prealloced(uint64_t)是一个全局变量。

触发此错误的可能原因是什么?

此外,该程序的一些其他线程的堆栈似乎已损坏。此外,核心转储显示其他线程的意外代码路径。

内核日志显示以下错误消息:

  [7547]: segfault at 10 ip 000000000040fbf6 sp 00007f122e1fcd90 error 4
  [7531]: segfault at 10 ip 000000000040fbf6 sp 00007fffc94bcca0 error 4 in tbt[400000+a0000] in tbt[400000+a0000]

在堆栈损坏的情况下是否可以触发这些seg错误?

0 个答案:

没有答案