调用__do_global_dtors_aux时双重免费或腐败(!prev)

时间:2012-11-05 14:32:19

标签: c++ gcc memory-management g++

在我的应用完成所有操作后,我收到此错误消息

/lib64/libc.so.6[0x3f1ee70d7f]
/lib64/libc.so.6(cfree+0x4b)[0x3f1ee711db]
/home/user/workspace/NewProject/build/bin/TestApp(_ZN9__gnu_cxx13new_allocatorIN5boost10shared_ptrINS1_5uuids4uuidEEEE10deallocateEPS5_m+0x20)[0x49c174]
/home/user/workspace/NewProject/build/bin/TestApp(_ZNSt12_Vector_baseIN5boost10shared_ptrINS0_5uuids4uuidEEESaIS4_EE13_M_deallocateEPS4_m+0x32)[0x495b84]
/home/user/workspace/NewProject/build/bin/TestApp(_ZNSt12_Vector_baseIN5boost10shared_ptrINS0_5uuids4uuidEEESaIS4_EED2Ev+0x47)[0x49598b]
/home/user/workspace/NewProject/build/bin/TestApp(_ZNSt6vectorIN5boost10shared_ptrINS0_5uuids4uuidEEESaIS4_EED1Ev+0x65)[0x48bf27]
/lib64/libc.so.6(__cxa_finalize+0x8e)[0x3f1ee337fe]
/home/user/workspace/NewProject/build/components/lib_path/libhelper-d.so[0x2aaaab052b36]

如果我在gdb中运行该程序,我可以获得以下回溯,但这是我得到的:

#0  0x0000003f1ee30285 in raise () from /lib64/libc.so.6
#1  0x0000003f1ee31d30 in abort () from /lib64/libc.so.6
#2  0x0000003f1ee692bb in __libc_message () from /lib64/libc.so.6
#3  0x0000003f1ee70d7f in _int_free () from /lib64/libc.so.6
#4  0x0000003f1ee711db in free () from /lib64/libc.so.6
#5  0x000000000049c174 in __gnu_cxx::new_allocator<boost::shared_ptr<boost::uuids::uuid> >::deallocate (this=0x2aaaab2cea50, __p=0x1cfd8d0)
    at /opt/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.4.5/../../../../include/c++/4.4.5/ext/new_allocator.h:95
#6  0x0000000000495b84 in std::_Vector_base<boost::shared_ptr<boost::uuids::uuid>, std::allocator<boost::shared_ptr<boost::uuids::uuid> > >::_M_deallocate (
    this=0x2aaaab2cea50, __p=0x1cfd8d0, __n=8) at /opt/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.4.5/../../../../include/c++/4.4.5/bits/stl_vector.h:146
#7  0x000000000049598b in std::_Vector_base<boost::shared_ptr<boost::uuids::uuid>, std::allocator<boost::shared_ptr<boost::uuids::uuid> > >::~_Vector_base (
    this=0x2aaaab2cea50, __in_chrg=<value optimized out>)
    at /opt/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.4.5/../../../../include/c++/4.4.5/bits/stl_vector.h:132
#8  0x000000000048bf27 in std::vector<boost::shared_ptr<boost::uuids::uuid>, std::allocator<boost::shared_ptr<boost::uuids::uuid> > >::~vector (this=0x2aaaab2cea50,
    __in_chrg=<value optimized out>) at /opt/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.4.5/../../../../include/c++/4.4.5/bits/stl_vector.h:313
#9  0x0000003f1ee337fe in __cxa_finalize () from /lib64/libc.so.6
#10 0x00002aaaab052b36 in __do_global_dtors_aux ()
from /home/user/workspace/NewProject/build/components/lib_path/libhelper-d.so
#11 0x0000000000000000 in ?? ()

我真的不知道如何从这里开始。

更新我忘了提到错误中显示的唯一全局变量类型会在错误出现时被清除m_uuids.size() == 0

2 个答案:

答案 0 :(得分:5)

我使用glog遇到同样的问题。就我而言,就是这种情况:

  1. 我有一个共享库,称之为'common.so',它链接了glog。
  2. 我的主要可执行文件,称之为'app'也链接了glog,并在common.so中链接。
  3. 我遇到的问题是glog在.so和exectuable中都是静态链接的。当我改变#1和#2来链接.so而不是.a时,问题就消失了。

    不确定这是你的问题,但可能是。一般来说,释放内存时的损坏通常意味着您损坏了内存池(例如两次删除相同的指针)。我相信在两种情况下都链接.a,我在同一个全局指针(在我的情况下是一个std :: string)上得到两次清理行为。

    更新: 经过多次调查,这很可能是问题所在。会发生的是每个可执行文件和.so都有一个std :: string类型的全局变量(glog的一部分)。当动态链接器/加载器加载对象(exe,.so)时,必须构造这些std :: string全局变量。此外,使用 at_exit 添加每个析构函数以进行清理。但是,当调用 at_exit 函数时,两个全局引用都指向同一个std :: string。这意味着std :: string析构函数被调用两次,但是在同一个对象上。然后两次在同一个内存位置调用 free 。全局std :: string(或任何带有构造函数的类)都是个坏主意。如果您选择基于.so的架构(一个好主意),您必须小心所有第三方库以及它们如何处理全局变量。通过链接到所有第三方图书馆的.so,您可以远离危险。

答案 1 :(得分:1)

出现错误的地方可能有点误导。我最好的猜测是你有一个共享指针的向量,当它被销毁时,这些共享指针中的一个(至少)试图删除它所指向的对象,却发现它已被删除

您是否将原始指针与共享指针混合在一起?如果是这样的话,你可能会发现一个完全无害的delete看起来正在从shared_ptr

的脚下拉地毯