返回
Hardware-Assisted AddressSanitizer: 精确守护 C/C++ 代码的内存堡垒
开发工具
2024-02-18 01:56:49
Hardware-Assisted AddressSanitizer 的优势
传统的 AddressSanitizer 需要在编译时插入额外的代码,以便在运行时对内存访问进行检查。这种方式虽然有效,但会对程序的性能造成一定的损耗。而 Hardware-Assisted AddressSanitizer 则可以利用硬件的支持,在不影响性能的情况下对内存访问进行检查。
Hardware-Assisted AddressSanitizer 的使用
首先,我们需要在编译器中启用 Hardware-Assisted AddressSanitizer。在 clang 中,可以通过在编译命令中添加 -fsanitize=hwaddress
选项来启用。
clang -fsanitize=hwaddress -o program program.c
启用 Hardware-Assisted AddressSanitizer 后,当程序发生内存错误时,它将生成一个报告,其中包含错误的详细信息,如错误发生的地址、错误类型以及导致错误的代码行。
Hardware-Assisted AddressSanitizer 的示例
#include <stdio.h>
int main() {
int *p = nullptr;
*p = 10;
return 0;
}
当我们编译并运行这段代码时,Hardware-Assisted AddressSanitizer 将生成以下报告:
=================================================================
==11814==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000020 at pc 0x400656
#0 0x400655 in main /tmp/t.c:5:3
#1 0x7f7a16799b31 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6: + 0x20b31)
#2 0x400526 in _start (/tmp/t + 0x526)
0x602000000020 is located 0 bytes inside of 8-byte region [0x602000000020,0x602000000028)
freed by thread T1 here:
#0 0x40062f in main /tmp/t.c:3:13
#1 0x7f7a16799b31 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6: + 0x20b31)
and then written to by thread T1 here:
#0 0x400655 in main /tmp/t.c:5:3
#1 0x7f7a16799b31 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6: + 0x20b31)
SUMMARY: AddressSanitizer: heap-use-after-free /tmp/t.c:5:3
Shadow bytes around the buggy address:
0x0c0000e17e30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0000e17e40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0000e17e50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0000e17e60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0000e17e70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c0000e17e80: 00 00[fd]fa 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0000e17e90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0000e17ea0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0000e17eb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0000e17ec0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0000e17ed0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
从报告中,我们可以看到程序发生了一次堆内存使用后释放错误。错误发生在第 5 行,即 *p = 10;
这行代码。该行代码试图对一个已经释放的内存地址进行赋值,从而导致了错误。
结论
Hardware-Assisted AddressSanitizer 是一个非常强大的工具,它可以帮助我们快速准确地检测出 C/C++ 代码中的内存错误。通过使用 Hardware-Assisted AddressSanitizer,我们可以提高代码的质量,并避免由于内存错误而导致的程序崩溃和数据丢失。