最近差一些问题,这些问题的现象一开始难以解释,函数的参数地址在函数内部被传递给另外的函数,然后发现地址发生了改变,这样的情况称之为函数的栈被毁坏,导致无法重入。
然后被调用的函数里面,访问了非法的地址导致了segment fault,产生core dump文件。问题比较棘手
查了一些文件,准备从gdb的栈保护设置开始着手。
1) 编译的时候添加编译选项
-fstack-protector 和 -fstack-protector-all 这两个选项指示编译器开启栈保护,这样在栈乱序的第一时间可以dump出来现场。可加在Makefile里面, 顺便扯一句,Makefile这种东西对于搞开源软件的人,还真是得精通,我随便想写个Makefile玩着,突然感觉自己头脑一片空白。
2) gdb的多线程功能
bt 查看当前线程的调用栈
bt full 查看详细的调用栈
info threads 可以查看所有线程的信息
thread <num> 可以具体跳转到某个线程
f <num> 可以跳转到某个栈中位置
i locals 显示当前调用栈的所有变量
i register 显示当前调用栈的寄存器值,主要是查看地址
有了这些命令的帮助我们可以从core dump 的文件里面分析出很多问题。
下面举个例子:
gdb /lab/testtools/rhel664/dallas/testRelease/R10A06_dynamic_udpport_5/mnsserv/bin/mhlif core-mhlif-18310-1384802382
(gdb) bt
#0 0x0000003383488611 in memcpy () from /lib64/libc.so.6
#1 0x000000000041a9aa in ReadFromQueue (q=0x647580, msg=0x4fc780004fc71 <Address 0x4fc780004fc71 out of bounds>, size=280,
time=21081) at ltsosdep.c:443
#2 0x000000000041b552 in OSH_ReceiveMsgQMillisec (q=0x647580, msg=0x4fc780004fc71 <Address 0x4fc780004fc71 out of bounds>,
size=280, time=21081) at ltsosdep.c:1370
#3 0x000000000042d47d in RPS::ReceiveMsg (this=0x2b3100005330, delay=21081) at rps.cc:590
#4 0x000000000042d731 in RPS::Execute (this=0x2b31681ffdf0) at rps.cc:572
#5 0x000000000042dbe8 in StartRps (arg=0x157a680) at rps.cc:181
#6 0x0000003383c077e1 in start_thread () from /lib64/libpthread.so.0
#7 0x00000033834e68ed in clone () from /lib64/libc.so.6
(gdb) bt full
#0 0x0000003383488611 in memcpy () from /lib64/libc.so.6
No symbol table info available.
#1 0x000000000041a9aa in ReadFromQueue (q=0x647580, msg=0x4fc780004fc71 <Address 0x4fc780004fc71 out of bounds>, size=280,
time=21081) at ltsosdep.c:443
row = 0x2b31682a433c
answer = LTS_OK
#2 0x000000000041b552 in OSH_ReceiveMsgQMillisec (q=0x647580, msg=0x4fc780004fc71 <Address 0x4fc780004fc71 out of bounds>,
size=280, time=21081) at ltsosdep.c:1370
No locals.
#3 0x000000000042d47d in RPS::ReceiveMsg (this=0x2b3100005330, delay=21081) at rps.cc:590
rpsMsg =