Valgrind 在 std::string::swap 中报告 SIGILL
Valgrind reports SIGILL in std::string::swap
我正在使用valgrind 3.16来调试我的程序,它报告了std::string::swap中的非法指令。该程序在 Ubuntu 18.04 上使用 g++ 7.5.0 编译。
vex amd64->IR: unhandled instruction bytes: 0x62 0xF1 0xFE 0x8 0x6F 0x47 0x1 0xC5 0xF8 0x11
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=NONE
vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0
==392550== valgrind: Unrecognised instruction at address 0x3fef89.
==392550== at 0x3FEF89: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::swap(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /tmp/tmp.BnUAMaceSS/cmake-build-release-parallel-chameleon/release/lqf-tpch-query-dev)
==392550== by 0x4F4CD0C: std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
我有两个问题:
是否有一个网站可以使用给定的OP代码查询指令?我尝试了这个网站,但找不到任何与
0x62 0xF1 0xFE ...
相对应的内容为什么瓦尔格林德会在性病图书馆报告SIGILL?
代码本身运行良好。我还应用了未定义,线程,泄漏和地址清理器以及堆栈检查。他们报告没有错误。所以我认为问题出在瓦尔格林德。
我非常感谢@TedLyngmo关于使用消毒剂的评论。虽然消毒剂本身不会给出任何错误,但在使用消毒剂后,错误位置会发生变化。现在它指向我的一些代码库,它使用 AVX 512 指令。当我替换这些指令时,瓦尔格林德可以运行。
虽然我仍然不确定为什么使用消毒剂会产生这样的效果,但我想与那些将来可能遇到类似错误的人分享这种经验。
问题 1:将操作码转换为汇编
本网站可以反汇编操作码以在线组装x86或x64。对于问题中的操作码,将62 F1 FE 08 6F 47 01 C5 F8 11
(请注意,使用08 表示0x8(插入到反汇编下的文本框中,然后输出
Disassembly:
0: 62 f1 fe 08 6f 47 01 vmovdqu64 xmm0,XMMWORD PTR [rdi+0x10]
7: c5 .byte 0xc5
8: f8 clc
9: 11 .byte 0x11
所以指令vmovdqu64
是AVX512指令。
或者你可以被黑客入侵如下
$ cat instruct.c
#include <stdio.h>
int main(void)
{
asm(".byte 0x62, 0xF1, 0xFE, 0x8, 0x6F, 0x47, 0x1, 0xC5, 0xF8, 0x11");
return 0;
}
$ gcc -c instruct.c
$ objdump -drwC -Mintel instruct.o
instruct.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: f3 0f 1e fa endbr64
4: 55 push rbp
5: 48 89 e5 mov rbp,rsp
8: 62 f1 fe 08 6f 47 01 vmovdqu64 xmm0,XMMWORD PTR [rdi+0x10]
f: c5 f8 11 b8 00 00 00 00 vmovups XMMWORD PTR [rax+0x0],xmm7
17: 5d pop rbp
18: c3 ret
为了使valgrind运行带有AVX512指令的程序,可以使用gcc标志-mno-avx512f
编译程序,如此处所述,指出可以使用标志启用扩展指令(例如-mavx512f
( 并使用相应的 -mno-
选项禁用。
在具有AVX512指令的程序上使用valgrind的另一种方法是从源代码构建Valgind并从此处应用补丁。以下是它的步骤:
克隆瓦尔格林德源代码
$ git clone https://sourceware.org/git/valgrind.git $ cd valgrind
从这里下载补丁
将补丁复制到本地文件(例如patch512-part1.patch 内部 文件夹 瓦尔格林德(。目前有 四个补丁,由于作者的事实,它们看起来很凌乱 保持 更新它(这很好(并淘汰旧的。还应该应用 右侧提交顶部的补丁,因为补丁后来自 Valgrind 主分支的新提交可能会破坏 构建系统。例如,到目前为止,来自评论 58、73、60 和 74 的补丁以及 在提交之上
b77dbefe72e4a5c7bcf1576a02c909010bd56991
可以编译 成功。$ git reset --hard b77dbefe72e4a5c7bcf1576a02c909010bd56991
应用补丁
$ patch -p1 < patch512-part1.patch $ patch -p1 < patch512-part2.patch $ patch -p1 < patch512-part3.patch $ patch -p1 < patch512-part4.patch
编译瓦尔格林德
$ ./autogen.sh $ ./configure --prefix=<install-path> $ make $ make install
- Android NDK传感器向事件队列报告奇怪的间隔
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- 使用std::source_location报告错误的最佳实践
- xmake总是报告:错误:无法获取cxx的程序,为什么
- 当用户超过按钮点击限制时报告
- 使用调试/崩溃报告将应用程序部署到客户端
- 为什么cudaMemGetInfo报告设备内存总量的变化
- 为什么瓦尔格林德在不释放恶意内存后没有报告任何问题?
- 内存清理程序报告全局对象构造中未初始化值的使用
- QDataStream 读取和写入的字节数比 QFile::length() 报告要多
- 在 Linux 中使用 ioctl() 获取隐藏功能报告时,零字节消失
- Valgrind 在 std::string::swap 中报告 SIGILL
- DRD 报告"conflicting load" std::mutex::lock 上的错误
- 柯南,CMake.test()生成XML报告
- 如何构建一个异常类来报告C++中的哪些文件和行号?
- Valgrind 在 QThread::start() 上报告内存泄漏
- 我是否访问了已释放的内存,或者在这种情况下DrMemory报告不正确?
- 瓦尔格林德报告在 =带有嵌套shared_ptrs的运算符上的读取错误
- 为什么 valgrind 报告两个内存分配,而我的代码只请求一个?
- boost::p rogram_options 在指定意外的位置参数时不报告任何错误