简单说,一个上层应用,下层是Rocksdb,编译机编好后放到测试机器上,崩溃, Got signal: 4 (Illegal instruction).,堆栈提示崩在shared_ptr上。

我简单搜了一下,发现可能有两个原因

  1. ud2a 指令导致的runtime abort。需要看堆栈反汇编。简单看代码不太像这个原因, 有个例子 warning: cannot pass objects of non-POD type ‘class A’ through ‘…’; call will abort at runtim

  2. 两个机器指令集有问题,同事和我说另一个测试机器内核版本号一毛一样,就没问题。不崩溃,就更让我确定是指令集的问题,简单搜了一圈,可以确定是-march=native 这个指令,现在就要确定这个指令在makefile中有没有了

期间我还查cpuinfo看指令集,看编译机和测试机有没有区别(没区别)

查指令集 grep -m1 ^flag /proc/cpuinfo | tr ' ' '\n' | sort

然后我查看了rocksdb的makefile cmakefile list 没有找到。(这是我的失误,我应该grep)

然后我又找上层应用 有没有这个编译指令,grep 没找到

最后同事发现在rocksdb的build_tools/build_detect_platform里。我才明白我实际上不懂rocksdb到底是怎么编译的。

makefile 会调用build_detect_platform 生成make_config.mk,包含了各种编译选项。

# detect what platform we're building on
dummy := $(shell (export ROCKSDB_ROOT="$(CURDIR)"; export PORTABLE="$(PORTABLE)"; "$(CURDIR)/build_tools/build_detect_platform" "$(CURDIR)/make_config.mk"))
# this file is generated by the previous line to set build flags and sources
include make_config.mk
CLEAN_FILES += make_config.mk

唉。

grep就会发现,且INSTALL中也有提示,要是想提高移植性,makefile 加上 PORTABLE=1

./INSTALL.md:(-march=native or the equivalent). If you want to build a portable binary, add 'PORTABLE=1' before 唉。

下面这个链接解释了为啥有人会用-march=native

https://stackoverflow.com/questions/52653025/why-is-march-native-used-so-rarelyWhy is -march=native used so rarely?Why is -march=native used so rarely?

下面这个链接解释了opencv类似的问题

https://answers.ros.org/question/11873/illegal-instruction-when-using-image_view-with-theora/