###Date: 2017/10/15
###Author:SoaringLee
Valgrind工具检测内存错误
Valgrind是一个检测内存问题的开源工具,可以用于检测linux下应用程序的内存泄漏问题。但是对于静态数组越界的问题,valgrind是检测不出来的,对于这个问题,可以采用converity静态检查。这个工具对于内存泄漏诊断非常有用,特整理下面相关问题。
1、内存泄漏
1.1 错误提示
are definitely lost in loss
1.2 C源代码mem_leak.c
#include <stdio.h>
#include <stdlib.h>
void memcheck()
{
char* p = (char*)malloc(20);
}
int main()
{
memcheck();
return 0;
}
1.3 使用命令
2、文件指针资源泄漏
2.1 错误提示
FILE DESCRIPTORS:4 open at exit
2.2 源代码
#include <stdio.h>
#include <stdlib.h>
void fopencheck()
{
FILE* p = fopen("test.txt","w");
}
int main()
{
fopencheck();
return 0;
}
2.3 测试结果
3、动态内存越界
3.1 错误提示
Invalid write
3.2 源代码
#include <stdio.h>
#include <stdlib.h>
void memcheck()
{
char* p = malloc(1);
*(short*)p = 2;
free(p);
}
int main()
{
memcheck();
return 0;
}
3.3 测试结果
4、无法检测数组越界
4.1错误提示
无法对分配在栈上的静态数组检测越界
4.2 源代码
#include <stdio.h> #include <stdlib.h> void memcheck() { char array[3]; strcpy(array,"hello"); } int main() { memcheck(); return 0; }
4.3 检测结果
5、内存释放两次或多次
5.1 错误提示
Invalid free()/delete/delete[]/realloc()
5.2 源代码
#include <stdio.h> #include <stdlib.h> void memcheck() { char* p = (char*)malloc(20); free(p); free(p); } int main() { memcheck(); return 0; }
6、使用野指针
6.1 错误提示
Invalid write of size
6.2 源代码
#include <stdio.h> #include <stdlib.h> void memcheck() { char* p = (void*)0x80808080; *p = 10; } int main() { memcheck(); return 0; }
6.3 测试结果
7、释放野指针
7.1 错误提示
Invalid free()/delete/delete[]/realloc()
7.2 源代码
#include <stdio.h>
#include <stdlib.h>
void memcheck()
{
char* p;
free(p);
}
int main()
{
memcheck();
return 0;
}
7.3 测试结果
8、valgrind的主要参数
- -h --help
- --help-debug
- --version
- -q, --quiet
- -v, --verbose:显示详细信息。
-
-tool=<toolname>[default:memcheck]
-
--log-file=<file>
-
--trace-children=<yes|no>[default:no]
9、常见错误
- malloc/free: in use at exit 内存在退出前没有释放
- invalid write of size 非法写入内存,一般为数组越界
- invalid read of size 非法读内存:一般为数组越界
- definitely lost /possibly lost /still reachable in loss record 内存未释放
- invalid free()/delete/delete[] 同一指针被多次释放
- source and destination overlay 一般是使用strncpy,memcpy引起
- syscall param contains uninitialized byte 调用系统函数时传入了未初始化的变量
- conditional jump or move depends on uninitialized value 条件判断时使用了未初始化的变量
- access not with mapped region/stack overflow 栈溢出
- mismatch free()/delete/delete[]/new delete/malloc/free搭配错误