valgrind error with __builtin_ctz

valgrind error with __builtin_ctz

本文关键字:builtin ctz with error valgrind      更新时间:2023-10-16

我想分析我的代码,但遇到了问题。

如果我运行以下代码:

#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的bug还是我不应该在我的计算机上使用__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——是TZCNT操作码,在BMI1中引入,您的CPU无法实现。但是,也是 REP;BSF (F3REP)和较旧的cpu,包括您的cpu,忽略此操作码的REP和类似的LZCNT == REP;BSR对。TZCNTBSF之间的差别很小(不同之处在于它们如何处理0)。

旧的gcc版本在旧的cpu上使用BSF,在新的cpu上使用TZCNT,但是由于操作码相对较少,在较新的gcc版本中,逻辑被简化了,并且总是使用TZCNT,因为旧的和新的cpu都理解它。

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

在Debian/Sid/x86-64 (Intel i4750HQ处理器)上使用gcc version 4.9.1 (Debian 4.9.1-4)valgrind-3.9.0,您的测试工作正常(valgrind运行成功,没有报告任何错误)。

所以我建议你升级你的GCC编译器,最重要的是valgrind。首先从它的valgrind-3.9.0源代码tarball编译valgrind(之前使用aptitude build-dep valgrind)。

顺便说一句,你的发行版本太旧了。你考虑过升级到Ubuntu 14.0 LTS吗?

如果你没有root权限,考虑将一些显式的--prefix(例如$HOME/pub/)传递给valgrind-3.9.0/configure