王嘉贝

导航

linux编译c++:segmentation fault <core dumped>

segmentation fault

分段错误 <核心转储> : 一般就是段页结构的内存,分段错误一般就是越界访问造成的
可能的原因有:

  1. 内存访问越界
  2. 多线程未保护
  3. 堆栈溢出
背景提要:
  1. 对象是一款基于c++开发的空调系统仿真计算程序, 在windows系统中开发使用Visual Studio编译,可以正常的使用运行。

  2. 将源代码拷贝到linux的服务器上,使用gcc开始编译-ansi -O3 等等选项,编译过程没有报错或者警告

  3. 编译成功后运行,某些功能正常,在执行特定功能的时候出现分段错误segmentation fault

  4. 为了复现linux的错误,使用源代码修改O3优化到-g的调试选项,生成的新的程序

  5. 新的程序进行运行的时候,出现了新的问题;

     服务器系统和gcc版本:
    
分析与推测的问题来源:
  1. 因为没有生成core文件不方便查询,在当前终端中使用ulimit -c unlimited 来不限制core文件的大小

  2. 此时使用 gdb +可执行文件的方式载入 , 因为是O3 flag编译的所以 < no debugging symbols found >.

  3. 使用run命令来执行程序和文件

     文件给出了错误消息:
     Program receive signal SIGSEGV,segmentation fault; 以及详细的地址 0x000000000049b141 
     在函数setTubesSpec (FinTubeHeatExchangerDetail作用域) 
    
  4. 查看堆栈信息
    使用bt信息:
    在CalcHx::inputSpec<ReadString&>();
    FinTubeHeatExchangerDetail::inputSpec 出了问题
    但是缺乏其他的信息深入进行调查

  5. 同理,使用-g编译的debug程序然后运行:
    发现当前程序的VIRT虚拟内存需要为46.2G;
    不使用run来进行,设定运行参数set args 参数1 参数2
    发现错误出现在一个使用 STL list .assgin 的函数功能

  6. 修改此功能后,重新编译-g可以发现运行良好。 更新后的代码重新编译O3 运行依然出现问题

  7. 重新编译程序,-O3 -g, 然后debug,发现问题是一个变量的内容和我预想的不一样
    检查修改次内容的函数,结果发现在程序空间内不存在此函数。

  8. 经过思索了解到该函数可能被inline内联到调用他的地方去了,这个函数的不恰当的内联导致了逻辑的错误

  9. 经过源代码检查,发现此函数的内容写到了类的定义里面去了,在O3优化情况下,在类里定义的函数都会全部内联;


总结:

此次问题,是由于不规范的编程习惯造成的。对于函数的定义可以在类的声明里存在(都在cpp里面)。
没有在类的声明空间外进行详细的定义;这就导致O3优化将此类的函数全部都inline化。
而造成的错误使用。 至于 STL list assign 函数造成的大量内存空间申请,至今不明白原因

有待于后续的考证和检测。

posted on 2021-07-07 17:02  toBeGeek  阅读(365)  评论(0编辑  收藏  举报