鲲鹏社区首页
中文
注册
GCC编译器GFDL-VortexTracker段错误问题定位

GCC编译器GFDL-VortexTracker段错误问题定位

编译调试

发表于 2025/05/30

0

作者 | 曹家智

问题背景

开源软件GFDL-VortexTracker(https://github.com/NOAA-GFDL/GFDL-VortexTracker)用oneAPI C++编译器编译后正常运行。但用GCC编译后运行报Segmentation fault错误,程序异常终止。



问题分析

GCC编译器原因排查:

1、设置coredump生成路径

vim /etc/sysctl.conf
kernel.core_pattern = /tmp/core-%e-%p-%t

2、设置debug模式编译运行代码/home/cjz/GFDL-VortexTracker/code/CMakeLists.txt


3、运行测试脚本,生成coredump文件

4、用gdb分析coredump文件


查看堆栈信息

5、查看代码

通过gdb调试定位到代码层,发现是变量sstflag定义问题,由于在用户脚本中将sstflag定义为n,导致程序进入if语句异常终止,如果将if语句注释或者将sstflag定义改为y,程序则正常进行,并输出结果。


官方脚本(左)与用户自定义脚本(右):



同一机器用不同的编译器编译运行测试的结果不一样,要分析其原因得看错误处汇编指令。在运行脚本/pg-weather/model-utils/generate_vortex_track/3b_run_tracker_v202503.sh添加gdb运行二进制gettrk.x二进制文件


然后打断点

break src/tracker/gettrk_subroutines.f:886

运行至汇编指令地址

0x55555565267b <access_subroutines_MOD_tracker+37383>: mov 0xeeade(%rip),%r10 # 0x555555741160 <tracked_parms_MOD_sst>

next进入下一行后,出现段错误



查看当前汇编指令地址

x/i $pc
0x5555556526cd <__access_subroutines_MOD_tracker+37465>: movss %xmm0,(%r10,%rax,4)


oneAPI编译器相应汇编指令地址

查看当前命令的汇编指令


0x41dac8 <access_subroutines_mp_tracker_+59736>: mov $0x6ddee0,%rax

在执行下一步next查看当前命令的汇编指令

0x41dc72 <access_subroutines_mp_tracker_+60162>: mov $0x6dde80,%rax


不同编译器的汇编对比

收集二进制gettrk.x的反汇编文件oneAPI和gcc

objdump -d gettrk.x


GCC


oneAPI



从汇编可以看出,

  • GCC 编译的代码使用了相对偏移量和 RIP 寄存器,这可能在某些情况下导致不正确的内存访问,从而引发段错误。
  • oneAPI 编译的代码使用了固定的内存地址,避免了 RIP 可能的计算错误,因此能够正常执行.


解决方式:将源码赋值那段加个标志位判断,让代码更加健全,无论用GCC和oneAPI编译器都能编译运行通过。社区上也有相关Issue

本页内容