问题描述
我为基于 armv7 的目标构建了一个用于 erlang (gitlab.com/Vagabond1/erlang-rocksdb@8708fe8) 的rocksdb 副本。这是一个 iMX6 SoloX 处理器,这里是 cpuinfo:
processor : 0
model name : ARMv7 Processor rev 10 (v7l)
BogoMIPS : 7.54
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
cpu implementer : 0x41
cpu architecture: 7
cpu variant : 0x2
cpu part : 0xc09
cpu revision : 10
Hardware : Freescale i.MX6 SoloX (Device Tree)
Revision : 0500
我有一个加载编译后的 liberocksdb.so
的程序,但它因 SIGILL 崩溃,这是回溯:
#0 0xb1b2a7b0 in std::__detail::_Mod_range_hashing::operator()(unsigned int,unsigned int) const () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#1 0xb1b79b48 in std::__detail::_Hash_code_base<std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::__cxx11::basic_string<char,std::allocator<char> > const,rocksdb::OptionsSanityCheckLevel>,std::__detail::_Select1st,std::hash<std::__cxx11::basic_string<char,std::allocator<char> > >,std::__detail::_Mod_range_hashing,std::__detail::_Default_ranged_hash,true>::_M_bucket_index(std::__cxx11::basic_string<char,std::allocator<char> > const&,unsigned int,unsigned int) const () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#2 0xb1b751d4 in std::_Hashtable<std::__cxx11::basic_string<char,std::allocator<std::pair<std::__cxx11::basic_string<char,rocksdb::OptionsSanityCheckLevel> >,std::equal_to<std::__cxx11::basic_string<char,std::__detail::_Prime_rehash_policy,std::__detail::_Hashtable_traits<true,false,true> >::_M_bucket_index(std::__cxx11::basic_string<char,unsigned int) const ()
from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#3 0xb1b6e01c in std::pair<std::__detail::_Node_iterator<std::pair<std::__cxx11::basic_string<char,true>,bool> std::_Hashtable<std::__cxx11::basic_string<char,true> >::_M_insert<std::pair<std::__cxx11::basic_string<char,rocksdb::OptionsSanityCheckLevel> const&,std::__detail::_AllocNode<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char,true> > > >(std::pair<std::__cxx11::basic_string<char,true> > > const&,std::integral_constant<bool,true>) () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#4 0xb1b63edc in std::__detail::_Insert_base<std::__cxx11::basic_string<char,true> >::insert(std::pair<std::__cxx11::basic_string<char,rocksdb::OptionsSanityCheckLevel> const&) ()
from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#5 0xb1b568b8 in std::_Hashtable<std::__cxx11::basic_string<char,true> >::_Hashtable<std::pair<std::__cxx11::basic_string<char,rocksdb::OptionsSanityCheckLevel> const*>(std::pair<std::__cxx11::basic_string<char,rocksdb::OptionsSanityCheckLevel> const*,std::allocator<char> > > const&,std::__detail::_Mod_range_hashing const&,std::__detail::_Default_ranged_hash const&,std::__detail::_Select1st const&,rocksdb::OptionsSanityCheckLevel> > const&) () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#6 0xb1b489fc in std::_Hashtable<std::__cxx11::basic_string<char,true> >::_Hashtable(std::initializer_list<std::pair<std::__cxx11::basic_string<char,rocksdb::OptionsSanityCheckLevel> > const&) () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#7 0xb1b3c10c in std::unordered_map<std::__cxx11::basic_string<char,rocksdb::OptionsSanityCheckLevel,rocksdb::OptionsSanityCheckLevel> > >::unordered_map(std::initializer_list<std::pair<std::__cxx11::basic_string<char,rocksdb::OptionsSanityCheckLevel> > const&) () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#8 0xb1b28b04 in __static_initialization_and_destruction_0 () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#9 0xb1b29d30 in _GLOBAL__sub_I_db_impl.cc () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#10 0xb6fddff8 in ?? () from /lib/ld-linux-armhf.so.3
Backtrace stopped: prevIoUs frame identical to this frame (corrupt stack?)
拆解如下:
(gdb) disas /m
Dump of assembler code for function _ZNKSt8__detail18_Mod_range_hashingclEjj:
0xb1b2a790 <+0>: push {r11} ; (str r11,[sp,#-4]!)
0xb1b2a794 <+4>: add r11,sp,#0
0xb1b2a798 <+8>: sub sp,#20
0xb1b2a79c <+12>: str r0,[r11,#-8]
0xb1b2a7a0 <+16>: str r1,#-12]
0xb1b2a7a4 <+20>: str r2,#-16]
0xb1b2a7a8 <+24>: ldr r3,#-12]
0xb1b2a7ac <+28>: ldr r2,#-16]
=> 0xb1b2a7b0 <+32>: udiv r2,r3,r2
0xb1b2a7b4 <+36>: ldr r1,#-16]
0xb1b2a7b8 <+40>: mul r2,r1,r2
0xb1b2a7bc <+44>: sub r3,r2
0xb1b2a7c0 <+48>: mov r0,r3
0xb1b2a7c4 <+52>: add sp,r11,#0
0xb1b2a7c8 <+56>: pop {r11} ; (ldr r11,[sp],#4)
0xb1b2a7cc <+60>: bx lr
End of assembler dump.
我不是这个领域的专家,但据我所知,程序崩溃是因为指令 udiv
对我的 cpu 是非法的。
我查看了 ARM 开发者网站,这是一个 Cortex M3 instruction,我相信我的 cpu 是 Cortex M4,所以我想它应该有这个指令?
也许我的分析是错误的,这是别的什么?
我的交叉编译是使用该 cpu 和 rootfs 的交叉工具链进行的,并包含诸如 -march=armv7-a -marm -mfpu=neon -mfloat-abi=hard
之类的参数,这些参数应该提供兼容的二进制文件。
谢谢
解决方法
cmake 脚本强制使用与我的 CPU 不兼容的 -march=armv8-a+crc
。
https://gitlab.com/Vagabond1/erlang-rocksdb/-/commit/6bf4a440b8132ef643682ba87dee6de87dc47d58