一个ILLEGLE INSTRUCTION转SEGMENT FAULT的诡异CORE
碰到一个ILLEGAL INSTRUCTION后面转SEGMANET FAULT的诡异的问题,求助一下……
先简单描述一下代码结果,实际比这个复杂,但大概也差不多
a1.c/a2.c/a3.c=>LIBA.SO
e.c + LIBA.SO=>execBin
下面我开始讲述一下,查找原因的过程(前后一个月……悲剧,到现在还没找到原因),感觉进展都可以写成一个小小说了……
阶段一,这个时候,CORE原因是ILLEGAL INSTRUCTION。
只有一个ILLEGAL INSTRUCTION,文件里有CORE的地方,但是根本无法定位原因。
因此只能开始瞎猜,首先怀疑LIBA.SO,因为这是一个开源代码基本上改过来的,唯一使用MALLOC的地方。
考虑到这个SO的功能是解析配置文件,只会有主线程调用,因此将LIBA.SO中动态分配内存(MALLOC/CALLOC/STRDUP)的地方,全部改成静态分配(全局BUFFER)。
改完之后,CORE消失,但是代码本身检查过,没有问题,而且有问题,为何会造成ILLEGAL INSTRUCTION?这感觉像是段错误覆盖了栈中的代码导致?后面再看
阶段二,中间有个小插曲:因为这套代码在操作系统升级前后都跑过,升级后才有的CORE,因此使用两个环境复现:
AIX7.1.2 未出现
AIX7.1.3 基于7.1.3全新编译或使用7.1.2编译的均会出现ILLEGAL INSTRUCTION。
暂时感觉毫无任何帮助。
阶段三:
因为ILLEGAL INSTRUCTION出现的慢(不停的运行过程中才出),所以在A函数中,使用了一些无用的变量(几百K),结果在A调用B时,立马出现CORE
此时CORE变成了SEGMENT FAULT。
这里的函数A是一个用户线程的入口函数,其间会调用函数B。
尝试在创建线程A的时候,增加堆栈大小,段错误消失。
阶段四:
这里肯定要问,是不是我加的变量导致SEGMENT FAULT?
没错,但是函数A内的变量少的可怜,是谁导致它,回想到阶段一改了LIBA.SO,如何证明和LIBA.SO有关系。
于是,验证如下:
首先调用LIBA.SO中的内容,都是在主线程,在A线程中没有调用。
其次因为LIBA.SO是解析配置文件,文件越在,MALLOCL的内存越多。
好了,程序任何都不改,只改配置文件,结果:
小的配置文件,不CORE
大的配置文件,必CORE
也就是说,导致线程堆栈溢出的,并不是用户线程A中的临时变量, 而是主线程调用LIBA.SO,导致堆栈溢出。
联想起阶段一,LIBA.SO的嫌疑越来越大。
到现在,由于线头太多,全部梳理出来几个关键点:
1、LIBA.SO中动态分配内存,改成静态,OK不CORE
2、用户线程A堆栈溢出,加大堆栈,OK不CORE了
3、上述任何作法,在两个操作系统中,都是7.1.2不CORE 7.1.3CORE,即使是完全同构的代码,这和操作系统有什么关系?
问题是,什么导致溢出的?是LIBASO分配的堆的内存使用越界,导致栈溢出吗?不同操作系统保护不一样?