一个诡异的SIGILL问题,,原来是这样导致的

来源:互联网 发布:java接口的继承 编辑:程序博客网 时间:2024/04/26 06:50

在一终端启动程序A之后,再另一个终端运行另外一个毫不相干(当然只是表面上看起来是这样)的进程B,,
然后就发现A极其诡异的挂掉了,,
gdb看生成的core文件显示收到一个SIGILL信号导致程序退出,,而查手册显示SIGILL竟然是非法硬件指令导致的,,

不是吧,这两个进程毫不相干啊,,太恐怖了!开始不着边际的猜测:
难道程序B修改了什么环境变量,影响了程序A?不对啊他们不在同一个终端啊,,
难道第三方库有问题?第三方库中的内存分配函数和我们库里用的malloc有冲突?不太可能;而且即使有冲突,也不会由一个毫不相干的进程来触发啊,,
难道是系统用的这个内核版本有bug?哎,我的想象力真是太丰富了,,

到底是什么原因呢?情绪开始变得满是郁闷和狂躁:
for (;;)
为什么一个进程会影响另一个进程,不可能啊;

食堂碰到前辈高手,求助:
cai:我们碰到一个极其诡异的问题,想破脑瓜,想不出来,,
niu:诡异(表示怀疑)? 是必现的吗?
cai:嗯,基本上是,,
niu:(失望)必现的问题,竟然搞了好久还没定位出来? 好吧,用完膳我去看看,,

高手开始定位:
启动A进程,gdb断到A进程挂掉的函数foo内,disassemble foo,,
然后再启动B进程,再看gdb 中disassemble foo,,结果发现程序指针竟然被修改了,,

看看启动B进程用的脚本(程序B是封装在一个脚本里的,启动前是一些判断和环境变量设定),里面步骤很多,“是不是你的脚本里加了什么鬼东西导致的问题”(指明了新的方向),
重新启动A,将必要的环境变量设置和启动B进程动作放在外面手动运行,果然问题不再复现

开始仔细检查启动B的脚本,发现其中用source载入了一个设定环境变量的setenv.sh脚本,且setenv.sh中有一个拷贝当前lib/下最新的libxxx.so覆盖/usr/local/lib/下libxxx.so的动作,而这个/usr/local/lib/libxxx.so是A进程正在用的,, 问题找到。

niu:要学会定位问题,必现的问题还是很好定位的,,我们以前要求可复现问题一天必须搞定,,,
cai:哦,(惭愧中,,我怎么就没有想到尼)

哎,以后碰到问题不能慌,要仔细排查,没有头绪就用试验、隔离法先缩小问题范围