记一次由指令集不同导致的coredump

798 阅读3分钟

注:运行的程序用ha代替

现象

个别机器上线后出core,大部分机器运行正常。发现出问题的机器cpu型号与正常机器不同

查看cpu型号,支持指令集命令: cat /proc/cpuinfo

dmesg查看原因

运行程序

.ha ...(参数)

发现出core,然后打dmesg,有如下显示

[58499207.187672] traps: ha[236179] trap invalid opcode ip:7fe6a307107e sp:7ffd3f387f80 error:0 in libfm_recall.so[7fe6a2ee8000+4f4000]

这个说的就很明白了,捕获无效操作码,立马怀疑是指令集问题

gdb运行程序寻找原因

运行gdb

gdb /bin/ha
r -a 123 - ....(运行参数)
layout asm 查看汇编

image.png 看到死的地方是一句vmovdqa64,谷歌一下发现,指令集属于指令集avx512f,在运行机器上cat /proc/cpuinfo发现并没有这个指令集,最高就是avx2

解决方法

可以看出造成问题的根本原因就是运行机器中个别机器cpu版本偏旧,不支持新的指令集

解决办法:

  1. 统一机器,全都用新的,这个是最理想的,用最新的机器,最新的指令集,性能最佳,不过现实总是残酷
  2. 在旧机器上编译线上运行版本,这样就不会出现新指令集中的指令了,这个方法比较偷懒
  3. 在编译参数中添加 -match=cpu-type,选择哪个cpu-type可以根据机器支持的指令参考<官方文档>

我这次来说,旧机器最高支持avx2,所以我在编译参数里加上了-march=skylake问题得到解决

确认不再有 vmovdqa64指令

用下面这句查看编译出来的二进制文件是否包含vmovdqa64指令

objdump -d ha |grep vmovdqa64

限制指令集之前,命令输出如下:

  170e8f:	62 f1 fd 08 6f 44 24 	vmovdqa64 0x80(%rsp),%xmm0
  17104e:	62 f1 fd 08 6f 54 24 	vmovdqa64 0x90(%rsp),%xmm2
  17120e:	62 f1 fd 08 6f 64 24 	vmovdqa64 0xa0(%rsp),%xmm4
  1712c6:	62 f1 fd 08 6f 74 24 	vmovdqa64 0xb0(%rsp),%xmm6
  1712e1:	62 f1 fd 08 6f 7c 24 	vmovdqa64 0x30(%rsp),%xmm7
  1715e7:	62 e1 fd 08 6f 5c 24 	vmovdqa64 0xc0(%rsp),%xmm19
  1715f8:	62 e1 fd 08 6f 64 24 	vmovdqa64 0x50(%rsp),%xmm20
  1716a3:	62 e1 fd 08 6f 6c 24 	vmovdqa64 0xd0(%rsp),%xmm21
  1716b4:	62 e1 fd 08 6f 74 24 	vmovdqa64 0x60(%rsp),%xmm22
  171730:	62 e1 fd 08 6f 7c 24 	vmovdqa64 0xe0(%rsp),%xmm23
  17174e:	62 61 fd 08 6f 44 24 	vmovdqa64 0x40(%rsp),%xmm24
  17183f:	62 e1 fd 08 6f 44 24 	vmovdqa64 0xf0(%rsp),%xmm16

加上指令集限定重新编译后,命令没有输出,说明我们把vmovdqa64以及avx512指令集干掉了