C++ Segfault在声明vector类型的变量时出错<;共享\u ptr<;int>&燃气轮机; 代码

C++ Segfault在声明vector类型的变量时出错<;共享\u ptr<;int>&燃气轮机; 代码,c++,gcc,segmentation-fault,redhat,ld,C++,Gcc,Segmentation Fault,Redhat,Ld,这是给出SEGFULT的程序 #include <iostream> #include <vector> #include <memory> int main() { std::cout << "Hello World" << std::endl; std::vector<std::shared_ptr<int>> y {}; std::cout << "Hello

这是给出SEGFULT的程序

#include <iostream>
#include <vector>
#include <memory>

int main() 
{
    std::cout << "Hello World" << std::endl;

    std::vector<std::shared_ptr<int>> y {};  

    std::cout << "Hello World" << std::endl;
}
但是,如果我运行它,而不设置
LD\u LIBRARY\u路径
。它运行良好


诊断学 1.ldd 以下是这两种情况下的
ldd
信息(请注意,我编辑了输出,在有差异的地方提到了库的完整版本)

并且没有LD_LIBRARY_路径:

$ ldd ./build/bin/run

linux-vdso.so.1 =>  (0x00007fffcedde000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6.0.16 
libgcc_s.so.1 => /lib64/libgcc_s-4.4.6-20110824.so.1
libc.so.6 => /lib64/libc.so.6 
libm.so.6 => /lib64/libm.so.6 
/lib64/ld-linux-x86-64.so.2 (0x0000560caff38000)
2.当gdb发生故障时 3.LD_DEBUG=all 我还试图通过为segfault案例启用
LD_DEBUG=all
来查看链接器信息。我发现了一些可疑的东西,因为它搜索了一次
pthread\u
symbol,当它找不到这个时,它给出了segfault(这是我对以下输出片段的解释):

但是我没有看到任何
pthread\u一次
成功运行的情况


问题 我知道像这样调试是非常困难的,可能我还没有给出很多关于环境和所有方面的信息。但是,我的问题是:这一故障的可能根本原因是什么?如何进一步调试并找到它?一旦我发现问题,修复将很容易


编译器与平台 我正在RHEL5上使用GCC4.9


实验 E#1 如果我评论下一行:

std::vector<std::shared_ptr<int>> y {}; 
它成功地运行了

接下来,我在
libboost\u系统上执行了
ldd
。因此
给出了一个lib列表,其中两个是:

  /lib64/librt.so.1
  /lib64/libpthread.so.0
因此,我没有预加载
libboost\u系统
,而是分别预加载
librt
libpthread

$ LD_PRELOAD=/lib64/librt.so.1 $project_dir/build/bin/run

$ LD_PRELOAD=/lib64/libpthread.so.0 $project_dir/build/bin/run
在这两种情况下,它都成功运行

现在我的结论是,通过加载
librt
libpthread
(或同时加载两者),可以满足某些要求,或者绕过问题!不过,我仍然不知道这个问题的根本原因


汇编和链接选项 因为构建系统很复杂,默认情况下有很多选项。因此,我尝试使用CMake的
set
命令显式添加
-lpthread
,然后它工作了,正如我们已经看到的那样,通过预加载
libpthread
它工作了

为了查看这两种情况之间的构建差异(当它工作时和给出segfault时),我在详细模式下通过将
-v
传递给GCC来构建它,以查看编译阶段以及它实际传递给
cc1plus
(编译器)和
collect2
(链接器)的选项

(请注意,为简洁起见,已使用美元符号和虚拟路径对路径进行了编辑。)

$/gcc-4.9.4/cc1plus-quiet-v-I/a/include-I/b/include-iprefix $/gcc-4.9.4/-MMD main.cpp.d-MF main.cpp.o.d-MT main.cpp.o -D_GNU_SOURCE-D_REENTRANT-D_使用XOPEN2K8-D_LARGEFILE_SOURCE-D_FILE_OFFSET_BITS=64-D_STDC_FORMAT_MACROS-D_STDC_LIMIT_MACROS-D NDEBUG$/lab/main.cpp-quiet-dumpbase main.cpp-msse-mfpmath=sse-march=core2-auxbase strip-main.cpp.o-g-O3-O3-Wall-Wextra-std=GNU-version=fdy=128-deptic-fno操作员名称-o/tmp/ccxfkRyd.s

无论它是否工作,cc1plus的命令行参数都是完全相同的。没什么区别。这似乎不是很有帮助

然而,区别在于链接时间。以下是我看到的,适用于它工作时的情况:

$/gcc-4.9.4/collect2-plugin$/gcc-4.9.4/liblto_plugin.so
-plugin opt=$/gcc-4.9.4/lto-wrapper-plugin opt=-fresolution=/tmp/cchl8RtI.res-plugin opt=-pass through=-lgcc_s-plugin opt=-pass through=-lgcc-plugin opt=-pass through=-lpthread-plugin opt=-lc=-pass=-lc-plugin-pass through=-lgcc_-s-plugin opt=-pass=-lgcc=-lgcc-eh-frame hdr-m elf-x86\u 64-导出动态链接器/lib64/ld-linux-x86-64.so.2-o运行/usr/lib/。/lib64/crt1.o /usr/lib/./lib64/crti.o$/gcc-4.9.4/crtbegin.o-L/a/lib-L/b/lib -L/c/lib -lpthread-根据需要main.cpp.o-lboost\u timer-lboost\u wave-lboost\u chrono-lboost\u filesystem-lboost\u graph-lboost\u locale-lboost\u thread-lboost\u序列化-lboost\u原子-lboost\u上下文-lboost\u日期\u时间-lboost\u丢失流-lboost\u数学-lboost\u数学lboost\u数学lboost\u c99f-lboost\u数学lboost\u 1-lboost\u数学\u tr1l-lboost\u mpi-lboost\u prg\u exec\u监视器-lboost\u程序选项-lboost\u随机-lboost\u正则表达式-lboost\u序列化-lboost\u信号-lboost\u系统-lboost\u单元测试框架-lboost\u异常-lboost\u测试\u exec\u监视器-lbz2-LICUUCUI18N-LICUUCUC-LICUUDATA-lz-rpath/a/lib:/b/lib:/c/lib:/c/lib:/L-LGU-CC-lpthread-lc-lgcc_-lgcc$/gcc-4.9.4/crtend.o/usr/lib/。/lib64/crtn.o

如您所见,
-lpthread
被提到了两次!第一个
-lpthread
(后面跟着
-根据需要
)在给出segfault时丢失。这是这两种情况之间的唯一区别


两种情况下
nm-C的输出
有趣的是,
nm-C
在这两种情况下的输出是相同的(如果忽略第一列中的整数值)

0000000000 402580 d\u动态
0000000000 402798 d_全局_偏移表_
0000000000 401000吨全球分输干管
0000000000 401358 R_IO_stdinu使用
w_ITM_注销可克隆
w_ITM_寄存器克隆表
w_Jv_注册类别
你(放松)你(恢复)
0000000000 401150 W标准::_Sp_counted_base::_M_destroy()
0000000000 401170 W标准::向量::~vector()
0000000000 401170 W标准::向量::~vector()
0000000000 401250 W标准::向量::~vector()
0000000000 401250 W标准::向量::~vector()
U std::ios_base::Init::Init()
U std::ios_base::Init::~Init()
0000000000 402880 B标准::cout
U std::basic_ostream&std::endl(std::basic_ostream&)
000
initialize program: $project_dir/build/bin/run

symbol=_ZNSt8ios_base4InitC1Ev;  lookup in file=$project_dir/build/bin/run [0]
symbol=_ZNSt8ios_base4InitC1Ev;  lookup in file=$project_dir/build/lib/libstdc++.so.6 [0]
binding file $project_dir/build/bin/run [0] to $project_dir/build/lib/libstdc++.so.6 [0]: normal symbol `_ZNSt8ios_base4InitC1Ev' [GLIBCXX_3.4]
symbol=_ZNSt6localeC1Ev;  lookup in file=$project_dir/build/bin/run [0]
symbol=_ZNSt6localeC1Ev;  lookup in file=$project_dir/build/lib/libstdc++.so.6 [0]
binding file $project_dir/build/lib/libstdc++.so.6 [0] to $project_dir/build/lib/libstdc++.so.6 [0]: normal symbol `_ZNSt6localeC1Ev' [GLIBCXX_3.4]
symbol=pthread_once;  lookup in file=$project_dir/build/bin/run [0]
symbol=pthread_once;  lookup in file=$project_dir/build/lib/libstdc++.so.6 [0]
symbol=pthread_once;  lookup in file=$project_dir/build/lib/libgcc_s.so.1 [0]
symbol=pthread_once;  lookup in file=/lib64/libc.so.6 [0]
symbol=pthread_once;  lookup in file=/lib64/libm.so.6 [0]
symbol=pthread_once;  lookup in file=/lib64/ld-linux-x86-64.so.2 [0]
std::vector<std::shared_ptr<int>> y {}; 
#include <boost/filesystem.hpp>
$ LD_PRELOAD=$project_dir/build/lib/libboost_system.so $project_dir/build/bin/run
  /lib64/librt.so.1
  /lib64/libpthread.so.0
$ LD_PRELOAD=/lib64/librt.so.1 $project_dir/build/bin/run

$ LD_PRELOAD=/lib64/libpthread.so.0 $project_dir/build/bin/run
0000000000402580 d _DYNAMIC
0000000000402798 d _GLOBAL_OFFSET_TABLE_
0000000000401000 t _GLOBAL__sub_I_main
0000000000401358 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
                 U _Unwind_Resume
0000000000401150 W std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_destroy()
0000000000401170 W std::vector<std::shared_ptr<int>, std::allocator<std::shared_ptr<int> > >::~vector()
0000000000401170 W std::vector<std::shared_ptr<int>, std::allocator<std::shared_ptr<int> > >::~vector()
0000000000401250 W std::vector<std::unique_ptr<int, std::default_delete<int> >, std::allocator<std::unique_ptr<int, std::default_delete<int> > > >::~vector()
0000000000401250 W std::vector<std::unique_ptr<int, std::default_delete<int> >, std::allocator<std::unique_ptr<int, std::default_delete<int> > > >::~vector()
                 U std::ios_base::Init::Init()
                 U std::ios_base::Init::~Init()
0000000000402880 B std::cout
                 U std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
0000000000402841 b std::__ioinit
                 U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
                 U operator delete(void*)
                 U operator new(unsigned long)
0000000000401510 r __FRAME_END__
0000000000402818 d __JCR_END__
0000000000402818 d __JCR_LIST__
0000000000402820 d __TMC_END__
0000000000402820 d __TMC_LIST__
0000000000402838 A __bss_start
                 U __cxa_atexit
0000000000402808 D __data_start
0000000000401100 t __do_global_dtors_aux
0000000000402820 t __do_global_dtors_aux_fini_array_entry
0000000000402810 d __dso_handle
0000000000402828 t __frame_dummy_init_array_entry
                 w __gmon_start__
                 U __gxx_personality_v0
0000000000402838 t __init_array_end
0000000000402828 t __init_array_start
00000000004012b0 T __libc_csu_fini
00000000004012c0 T __libc_csu_init
                 U __libc_start_main
                 w __pthread_key_create
0000000000402838 A _edata
0000000000402990 A _end
000000000040134c T _fini
0000000000400e68 T _init
0000000000401028 T _start
0000000000401054 t call_gmon_start
0000000000402840 b completed.6661
0000000000402808 W data_start
0000000000401080 t deregister_tm_clones
0000000000401120 t frame_dummy
0000000000400f40 T main
00000000004010c0 t register_tm_clones
  void
  locale::_S_initialize()
  {
#ifdef __GTHREADS
    if (__gthread_active_p())
      __gthread_once(&_S_once, _S_initialize_once);
#endif
    if (!_S_classic)
      _S_initialize_once();
  }