linux编译c++:segmentation fault <core dumped>
segmentation fault
分段错误 <核心转储> : 一般就是段页结构的内存,分段错误一般就是越界访问造成的
可能的原因有:
- 内存访问越界
- 多线程未保护
- 堆栈溢出
背景提要:
-
对象是一款基于c++开发的空调系统仿真计算程序, 在windows系统中开发使用Visual Studio编译,可以正常的使用运行。
-
将源代码拷贝到linux的服务器上,使用gcc开始编译-ansi -O3 等等选项,编译过程没有报错或者警告
-
编译成功后运行,某些功能正常,在执行特定功能的时候出现分段错误segmentation fault
-
为了复现linux的错误,使用源代码修改O3优化到-g的调试选项,生成的新的程序
-
新的程序进行运行的时候,出现了新的问题;
服务器系统和gcc版本:
分析与推测的问题来源:
-
因为没有生成core文件不方便查询,在当前终端中使用ulimit -c unlimited 来不限制core文件的大小
-
此时使用 gdb +可执行文件的方式载入 , 因为是O3 flag编译的所以 < no debugging symbols found >.
-
使用run命令来执行程序和文件
文件给出了错误消息: Program receive signal SIGSEGV,segmentation fault; 以及详细的地址 0x000000000049b141 在函数setTubesSpec (FinTubeHeatExchangerDetail作用域)
-
查看堆栈信息
使用bt信息:
在CalcHx::inputSpec<ReadString&>();
FinTubeHeatExchangerDetail::inputSpec 出了问题
但是缺乏其他的信息深入进行调查 -
同理,使用-g编译的debug程序然后运行:
发现当前程序的VIRT虚拟内存需要为46.2G;
不使用run来进行,设定运行参数set args 参数1 参数2
发现错误出现在一个使用 STL list .assgin 的函数功能 -
修改此功能后,重新编译-g可以发现运行良好。 更新后的代码重新编译O3 运行依然出现问题
-
重新编译程序,-O3 -g, 然后debug,发现问题是一个变量的内容和我预想的不一样
检查修改次内容的函数,结果发现在程序空间内不存在此函数。 -
经过思索了解到该函数可能被inline内联到调用他的地方去了,这个函数的不恰当的内联导致了逻辑的错误
-
经过源代码检查,发现此函数的内容写到了类的定义里面去了,在O3优化情况下,在类里定义的函数都会全部内联;
总结:
此次问题,是由于不规范的编程习惯造成的。对于函数的定义可以在类的声明里存在(都在cpp里面)。
没有在类的声明空间外进行详细的定义;这就导致O3优化将此类的函数全部都inline化。
而造成的错误使用。 至于 STL list assign 函数造成的大量内存空间申请,至今不明白原因
有待于后续的考证和检测。