linux下程序崩溃会生成一个core文件(当然内核可配置是否生成)。对于对linux系统不熟的同学,追core查问题是比较困难。今天首次尝试用GDB去追core,记录下来作为经验积累,供以后翻阅
问题:跑单测的出core
拿到core文件和对应的bin文件,第一步:gdb ./bin core.xx
(2.) bt打印调用栈
#0 0x000000302af71e17 in strcasestr () from /lib64/tls/libc.so.6
#1 0x00000000007c9937 in DISPLAY::DITitleSelect::TagTitleComparator::operator() (this=0x7fbfffe700, tag=0x7fbfffe7d0, normal=0x7fbfffe750) at title_select.cpp:474
#2 0x000000000071dfa8 in TestDITitleSelect_adjust_quality_pooranchor_Test::TestBody (this=0x1812200) at test_titleselect.cpp:160
#3 0x0000000000ccc822 in testing::Test::Run (this=0x1812200) at ./src/gtest.cc:2311
#4 0x0000000000cccb70 in testing::internal::TestInfoImpl::Run (this=0x182d1a0) at ./src/gtest.cc:2530
#5 0x0000000000cccc34 in testing::TestCase::Run (this=0x17f5180) at ./include/gtest/gtest.h:699
core在了库函数strcasestr, 由于libc.so.6的符号表没有加载(应该是这个原因),我们想看看参数、局部变量等信息都看不了
No symbol table info available.
(gdb) info args
No symbol table info available.
(gdb)
(3)这是我返回上一个函数(DISPLAY::DITitleSelect::TagTitleComparator::operator() )的栈 up,再info args
(gdb) info args
this = (const DISPLAY::DITitleSelect::TagTitleComparator * const) 0x7fbfffe700
tag = (const DISPLAY::DITitle *) 0x7fbfffe7d0
normal = (const DISPLAY::DITitle *) 0x7fbfffe750
可以看到这个函数的参数值有this, tag, normal,再这个函数中调用strcasestr的语句是 strcasestr(tag->content, normal->content)
这是我们打印tag->content 和 normal->content就可以了
(4) p ((const DISPLAY::DITitle *) 0x7fbfffe7d0)->content
p ((const DISPLAY::DITitle *) 0x7fbfffe750)->content
打印出来值都是0x0, core原因就找到了 strcasestr(0, 0)会出core
(5)延伸:core不是毕现, 我又试了一下为什么又时候不出core
gdb ./bin
设置断点 b filename:linenum
跑动程序 run
在断点处停住,然后单步执行 s,不停地观察局部变量,发现类的成员变量为false,恰好函数有这个判断返回了
(6) 打印成员变量的方法
先找到this指针地址 p ((const DISPLAY::DITitleSelect::TagTitleComparator * const) 0x7fbfffe700)->m_variable
总结:这次追core 感觉还是要对函数调用有一定的理解,(1)开始的时候库函数strcasestr的栈信息很少,我们就要返回上一个函数的栈信息,(2)打印成员变量的时候要先知道this指针的地址。