c++ - __builtin_ctz 的 valgrind 错误

标签 c++ ubuntu-12.04 valgrind

我正在尝试分析我的代码,但遇到了问题。

如果我运行以下代码:

#include <iostream>

int main() {
    size_t val = 8;

    std::cout << sizeof(val) << std::endl;
    std::cout << __builtin_ctz(val) << std::endl;
}

它按预期返回

8
3

如果我在上面运行 valgrind,它会返回:

==28602== Memcheck, a memory error detector
==28602== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==28602== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==28602== Command: ./test
==28602== 
8
vex amd64->IR: unhandled instruction bytes: 0xF3 0xF 0xBC 0xC0 0x89 0xC6 0xBF 0x60
==28602== valgrind: Unrecognised instruction at address 0x400890.
==28602==    at 0x400890: main (in /home/magu_/sod/test/test)
==28602== Your program just tried to execute an instruction that Valgrind
==28602== did not recognise.  There are two possible reasons for this.
==28602== 1. Your program has a bug and erroneously jumped to a non-code
==28602==    location.  If you are running Memcheck and you just saw a
==28602==    warning about a bad jump, it's probably your program's fault.
==28602== 2. The instruction is legitimate but Valgrind doesn't handle it,
==28602==    i.e. it's Valgrind's fault.  If you think this is the case or
==28602==    you are not sure, please let us know and we'll try to fix it.
==28602== Either way, Valgrind will now raise a SIGILL signal which will
==28602== probably kill your program.
==28602== 
==28602== Process terminating with default action of signal 4 (SIGILL)
==28602==  Illegal opcode at address 0x400890
==28602==    at 0x400890: main (in /home/magu_/sod/test/test)
==28602== 
==28602== HEAP SUMMARY:
==28602==     in use at exit: 0 bytes in 0 blocks
==28602==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==28602== 
==28602== All heap blocks were freed -- no leaks are possible
==28602== 
==28602== For counts of detected and suppressed errors, rerun with: -v
==28602== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Illegal instruction (core dumped)

这是 valgrind 的错误还是我不应该在我的计算机上使用 __builtin_ctz__builtin_popcount 不会引发任何错误。

我的系统:

g++ (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1
CPU : Intel Core Duo T7500 

最佳答案

您需要将 valgrind 至少升级到 4.8.1 或使用早于 v4.8 的 gcc。

您遇到的操作码 -- F3 0F BC -- 是 BMI1 中引入的 TZCNT 操作码,您的 CPU 没有实现它。但是,它也是 REP;BSF(F3REP)并且旧的 CPU,包括你的,忽略此操作码的 REP,以及类似的 LZCNT == REP;BSR 对。 TZCNTBSF 之间几乎没有区别(它们在处理 0 的方式上有所不同)。

较旧的 gcc 版本对较旧的 CPU 使用 BSF,对较新的 CPU 使用 TZCNT,但由于操作码相对较少,因此在较新的 gcc 版本中逻辑得到了简化,并且始终使用 TZCNT,因为新旧 CPU 都能理解它。

不幸的是,直到 v4.8.1,valgrind 才正确地从 TZCNT 回退到 BSF。参见 bug 295808 .

关于c++ - __builtin_ctz 的 valgrind 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25190315/

相关文章:

putty - byobu 更新时硬状态行会滚动屏幕

c++ - 链接外部库时出错

c - 使用 Instruments 检测 C/C++ 命令行内存泄漏

android - 无法使用 Valgrind 运行 Java Android 程序

c - 可能的堆损坏,使用 valgrind 调试

c++ - 放置新地址与原始内存地址

c++ - Clang 真的有这么聪明吗?

c++ - Qt QCursor::setPos() 什么都不做

c++ - 多核机器上的多个程序实例

c++ - 1000 以下所有数字的总和,是 3 或 5 的倍数