Windows和Linux内存检测工具:Valgrind,Visual Leak Detector,CppCheck, Cpplint

田琛
2023-12-01

 

1 Linux内存泄漏检测工具Valgrind

 

 

 

Valgrind简介

        Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。

Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。

 

Valgrind用法

valgrind [options] prog-and-args [options]: 常用选项,适用于所有Valgrind工具。

- tool=<name> 最常用的选项。运行 valgrind中名为toolname的工具。默认memcheck。
h –help 显示帮助信息。
-version 显示valgrind内核的版本,每个工具都有各自的版本。
q –quiet 安静地运行,只打印错误信息。
v –verbose 更详细的信息, 增加错误数统计。
-trace-children=no|yes 跟踪子线程? [no]
-track-fds=no|yes 跟踪打开的文件描述?[no]
-time-stamp=no|yes 增加时间戳到LOG信息? [no]
-log-fd=<number> 输出LOG到描述符文件 [2=stderr]
-log-file=<file> 将输出的信息写入到filename.PID的文件里,PID是运行程序的进行ID
-log-file-exactly=<file> 输出LOG信息到 file
-log-file-qualifier=<VAR> 取得环境变量的值来做为输出信息的文件名。 [none]
-log-socket=ipaddr:port 输出LOG到socket ,ipaddr:port
LOG信息输出
-xml=yes 将信息以xml格式输出,只有memcheck可用
-num-callers=<number> show <number> callers in stack traces [12]
-error-limit=no|yes 如果太多错误,则停止显示新错误? [yes]
-error-exitcode=<number> 如果发现错误则返回错误代码 [0=disable]
-db-attach=no|yes 当出现错误,valgrind会自动启动调试器gdb。[no]
-db-command=<command> 启动调试器的命令行选项[gdb -nw %f %p]
适用于Memcheck工具的相关选项:
-leak-check=no|summary|full 要求对leak给出详细信息? [summary]
-leak-resolution=low|med|high how much bt merging in leak check [low]
-show-reachable=no|yes show reachable blocks in leak check? [no]

 

 

安装valgrind

azheng@ubuntu16:~/test$ sudo apt-get install valgrind

 

测试代码

azheng@ubuntu16:~/test$ cat testcode.c 

#include <stdlib.h>

int *fun()
{
    int *p = malloc(10 * sizeof(int));
    p[10] =0 ;  //error 1
    return p;
}

int main()
{
    int *ptr = NULL;
    ptr = fun();
    //free(c);  //error 2
    ptr = NULL;
    return 0;
}


编译:
azheng@ubuntu16:~/gcc testcode.c -o main
azheng@ubuntu16:~/test$ ls

main  testcode.c

 

 

 

valgrind使用

azheng@ubuntu16:~/test$ valgrind --tool=memcheck  --leak-check=full ./main

 

报告

==77673== Memcheck, a memory error detector
==77673== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==77673== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==77673== Command: ./main
==77673== 
==77673== Invalid write of size 4
==77673==    at 0x400544: fun (in /home/azheng/test/main)
==77673==    by 0x400566: main (in /home/azheng/test/main)
==77673==  Address 0x5204068 is 0 bytes after a block of size 40 alloc'd
==77673==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==77673==    by 0x400537: fun (in /home/azheng/test/main)
==77673==    by 0x400566: main (in /home/azheng/test/main)
==77673== 
==77673== 
==77673== HEAP SUMMARY:
==77673==     in use at exit: 40 bytes in 1 blocks
==77673==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==77673== 
==77673== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==77673==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==77673==    by 0x400537: fun (in /home/azheng/test/main)
==77673==    by 0x400566: main (in /home/azheng/test/main)
==77673== 
==77673== LEAK SUMMARY:
==77673==    definitely lost: 40 bytes in 1 blocks
==77673==    indirectly lost: 0 bytes in 0 blocks
==77673==      possibly lost: 0 bytes in 0 blocks
==77673==    still reachable: 0 bytes in 0 blocks
==77673==         suppressed: 0 bytes in 0 blocks
==77673== 
==77673== For counts of detected and suppressed errors, rerun with: -v
==77673== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

 

重新修改代码后,进行内存检查

azheng@ubuntu16:~/test$ valgrind --tool=memcheck  --leak-check=yes --show-reachable=yes ./main 
==77813== Memcheck, a memory error detector
==77813== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==77813== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==77813== Command: ./main
==77813== 
==77813== 
==77813== HEAP SUMMARY:
==77813==     in use at exit: 0 bytes in 0 blocks
==77813==   total heap usage: 1 allocs, 1 frees, 40 bytes allocated
==77813== 
==77813== All heap blocks were freed -- no leaks are possible
==77813== 
==77813== For counts of detected and suppressed errors, rerun with: -v
==77813== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

 

说明

Invalid write of size 4:表示数组越界写了4字节

40 bytes in 1 blocks:表示因程序退出而发生内存泄露40字节

 

 

 

2 Windows内存泄漏检测工具VLD

 

Visual Leak Detector

下载链接:https://vld.codeplex.com/releases


在Visual C++ IDE的"工具"→"选项"→"项目和解决方案"→"VC++ 目录","包含文件"增加VLD的"\include"路径,"库文件"增加VLD的"\lib\Win32"路径,另外动态库"\bin\Win32"路径在安装时已经添加到环境变量里面了,若是未添加,则需要手动拷贝"\bin\Win32"下的文件到工程Debug目录。

添加#include "vld.h"


 

3 CppCheck

        Windows版本不好用,Linux还可以。

4 Cpplint

 

代码规范检查

azheng@ubuntu16:~$ cat test/testcode.c 

#include <stdlib.h>

int *fun()
{
    int *x = malloc(10 * sizeof(int));
    x[10] =0 ; //error
}

int main()
{
    int *c = NULL;
    c = fun();
    return 0;
}

 

azheng@ubuntu16:~$ cppcheck test/testcode.c 

Checking test/testcode.c...
[test/testcode.c:5]: (error) Array 'x[10]' accessed at index 10, which is out of bounds.

[test/testcode.c:6]: (error) Memory leak: x

 

azheng@ubuntu16:~$ cpplint-1.3.0/cpplint.py test/testcode.c 
test/testcode.c:0:  No copyright message found.  You should have a line: "Copyright [year] <Copyright Owner>"  [legal/copyright] [5]
test/testcode.c:3:  { should almost always be at the end of the previous line  [whitespace/braces] [4]
test/testcode.c:4:  Tab found; better to use spaces  [whitespace/tab] [1]
test/testcode.c:5:  Tab found; better to use spaces  [whitespace/tab] [1]
test/testcode.c:5:  At least two spaces is best between code and comments  [whitespace/comments] [2]
test/testcode.c:5:  Should have a space between // and comment  [whitespace/comments] [4]
test/testcode.c:5:  Missing spaces around =  [whitespace/operators] [4]
test/testcode.c:5:  Extra space before last semicolon. If this should be an empty statement, use {} instead.  [whitespace/semicolon] [5]
test/testcode.c:9:  { should almost always be at the end of the previous line  [whitespace/braces] [4]
test/testcode.c:10:  Tab found; better to use spaces  [whitespace/tab] [1]
test/testcode.c:11:  Tab found; better to use spaces  [whitespace/tab] [1]
test/testcode.c:12:  Tab found; better to use spaces  [whitespace/tab] [1]
Done processing test/testcode.c
Total errors found: 12

 

 

 
 类似资料: