2016-09-24 139 views
6

我有,看起来像这样的功能 -的valgrind:在地址无法识别的指令0x5111715

std::string func() 
{ 
    std::string result; 

    ... 

    auto seed = std::random_device()(); 
    std::mt19937 gen(seed); 
    std::uniform_int_distribution<> dis(0, 61); 

    ... 
    return result; 
} 

横跨各种编译器及其版本编译罚款,但还是未能通过测试Valgrind的上的Ubuntu。我明确提到了ubuntu,因为它在我的Arch Linux安装的机器上成功传递。

这两个valgrind安装都报告它们的版本为valgrind-3.11.0,唯一的区别是Arch Linux安装在我的机器上没有虚拟化,而Ubuntu测试已经在DO/CI服务器上完成,而这些服务器可能正在进行某种虚拟化。但是,这是否重要?


这里是日志的valgrind运行 -

--- stderr --- 
==13849== Memcheck, a memory error detector 
==13849== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==13849== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==13849== Command: file/path/here 
==13849== 
vex amd64->IR: unhandled instruction bytes: 0xF 0xC7 0xF0 0x89 0x6 0xF 0x42 0xC1 
vex amd64->IR: REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0 
vex amd64->IR: VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=0F 
vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0 
==13849== valgrind: Unrecognised instruction at address 0x5111715. 
==13849== at 0x5111715: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22) 
==13849== by 0x51118B1: std::random_device::_M_getval() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22) 
==13849== by 0x4809FB: std::random_device::operator()() (random.h:1612) 
==13849== by 0x47F0C2: isaac::deviceList::genId[abi:cxx11](unsigned int) (deviceList.cpp:21) 
==13849== by 0x47F2A7: isaac::deviceList::place(isaac::deviceType, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator>) (deviceList.cpp:38) 
==13849== by 0x40D06E: DeviceList_place_Test::TestBody() (test.cpp:194) 
==13849== by 0x45D5A7: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2078) 
==13849== by 0x4588D2: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2114) 
==13849== by 0x43EBB3: testing::Test::Run() (gtest.cc:2151) 
==13849== by 0x43F3F5: testing::TestInfo::Run() (gtest.cc:2326) 
==13849== by 0x43FA52: testing::TestCase::Run() (gtest.cc:2444) 
==13849== by 0x446911: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:4315) 
==13849== Your program just tried to execute an instruction that Valgrind 
==13849== did not recognise. There are two possible reasons for this. 
==13849== 1. Your program has a bug and erroneously jumped to a non-code 
==13849== location. If you are running Memcheck and you just saw a 
==13849== warning about a bad jump, it's probably your program's fault. 
==13849== 2. The instruction is legitimate but Valgrind doesn't handle it, 
==13849== i.e. it's Valgrind's fault. If you think this is the case or 
==13849== you are not sure, please let us know and we'll try to fix it. 
==13849== Either way, Valgrind will now raise a SIGILL signal which will 
==13849== probably kill your program. 
==13849== 
==13849== Process terminating with default action of signal 4 (SIGILL): dumping core 
==13849== Illegal opcode at address 0x5111715 
==13849== at 0x5111715: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22) 
==13849== by 0x51118B1: std::random_device::_M_getval() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22) 
==13849== by 0x4809FB: std::random_device::operator()() (random.h:1612) 
==13849== by 0x47F0C2: isaac::deviceList::genId[abi:cxx11](unsigned int) (deviceList.cpp:21) 
==13849== by 0x47F2A7: isaac::deviceList::place(isaac::deviceType, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator>) (deviceList.cpp:38) 
==13849== by 0x40D06E: DeviceList_place_Test::TestBody() (test.cpp:194) 
==13849== by 0x45D5A7: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2078) 
==13849== by 0x4588D2: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2114) 
==13849== by 0x43EBB3: testing::Test::Run() (gtest.cc:2151) 
==13849== by 0x43F3F5: testing::TestInfo::Run() (gtest.cc:2326) 
==13849== by 0x43FA52: testing::TestCase::Run() (gtest.cc:2444) 
==13849== by 0x446911: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:4315) 
==13849== 
==13849== HEAP SUMMARY: 
==13849==  in use at exit: 84,300 bytes in 108 blocks 
==13849== total heap usage: 622 allocs, 514 frees, 530,112 bytes allocated 
==13849== 
==13849== LEAK SUMMARY: 
==13849== definitely lost: 0 bytes in 0 blocks 
==13849== indirectly lost: 0 bytes in 0 blocks 
==13849==  possibly lost: 0 bytes in 0 blocks 
==13849== still reachable: 84,300 bytes in 108 blocks 
==13849==   suppressed: 0 bytes in 0 blocks 
==13849== Rerun with --leak-check=full to see details of leaked memory 
==13849== 
==13849== For counts of detected and suppressed errors, rerun with: -v 
==13849== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 
------- 

编辑 - 我也试过手动构建从官方消息的valgrind并安装它,但是仍然会产生同样的错误。

+1

你在Ubuntu机器上使用了哪些编译器标志?显然,编译器正在生成一条非法指令。 Ubuntu机器上'/ proc/cpuinfo'的输出是什么? –

+0

@MartinNyolt两个版本都有相同的标志,ubuntu'/ proc/cpuinfo' - https://gist.github.com/agauniyal/c8d57b106097a16296b259b86fc93368 –

+1

但是* *标记究竟是什么?我正在帮你找出*为什么你的编译器生成一个非法指令。你调试过代码并检查它试图执行哪条指令吗?该错误是否仅在valgrind期间发生,或者在正常执行期间是否也获得了SIGILL? –

回答

3

它看起来像你的Ubuntu系统有一个随机数字库,它使用您的Valgrind版本无法识别的RDRAND指令(操作码0x0f 0xc7)。您的Arch系统显然使用了不利用此指令的不同实现。

您可能可以通过重新编译预编译Ivy Bridge CPU来解决此问题。

+0

重新编译为在我的系统上编译,然后在CI上下载该二进制文件并在其上运行valgrind? –

+1

它看起来像指令是在你的libstdC++库中,所以我想你可能需要重新编译它。你也可以检查这是否是Valgrind的已知问题,并查看是否有任何补丁修复它。 –

+0

嗯,我不能静态链接到它呢?重新编译libstdC++库似乎对我来说不是一天的任务:p –

7

参见https://bugs.kde.org/show_bug.cgi?id=353370

获取/编译最后的svn版本应该可以解决这个问题。

如果不是,请在bugzilla上报告,因为3.12版本即将出版。 谢谢

+1

我忘了评论,但它确实解决了我的问题:) –