这可能过于具体,但张贴在这里,因为它可能会帮助那些试图在默认 SPEC 基准测试工具之外编译/运行 SPEC 2006 基准测试的其他人。 (我们这样做的原因是比较编译策略和代码覆盖率,而 SPEC 工具只关注结果代码的性能)。
执行 perlbench 的引用运行时,基准测试因段错误而崩溃:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004f6868 in S_regmatch (prog=0x832144)
at <path-to-spec>/CPU2006/400.perlbench/src/regexec.c:3024
3024 PL_reg_start_tmp[n] = locinput;
(gdb) bt
#0 0x00000000004f6868 in S_regmatch (prog=0x832144)
at <path-to-spec>/CPU2006/400.perlbench/src/regexec.c:3024
#1 0x00000000004f22cf in S_regtry (prog=0x8320c0, startpos=0x831e70 "o")
at <path-to-spec>/CPU2006/400.perlbench/src/regexec.c:2196
#2 0x00000000004eba71 in Perl_regexec_flags (prog=0x8320c0, stringarg=0x831e70 "o", strend=0x831e71 "",
strbeg=0x831e70 "o", minend=0, sv=0x7e2528, data=0x0, flags=3)
at <path-to-spec>/CPU2006/400.perlbench/src/regexec.c:1910
#3 0x00000000004b33bb in Perl_pp_match ()
at <path-to-spec>/CPU2006/400.perlbench/src/pp_hot.c:1340
#4 0x00000000004fcde4 in Perl_runops_standard ()
at <path-to-spec>/CPU2006/400.perlbench/src/run.c:37
#5 0x000000000046bf57 in S_run_body (oldscope=1)
at <path-to-spec>/CPU2006/400.perlbench/src/perl.c:2017
#6 0x000000000046b9f6 in perl_run (my_perl=0x7bf010)
at <path-to-spec>/CPU2006/400.perlbench/src/perl.c:1934
#7 0x000000000047add2 in main (argc=4, argv=0x7fffffffe178, env=0x7fffffffe1a0)
at <path-to-spec>/CPU2006/400.perlbench/src/perlmain.c:98
执行环境是 64 位 Linux,并且使用最新的 gcc 和 clang 观察到行为。
导致崩溃的原因是什么?
最佳答案
段错误是由指出的行上的变量 n
的垃圾值引起的。检查代码显示该值来自以下类型对象的字段 arg1
:
struct regnode_1 {
U8 flags;
U8 type;
U16 next_off;
U32 arg1;
};
检查对象的内存位置显示它没有打包,即 next_off
和 arg1
之间有 32 位填充:
(gdb) x/16xb scan
0x7f4978: 0xde 0x2d 0x02 0x00 0x00 0x00 0x00 0x00
0x7f4980: 0x00 0x11 0x0d 0x00 0x00 0x00 0x00 0x00
(gdb) print/x n
$1 = 0xd1100
这很可疑。 perlbench
中正在进行指针和类型转换,因此类型大小假设可能在某处失败。使用 multilib
编译产生一个工作基准并检查内存以验证没有填充。
在执行 64 位编译时将结构强制放入位域修复了崩溃:
struct regnode_1 {
U8 flags : 8;
U8 type : 8;
U16 next_off : 16;
U32 arg1 : 32;
};
关于c - perlbench 在 SPEC 2006 线束之外导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40219744/