背景

排查和检测内存泄漏的问题时,需要选择一些好用的工具,由于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 <main> 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目录下就可以了。

 

技术
©2019-2020 Toolsou All rights reserved,
LinkedHashMap基本用法&使用实现简单缓存 dedecms网站被黑 劫持到其他网站如何解决苹果不送充填器耳机真为环保?可能还是为了赚钱吧图片格式转换错误总结-myBatis plus 分页numpy:多维数组的创建用C语言做很简单的飞机游戏Keras保存与加载模型(JSON+HDF5)福布斯中国汽车富豪榜:何小鹏第11 李想第14 李斌第15hive大量小文件处理方法总结