随便玩耍,我发现一个SIGILL尝试std::random_device
,但我真的不明白为什么。
代码如下:
#include <random>
int main()
{
std::random_device rd;
auto seed = rd(); // SIGILL with memcheck
std::mt19937 gen(seed);
}
该程序可以编译并正常运行,但是当我使用memcheck
运行该程序时,会收到非法指令信号。
这可能是预料之中的,但我不确定。
我按照以下步骤进行编译和运行:
g++ -std=c++17 -Wall -Wextra -o tst ./main.cc && ./tst && valgrind --tool=memcheck ./tst
内存检查日志:
> ==16801== Memcheck, a memory error detector
> ==16801== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
> ==16801== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
> ==16801== Command: ./tst
> ==16801== 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
> ==16801== valgrind: Unrecognised instruction at address 0x4ef3c05.
> ==16801== at 0x4EF3C05: std::(anonymous namespace)::__x86_rdrand() (random.cc:81)
> ==16801== by 0x4EF3D71: std::random_device::_M_getval() (in /media/jp/Data/install_gcc/lib64/libstdc++.so.6.0.25)
> ==16801== by 0x401745: std::random_device::operator()() (in /home/jp/sandbox/cpp/random/tst)
> ==16801== by 0x40159C: main (in /home/jp/sandbox/cpp/random/tst)
> ==16801== Your program just tried to execute an instruction that Valgrind
> ==16801== did not recognise. There are two possible reasons for this.
> ==16801== 1. Your program has a bug and erroneously jumped to a non-code
> ==16801== location. If you are running Memcheck and you just saw a
> ==16801== warning about a bad jump, it's probably your program's fault.
> ==16801== 2. The instruction is legitimate but Valgrind doesn't handle it,
> ==16801== i.e. it's Valgrind's fault. If you think this is the case or
> ==16801== you are not sure, please let us know and we'll try to fix it.
> ==16801== Either way, Valgrind will now raise a SIGILL signal which will
> ==16801== probably kill your program.
> ==16801==
> ==16801== Process terminating with default action of signal 4 (SIGILL)
> ==16801== Illegal opcode at address 0x4EF3C05
> ==16801== at 0x4EF3C05: std::(anonymous namespace)::__x86_rdrand() (random.cc:81)
> ==16801== by 0x4EF3D71: std::random_device::_M_getval() (in /media/jp/Data/install_gcc/lib64/libstdc++.so.6.0.25)
> ==16801== by 0x401745: std::random_device::operator()() (in /home/jp/sandbox/cpp/random/tst)
> ==16801== by 0x40159C: main (in /home/jp/sandbox/cpp/random/tst)
> ==16801==
> ==16801== HEAP SUMMARY:
> ==16801== in use at exit: 72,704 bytes in 1 blocks
> ==16801== total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
> ==16801==
> ==16801== LEAK SUMMARY:
> ==16801== definitely lost: 0 bytes in 0 blocks
> ==16801== indirectly lost: 0 bytes in 0 blocks
> ==16801== possibly lost: 0 bytes in 0 blocks
> ==16801== still reachable: 72,704 bytes in 1 blocks
> ==16801== suppressed: 0 bytes in 0 blocks
> ==16801== Rerun with --leak-check=full to see details of leaked memory
> ==16801==
> ==16801== For counts of detected and suppressed errors, rerun with: -v
> ==16801== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) Illegal instruction (core dumped)
其他信息:
我设法使用g++
使用Wlarger-than
生成了警告,但是在谈论随机性时,我认为可以安全地忽略此警告。
./ main.cc:7:22:警告:“ rd”的大小为5000个字节[-Wlarger-than =]
g++ --version
g ++-8(Ubuntu 8.1.0-5ubuntu1〜16.04)8.1.0版权所有(C)2018免费 Software Foundation,Inc。这是免费软件。请参阅源 复制条件。没有保修;甚至没有 特定目的的适销性或适用性。
valgrind --version
valgrind-3.11.0