Linux gcc自带检测内存泄漏工具asan

背景

排查和检测内存泄漏的问题时,需要选择一些好用的工具,由于dmalloc编译复杂,valgrind依赖太多,所以选择使用gcc自带检测内存泄漏工具asan,版本4.8之后就支持asan了,下面来使用看下效果。

安装

安装gcc依赖的asan库:libasan.so

sudo yum install libasan

编译

编译参数:

-fsanitize=address -fno-omit-frame-pointer -g -O2

此功能是运行的时候检测,且没有运行的代码是不能被检测到的。

代码

内存越界

int fun0(){
	char str[4] = {0,};
	strcpy(str,"测试");
	return 0;
}
=================================================================
==12724== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe1ac0d566 at pc 0x4008d3 bp 0x7ffe1ac0d530 sp 0x7ffe1ac0d520
WRITE of size 1 at 0x7ffe1ac0d566 thread T0
    #0 0x4008d2 (/home/yubo.wang/4g-box/func-call/a.out+0x4008d2)
    #1 0x7f82632a9444 (/usr/lib64/libc-2.17.so+0x22444)
    #2 0x400931 (/home/yubo.wang/4g-box/func-call/a.out+0x400931)
Address 0x7ffe1ac0d566 is located at offset 38 in frame 
of T0's stack: This frame has 1 object(s): [32, 36) 'str' HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) Shadow bytes around the buggy address: 0x100043579a50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100043579a60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100043579a70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100043579a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100043579a90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x100043579aa0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1[04]f4 f4 f4 0x100043579ab0: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 0x100043579ac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100043579ad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100043579ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100043579af0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 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 Heap righ redzone: fb Freed Heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 ASan internal: fe ==12724== ABORTING

 内存泄漏

char *fun1(char *str) {
	static char *p;
	p = malloc(64);
	strcpy(p,str);
	return p;
}

int fun2(){
	char *str=fun1("abcd");
	printf("str=%s\n",str);
	return 0;
}

没有检测出内存泄漏的问题。

非法内存

int fun3(){
	char *p = NULL;
	strcpy(p,"a");
	return 0;
}
ASAN:SIGSEGV
=================================================================
==12787== ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000040081c sp 0x7ffc02097320 bp 0x7ffc02097320 T0)
AddressSanitizer can not provide additional info.
    #0 0x40081b (/home/yubo.wang/4g-box/func-call/a.out+0x40081b)
    #1 0x7f7be5ab3444 (/usr/lib64/libc-2.17.so+0x22444)
    #2 0x4008b1 (/home/yubo.wang/4g-box/func-call/a.out+0x4008b1)
==12787== ABORTING

总结

asan能够检测出内存越界和非法,但是对于malloc与free的匹配就不能检测到了。

如果需要使用交叉编译链编译的话,需要交叉工具链里面支持libasan.so库,一般高于4.8的版本都是自带这个库的,然后把这个动态库拷贝到开发板的lib目录下就可以了。

 

你可能感兴趣的:(Linux)