Valgrind的用法
来源:互联网 发布:算法分析与设计 王晓东 编辑:程序博客网 时间:2024/06/04 18:40
一、valgrind介绍
调用valgrind的通用格式为
// test4.c
// test5.c
// test6.c
valgrind不对静态数组(分配在栈上)进行边界检查
// test7.c
1、valgrind体系结构
(1)valgrind有内核(core)以及基于内核的其他调试工具组成。
(2)内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具。
(3)其他工具则类似于插件(plug-in),利用内核提供的服务完成各种特点的内存调试任务。
2、valgrind工具集
(1)Memcheck:valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况。
(2)Callgrind:它主要用来检查程序中函数调用过程中出现的问题。
(3)Cachegrind:它主要用来检查程序中缓存使用出现的问题。
(4)Helgrind:它主要用来检查多线程程序中出现的竞争问题。
(5)Massif:它主要用来检查程序中堆栈使用中出现的问题。
(6)Extension:可以利用core提供的功能,自己编写特定的内存调试工具。
二、valgrind内存检查
1、linux程序的内存布局
(1)代码段(.text)
存放的是CPU要执行的指令。代码段是可以共享的,相同的代码在内存中只会有一个拷贝,同时这个段是只读的,
防止程序由于错误而修改自身的指令。
(2)初始化数据段(.data)
存放的是程序中需要明确赋初始值的变量,内核在调用exec函数启动该程序时从源程序文件中读入。int val = 100;
(3)未初始化数据段(.bss)
位于这一段中的数据,内核在执行该程序前,将其初始化为0或者null。int sum;
(4)堆(Heap)
用于在程序中进行动态内存申请,如malloc,new等函数。
(5)栈(Stack)
函数中的局部变量,在函数调用过程中产生的临时变量。
2、内存检查原理
Memcheck能够检测出内存问题,关键在于其建立了两个全局表。
(1)Valid-Value表
对于进程的整个地址空间中的每一个字节(byte),都有与之对应的8个bits。
对于CPU的每个寄存器,也有一个与之对应的bit向量。
这些bits负责记录该字节或者寄存器值是否具有有效的、已初始化的值。
(2)Valid-Address表
对于进程整个地址空间中的每一个字节(byte),还有与之对应的1个bit,
负责记录该地址是否能够被读写。
(3)当要读写内存中某个字节时,首先检查这个字节对应的A bit。
如果该A bit显示该位置是无效位置,memcheck则报告读写错误。
(4)内核类似于一个虚拟的CPU环境,当内存中的某个字节被加载到真实的CPU中,该字节对应的V bit也被加载到
虚拟的CPU环境中。一旦寄存器中的值,被用来产生内存地址,或者该值能够影响程序输出,则memcheck会检查
对应的V bit,如果该值尚未初始化,则会报告使用未初始化内存错误。
三、valgrind的用法
为了使valgrind发现的错误更精确,建议在编译时加上-g参数,编译优化选项选择O0,虽然这会降低程序的执行效率。
gcc -g -O0 prog.c -o prog
valgrind [valgrind-options] prog [prog-options]
内存非法使用的检测方法
valgrind --tool=memcheck --leak-check=yes prog
1、检测内存泄漏
// test1.c
#include <stdio.h>#include <stdlib.h>int main(void){ char *p = malloc(10); return EXIT_SUCCESS;}
$ gcc -g -O0 test1.c -o test1$ valgrind --tool=memcheck --leak-check=yes test1==37444== Memcheck, a memory error detector==37444== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.==37444== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info==37444== Command: test1==37444====37444====37444== HEAP SUMMARY:==37444== in use at exit: 10 bytes in 1 blocks==37444== total heap usage: 1 allocs, 0 frees, 10 bytes allocated==37444====37444== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1==37444== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37444== by 0x400537: main (test1.c:6)==37444====37444== LEAK SUMMARY:==37444== definitely lost: 10 bytes in 1 blocks==37444== indirectly lost: 0 bytes in 0 blocks==37444== possibly lost: 0 bytes in 0 blocks==37444== still reachable: 0 bytes in 0 blocks==37444== suppressed: 0 bytes in 0 blocks==37444====37444== For counts of detected and suppressed errors, rerun with: -v==37444== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
2、检测对非法内存地址的访问
// test2.c
#include <stdio.h>#include <stdlib.h>int main(void){ char *p = malloc(10); p[10] = 1; free(p); return EXIT_SUCCESS;}
$ gcc -g -O0 test2.c -o test2$ valgrind --tool=memcheck --leak-check=yes test2==37481== Memcheck, a memory error detector==37481== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.==37481== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info==37481== Command: test2==37481====37481== Invalid write of size 1==37481== at 0x400584: main (test2.c:7)==37481== Address 0x520304a is 0 bytes after a block of size 10 alloc'd==37481== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37481== by 0x400577: main (test2.c:6)==37481====37481====37481== HEAP SUMMARY:==37481== in use at exit: 0 bytes in 0 blocks==37481== total heap usage: 1 allocs, 1 frees, 10 bytes allocated==37481====37481== All heap blocks were freed -- no leaks are possible==37481====37481== For counts of detected and suppressed errors, rerun with: -v==37481== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
3、读取未初始化区域
// test3.c
#include <stdio.h>#include <stdlib.h>int main(void){ int *x = malloc(sizeof(int)); int a = *x + 1; free(x); return a;}
$ gcc -g -O0 test3.c -o test3$ valgrind --tool=memcheck --leak-check=yes test3==37505== Memcheck, a memory error detector==37505== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.==37505== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info==37505== Command: test3==37505====37505== Syscall param exit_group(status) contains uninitialised byte(s)==37505== at 0x4F05B98: _Exit (_exit.c:31)==37505== by 0x4E73FAA: __run_exit_handlers (exit.c:97)==37505== by 0x4E74044: exit (exit.c:104)==37505== by 0x4E5A836: (below main) (libc-start.c:325)==37505====37505====37505== HEAP SUMMARY:==37505== in use at exit: 0 bytes in 0 blocks==37505== total heap usage: 1 allocs, 1 frees, 4 bytes allocated==37505====37505== All heap blocks were freed -- no leaks are possible==37505====37505== For counts of detected and suppressed errors, rerun with: -v==37505== Use --track-origins=yes to see where uninitialised values come from==37505== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)4、访问已释放的区域
// test4.c
#include <stdio.h>#include <stdlib.h>int main(void){ int *x = malloc(sizeof(int)); free(x); int a = *x + 1; return a;}
$ gcc -g -O0 test4.c -o test4$ valgrind --tool=memcheck --leak-check=yes test4==37533== Memcheck, a memory error detector==37533== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.==37533== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info==37533== Command: test4==37533====37533== Invalid read of size 4==37533== at 0x40058C: main (test4.c:8)==37533== Address 0x5203040 is 0 bytes inside a block of size 4 free'd==37533== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37533== by 0x400587: main (test4.c:7)==37533== Block was alloc'd at==37533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37533== by 0x400577: main (test4.c:6)==37533====37533====37533== HEAP SUMMARY:==37533== in use at exit: 0 bytes in 0 blocks==37533== total heap usage: 1 allocs, 1 frees, 4 bytes allocated==37533====37533== All heap blocks were freed -- no leaks are possible==37533====37533== For counts of detected and suppressed errors, rerun with: -v==37533== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)5、内存双重释放
// test5.c
#include <stdio.h>#include <stdlib.h>int main(void){ char *x = malloc(sizeof(int)); free(x); free(x); return EXIT_SUCCESS;}
$ gcc -g -O0 test5.c -o test5$ valgrind --tool=memcheck --leak-check=yes test5==37554== Memcheck, a memory error detector==37554== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.==37554== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info==37554== Command: test5==37554====37554== Invalid free() / delete / delete[] / realloc()==37554== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37554== by 0x400593: main (test5.c:8)==37554== Address 0x5203040 is 0 bytes inside a block of size 4 free'd==37554== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37554== by 0x400587: main (test5.c:7)==37554== Block was alloc'd at==37554== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37554== by 0x400577: main (test5.c:6)==37554====37554====37554== HEAP SUMMARY:==37554== in use at exit: 0 bytes in 0 blocks==37554== total heap usage: 1 allocs, 2 frees, 4 bytes allocated==37554====37554== All heap blocks were freed -- no leaks are possible==37554====37554== For counts of detected and suppressed errors, rerun with: -v==37554== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)6、内存覆盖
// test6.c
#include <stdio.h>#include <stdlib.h>#include <string.h>int main(int argc, char *argv[]){ char x[50]; int i; for(i = 0; i < 50; i++) { x[i] = i + 1; } strncpy(x+20, x, 20); // ok strncpy(x+20, x, 21); // overlap strncpy(x, x+20, 20); // ok strncpy(x, x+20, 21); // overlap x[39] = '\0'; strcpy(x, x+20); // ok x[39] = 39; x[40] = '\0'; strcpy(x, x+20); // overlap return 0;}
$ gcc -g -O0 test6.c -o test6$ valgrind --tool=memcheck --leak-check=yes test6==37692== Memcheck, a memory error detector==37692== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.==37692== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info==37692== Command: test6==37692====37692== Source and destination overlap in strncpy(0xffefffb49, 0xffefffb35, 21)==37692== at 0x4C31626: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37692== by 0x40064F: main (test6.c:14)==37692====37692== Source and destination overlap in strncpy(0xffefffb35, 0xffefffb49, 21)==37692== at 0x4C31626: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37692== by 0x400687: main (test6.c:16)==37692====37692== Source and destination overlap in strcpy(0xffefffb20, 0xffefffb34)==37692== at 0x4C310E6: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==37692== by 0x4006C1: main (test6.c:23)==37692====37692====37692== HEAP SUMMARY:==37692== in use at exit: 0 bytes in 0 blocks==37692== total heap usage: 0 allocs, 0 frees, 0 bytes allocated==37692====37692== All heap blocks were freed -- no leaks are possible==37692====37692== For counts of detected and suppressed errors, rerun with: -v==37692== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)7、valgrind不能检测的错误
valgrind不对静态数组(分配在栈上)进行边界检查
// test7.c
#include <stdio.h>#include <stdlib.h>int main(void){ char x[10]; x[11] = 'a'; return EXIT_SUCCESS;}
$ valgrind --vgdb=yes --tool=memcheck --leak-check=yes test7==37863== Memcheck, a memory error detector==37863== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.==37863== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info==37863== Command: test7==37863====37863====37863== HEAP SUMMARY:==37863== in use at exit: 0 bytes in 0 blocks==37863== total heap usage: 0 allocs, 0 frees, 0 bytes allocated==37863====37863== All heap blocks were freed -- no leaks are possible==37863====37863== For counts of detected and suppressed errors, rerun with: -v==37863== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
0 0
- valgrind的用法
- Valgrind的用法
- valgrind用法
- valgrind用法
- Valgrind简单用法
- valgrind简单用法
- Valgrind简单用法
- valgrind基本用法
- Valgrind简单用法
- Valgrind简单用法
- Valgrind简单用法
- Valgrind简单用法
- Valgrind简单用法
- Valgrind简单用法
- Valgrind简单用法
- Valgrind简单用法
- valgrind 内存检测工具用法
- Valgrind简单用法
- SpannableString属性详解
- Windows下获取文件权限
- 使用PHP生成二维码的两种方法(带logo图像)
- ServletConfig和ServletContext对象
- Android动态来改变App桌面图标--根据不同节日显示不同logo
- Valgrind的用法
- Android
- PHP用isset替换count之优化
- ext 不错的入门
- 初学Angular+webpack+bootstrap
- PHP去除文章的html格式
- 代码规范文档学习笔记
- 使用Ngrok免注册版将内网项目发布到外网上(Windows系统下)
- Struts2中的ModelDriven机制及其运用