当libstdc++内部报错的时候一般不会深入调试,更多的是从自身代码来找问题。一方面是标准库出错的可能性较小,另一方面libstdc++的调试也不是很方便,默认的libstdc++不带符号表,stack一般定位不到具体的文件行号,比如:
(gdb) bt
#0 0x0000003ebda30265 in raise () from /lib64/libc.so.6
#1 0x0000003ebda31d10 in abort () from /lib64/libc.so.6
#2 0x0000003ec46bed14 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib64/libstdc++.so.6
#3 0x0000003ec46bce16 in ?? () from /usr/lib64/libstdc++.so.6
#4 0x0000003ec46bce43 in std::terminate() () from /usr/lib64/libstdc++.so.6
#5 0x0000003ec46bcf2a in __cxa_throw () from /usr/lib64/libstdc++.so.6
#6 0x0000003ec46bd239 in operator new(unsigned long) () from /usr/lib64/libstdc++.so.6
#7 0x0000003ec469b861 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) () from /usr/lib64/libstdc++.so.6
#8 0x0000003ec469c23b in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_M_clone(std::allocator<char> const&, unsigned long) () from /usr/lib64/libstdc++.so.6
#9 0x0000003ec469ca91 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /usr/lib64/libstdc++.so.6
这里记录一下如何进行libstdc++本身调试的方法:
1. 下载需要的libstdc++的版本
libstdc++在gcc官网的链接:https://gcc.gnu.org/libstdc++/,从里面选择一个可以连接上的镜像。可以将整个gcc下载下来:
http://mirrors-usa.go-parts.com/gcc/releases/gcc-4.1.2/gcc-4.1.2.tar.gz。
2. 本地编译libstdc++
//为了不影响其它程序,可以将自己编译的库安装在一个自定义的目录;另外为了方便调试,指定config的时候添加debug编译选项
./configure --prefix=xxxx --enable-cxx-flags="-g3 -O0"
make
make install
3. 将编译和运行的库指向自己编译出的libstdc++.so
g++ -o main main.cpp -lstdc++ -L ./lib64/ -Wl,-rpath ./lib64/
利用上面的so就可以显示出可调试的stack
(gdb) bt
#0 0x0000003ebda30265 in raise () from /lib64/libc.so.6
#1 0x0000003ebda31d10 in abort () from /lib64/libc.so.6
#2 0x00007fd4235a07dc in __gnu_cxx::__verbose_terminate_handler () at vterminate.cc:97
#3 0x00007fd42359d56a in __cxxabiv1::__terminate (handler=0x7fd4235a05fc <__gnu_cxx::__verbose_terminate_handler()>) at eh_terminate.cc:43
#4 0x00007fd42359d58f in std::terminate () at eh_terminate.cc:53
#5 0x00007fd42359d720 in __cxxabiv1::__cxa_throw (obj=0x7fd41c000930, tinfo=0x7fd4237d3410, dest=0x7fd42359dbee <std::bad_alloc::~bad_alloc()>)
at eh_throw.cc:77
#6 0x00007fd42359dcd3 in operator new (sz=269472840273) at new_op.cc:63
#7 0x00007fd423579791 in __gnu_cxx::new_allocator<char>::allocate (this=0x41350faf, __n=269472840273)
at /apsara/deploy/testcpp/gcc-4.1.2/libstdc++-v3/include/ext/new_allocator.h:88
#8 0x00007fd42357988a in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create (__capacity=269472840248,
__old_capacity=269472840248, __alloc=...) at /apsara/deploy/testcpp/gcc-4.1.2/libstdc++-v3/include/bits/basic_string.tcc:588
#9 0x00007fd42357a643 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_M_clone (this=0x602310, __alloc=...,
__res=0) at /apsara/deploy/testcpp/gcc-4.1.2/libstdc++-v3/include/bits/basic_string.tcc:610
#10 0x00007fd42357a6fc in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_M_grab (this=0x602310, __alloc1=...,
__alloc2=...) at /apsara/deploy/testcpp/gcc-4.1.2/libstdc++-v3/include/bits/basic_string.h:219
#11 0x00007fd42357a76d in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign (this=0x41351100, __str=...)
at /apsara/deploy/testcpp/gcc-4.1.2/libstdc++-v3/include/bits/basic_string.tcc:253
#12 0x00007fd42357a80b in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator= (this=0x41351100, __str=...)
at /apsara/deploy/testcpp/gcc-4.1.2/libstdc++-v3/include/bits/basic_string.h:486