【发布时间】:2014-01-28 09:36:37
【问题描述】:
我的应用程序使用使用 gcc 编译的静态库:Boost(C++11 lambdas (with boost bind and boost function)) Bullet; SDL 等系统共享库,以及一个用 clang 编译的共享库。这样的动物园会不会弄乱AdressSanitizer?
【问题讨论】:
标签: c++ linux gcc memory-leaks clang
我的应用程序使用使用 gcc 编译的静态库:Boost(C++11 lambdas (with boost bind and boost function)) Bullet; SDL 等系统共享库,以及一个用 clang 编译的共享库。这样的动物园会不会弄乱AdressSanitizer?
【问题讨论】:
标签: c++ linux gcc memory-leaks clang
是的,如果它们没有被检测:
https://code.google.com/p/address-sanitizer/wiki/AddressSanitizer
为了使用 AddressSanitizer,您需要编译和链接 您的程序使用带有 -fsanitize=address 开关的 clang。
【讨论】:
您的程序中必须存在 ASan 运行时库,因此您的主可执行文件需要与 -fsanitize=address 标志链接。将非插桩库和插桩库链接在一起可能会起作用,除非在初始化运行时库之前执行插桩代码(我认为现在在 Linux 上是不可能的)。 请注意,AddressSanitizer 将无法在未由 Clang 检测的代码中找到可寻址性问题。
【讨论】:
Clang 消毒剂可以如下使用
从这里下载clang工具链http://releases.llvm.org/download.html
$ wget http://releases.llvm.org/9.0.0/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
$ tar -Jxvf clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
$ CLANG=$PWD/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-16.04
示例程序
$ cat hello.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int *a = (int *) malloc(sizeof(int)*2);
int n = atoi(argv[1]);
a[n] = 10;
return 0;
}
使用地址清理器编译程序
$ $CLANG/bin/clang -O0 -g -fno-omit-frame-pointer -fsanitize=address -o hello hello.c
运行
$ ASAN_SYMBOLIZER_PATH=$CLANG/bin/llvm-symbolizer ./hello 12
=================================================================
==48489==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x602000000040 at pc 0x0000004c2981 bp 0x7ffe3f888c30 sp 0x7ffe3f888c28
WRITE of size 4 at 0x602000000040 thread T0
#0 0x4c2980 in main /b/syrajendra/clang-libs/hello.c:8:8
#1 0x7f0349c3a82f in __libc_start_main /build/glibc-Cl5G7W/glibc-
2.23/csu/../csu/libc-start.c:291
#2 0x41b2f8 in _start (/b/syrajendra/clang-libs/hello+0x41b2f8)
Address 0x602000000040 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow /b/syrajendra/clang-
libs/hello.c:8:8 in main
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00 fa fa fa fa fa[fa]fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==48489==ABORTING
【讨论】: