Linux内存检查工具

ASAN 使用

  1. 安装asan库
    一般gcc4.8以上带,但默认不会安装
yum install libasan*
  1. 编译选项
LDADD +=-L/usr/lib/gcc/aarch64-linux-gnu/7.3.0/ -lasan
LFLAGS = -g1 -fsanitize=address -fno-omit-frame-pointer -O1
  1. 运行
export ASAN_OPTIONS=halt_on_error=0:use_sigaltstack=0:detect_leaks=1:malloc_context_size=15:log_path=/userdata/logasan/
LD_PRELOAD=/usr/lib/gcc/aarch64-linux-gnu/7.3.0/libasan.so /var/eyou/queue/bin/smtpd

backtrace()的使用
在退出位置调用下面dump()

#ifdef __linux
#include <sys/syscall.h>
#endif
#include <execinfo.h>     /* for backtrace() */
#define BACKTRACE_SIZE 1024
void dump(void)
{
    int j, nptrs;
    void *buffer[BACKTRACE_SIZE];
    char **strings;
    nptrs = backtrace(buffer, BACKTRACE_SIZE);

    eyou_syslog("backtrace() returned %d addresses\n", nptrs);

    strings = backtrace_symbols(buffer, nptrs);
    if (strings == NULL) {
        perror("backtrace_symbols");
        exit(EXIT_FAILURE);
	}
   
   for (j = 0; j < nptrs; j++)
   eyou_syslog("  [%02d] %s\n", j, strings[j]);
    if(strings != NULL)
    {
    	printf("dump free strings err s\n"); 
		free(strings);
	  	strings = NULL;
	}
}
  1. Linux例子:
#include <stdio.h>
#include <stdlib.h>

void access_invalid_memory() {
    int* ptr = malloc(sizeof(int));
    *ptr = 10;
    free(ptr);
    printf("The value is: %d\n", *ptr);  // 这里访问已经释放的内存
}

int main() {
    access_invalid_memory();
    return 0;
}

编译:

gcc -g example.c -o example -fsanitize=address

运行:

./example
=================================================================
==5828== ERROR: AddressSanitizer: heap-use-after-free on address 0x60040000dff0 at pc 0x4008e7 bp 0x7fff352b37c0 sp 0x7fff352b37b0
READ of size 4 at 0x60040000dff0 thread T0
    #0 0x4008e6 (/root/test/memory_check_tool/asan/example+0x4008e6)
    #1 0x40090d (/root/test/memory_check_tool/asan/example+0x40090d)
    #2 0x7fc641109554 (/usr/lib64/libc-2.17.so+0x22554)
    #3 0x400788 (/root/test/memory_check_tool/asan/example+0x400788)
0x60040000dff0 is located 0 bytes inside of 4-byte region [0x60040000dff0,0x60040000dff4)
freed by thread T0 here:
    #0 0x7fc6414caff9 (/usr/lib64/libasan.so.0.0.0+0x15ff9)
    #1 0x4008af (/root/test/memory_check_tool/asan/example+0x4008af)
    #2 0x40090d (/root/test/memory_check_tool/asan/example+0x40090d)
    #3 0x7fc641109554 (/usr/lib64/libc-2.17.so+0x22554)
previously allocated by thread T0 here:
    #0 0x7fc6414cb119 (/usr/lib64/libasan.so.0.0.0+0x16119)
    #1 0x40085e (/root/test/memory_check_tool/asan/example+0x40085e)
    #2 0x40090d (/root/test/memory_check_tool/asan/example+0x40090d)
    #3 0x7fc641109554 (/usr/lib64/libc-2.17.so+0x22554)
Shadow bytes around the buggy address:
  0x0c00ffff9ba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c00ffff9bf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[fd]fa
  0x0c00ffff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==5828== ABORTING

valgrind memcheck

安装

yum install valgrind -y

说明:

  1. 概念:

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

    Valgrind包括memcheck、Callgrind、Cachegrind、Helgrind、Massif等工具。

    memcheck用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete 的调用都会被捕获。

  2. 命令行

    valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --undef-value-errors=no --log-file=log ./可执行程序名
    

    –tool=memcheck:使用 memcheck 工具检测内存错误,包括使用未初始化的变量、读写越界等;
    –leak-check=full:全面检测内存泄漏,不仅仅检测未释放的内存,还会检测处理时出现的一些问题;
    –show-leak-kinds=all:显示所有的内存泄漏信息;
    –undef-value-errors=no:不检查未定义的值错误;
    –log-file=log:将日志信息输出到 log 文件中;

示例:

testValgrind.cpp

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

void MyTest()
{
	char* p = (char*)malloc(sizeof(char)*10);
	
	delete[] p;

	cout << "MyTest finished" << endl;

	delete[] p;
}

int main()
{
	MyTest();

	return 0;
}

编译:

g++ -o testValgrind testValgrind.cpp

检查内存:

valgrind --leak-check=yes ./testValgrind

结果:

==12366== Memcheck, a memory error detector
==12366== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12366== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==12366== Command: ./testValgrind
==12366== 
==12366== Mismatched free() / delete / delete []
==12366==    at 0x4C2BB8F: operator delete[](void*) (vg_replace_malloc.c:651)
==12366==    by 0x400898: MyTest() (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366==    by 0x4008D2: main (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366==  Address 0x5ab1c80 is 0 bytes inside a block of size 10 alloc'd
==12366==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==12366==    by 0x400881: MyTest() (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366==    by 0x4008D2: main (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366== 
MyTest finished
==12366== Invalid free() / delete / delete[] / realloc()
==12366==    at 0x4C2BB8F: operator delete[](void*) (vg_replace_malloc.c:651)
==12366==    by 0x4008C7: MyTest() (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366==    by 0x4008D2: main (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366==  Address 0x5ab1c80 is 0 bytes inside a block of size 10 free'd
==12366==    at 0x4C2BB8F: operator delete[](void*) (vg_replace_malloc.c:651)
==12366==    by 0x400898: MyTest() (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366==    by 0x4008D2: main (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366==  Block was alloc'd at
==12366==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==12366==    by 0x400881: MyTest() (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366==    by 0x4008D2: main (in /root/test/memory_check_tool/memcheck/testValgrind)
==12366== 
==12366== 
==12366== HEAP SUMMARY:
==12366==     in use at exit: 0 bytes in 0 blocks
==12366==   total heap usage: 2 allocs, 3 frees, 72,714 bytes allocated
==12366== 
==12366== All heap blocks were freed -- no leaks are possible
==12366== 
==12366== For lists of detected and suppressed errors, rerun with: -s
==12366== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

Dmalloc

参考:https://www.cnblogs.com/renhl/p/3302486.html

  1. 下载:

http://dmalloc.com/releases/

  1. 安装:
tar zxvf dmalloc-5.5.2.tgz
cd dmalloc-5.5.2
./configure --prefix=/usr
make
make install
  1. 使用:
    设置环境变量:在~/.bashrc添加
function dmalloc { eval `command dmalloc -b $*`; }

然后重新登陆用户,或者执行:

source ~/.bashrc
  1. 示例代码:
//gcc -DDMALLOC -DDMALLOC_FUNC_CHECK -ldmalloc test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef DMALLOC
#include <dmalloc.h>
#endif
int main(int argc, char **argv)
{
  char *string;
  string = (char*)malloc(sizeof(char));
  string = (char*)malloc(sizeof(int*));

  return 0;
}
  1. 编译:
gcc -DDMALLOC -DDMALLOC_FUNC_CHECK -ldmalloc test.c -L/root/test/memory_check_tool/Dmalloc/dmalloc-5.5.2/ -l dmalloc
dmalloc -l logfile -i 100 low
  1. 运行:./a.out
  2. 查看logfile
1711700382: 2: Dmalloc version '5.6.5' from 'http://dmalloc.com/'
1711700382: 2: flags = 0x4e48503, logfile 'logfile'
1711700382: 2: interval = 100, addr = 0x0, seen # = 0, limit = 0
1711700382: 2: starting time = 1711700382
1711700382: 2: process pid = 15807
1711700382: 2: Dumping Chunk Statistics:
1711700382: 2: basic-block 4096 bytes, alignment 8 bytes
1711700382: 2: heap address range: 0x7f5c7b993000 to 0x7f5c7b9a4000, 69632 bytes
1711700382: 2:     user blocks: 2 blocks, 8153 bytes (14%)
1711700382: 2:    admin blocks: 12 blocks, 49152 bytes (85%)
1711700382: 2:    total blocks: 14 blocks, 57344 bytes
1711700382: 2: heap checked 1
1711700382: 2: alloc calls: malloc 2, calloc 0, realloc 0, free 0
1711700382: 2: alloc calls: recalloc 0, memalign 0, valloc 0
1711700382: 2: alloc calls: new 0, delete 0
1711700382: 2:   current memory in use: 9 bytes (2 pnts)
1711700382: 2:  total memory allocated: 9 bytes (2 pnts)
1711700382: 2:  max in use at one time: 9 bytes (2 pnts)
1711700382: 2: max alloced with 1 call: 8 bytes
1711700382: 2: max unused memory space: 39 bytes (81%)
1711700382: 2: top 10 allocations:
1711700382: 2:  total-size  count in-use-size  count  source
1711700382: 2:           8      1           8      1  test.c:12
1711700382: 2:           1      1           1      1  test.c:11
1711700382: 2:           9      2           9      2  Total of 2
1711700382: 2: Dumping Not-Freed Pointers Changed Since Start:
1711700382: 2:  not freed: '0x7f5c7b998fe8|s1' (8 bytes) from 'test.c:12'
1711700382: 2:  not freed: '0x7f5c7b9a3ff8|s1' (1 bytes) from 'test.c:11'
1711700383: 2:  total-size  count  source
1711700383: 2:           8      1  test.c:12
1711700383: 2:           1      1  test.c:11
1711700383: 2:           9      2  Total of 2
1711700383: 2: ending time = 1711700383, elapsed since start = 0:00:01
  • Dmalloc version ‘5.6.5’ from ‘http://dmalloc.com/’:显示DMALLOC版本信息。
  • flags = 0x4e48503, logfile ‘logfile’:显示一些标志和日志文件名。
  • heap address range: 0x7f5c7b993000 to 0x7f5c7b9a4000, 69632 bytes:显示堆的地址范围和大小。
  • user blocks: 2 blocks, 8153 bytes (14%):显示用户分配的内存块数量和大小。
  • admin blocks: 12 blocks, 49152 bytes (85%):显示管理(内部)分配的内存块数量和大小。
  • alloc calls: malloc 2, calloc 0, realloc 0, free 0:显示不同内存分配函数的调用次数。
  • current memory in use: 9 bytes (2 pnts):当前使用的内存大小。
  • max in use at one time: 9 bytes (2 pnts):最大同时使用的内存大小。
  • top 10 allocations:显示前十个内存分配情况。
  • Dumping Not-Freed Pointers Changed Since Start:显示从开始以来未释放的指针。
  • ending time = 1711700383, elapsed since start = 0:00:01:显示结束时间和从开始到结束的时间。

Dmalloc的局限性:

  1. Dmalloc只能检测堆上内存,对栈内存和静态内存无能为力。

  2. dmalloc只用于利用malloc申请的内存,对使用sbrk()或mmap()分配的内存无能为力。

  3. dmalloc不能用于检测读写没有申请的或者没有初始化的内存,也不能检测写只读内存。

cppcheck

  1. 下载:

Cppcheck - A tool for static C/C++ code analysis

  1. 安装:
tar -zxvf cppcheck-2.13.0.tar.gz
cd cppcheck-2.13.0
  1. 手动设置 FILESDIR 变量: 在执行 make 命令之前,先手动设置 FILESDIR 变量的值:
export FILESDIR=/usr/share/cppcheck

尝试:

yum install g++ make python
yum install python3
make MATCHCOMPILER=yes CFGDIR=/usr/share/cppcheck HAVE_RULES=yes
make install
make clean
  1. 编译安装:
make -j
make install
  1. 使用:

查看cppcheck版本:

cppcheck --version

启用所有检查规则,检查某个文件

cppcheck --enable=all --inconclusive testValgrind.cpp 

检查当前路径下的代码,并输出到 txt 文件 – err.txt

cppcheck testValgrind.cpp --output-file=err.txt

输出 xml 格式的日志文件 – log.xml

cppcheck testValgrind.cpp --enable=all --output-file=log.xml --xml

检查某个路径,不输出过程日志

cppcheck --quiet ../memcheck/

Clang Static Analyzer

  1. 安装:
yum install clang

查看版本:

clang --version
clang version 3.4.2 (tags/RELEASE_34/dot2-final)
Target: x86_64-redhat-linux-gnu
Thread model: posix

查看clang位置:

which clang
/usr/bin/clang
  1. 使用:

例子:example.c

#include <stdlib.h>

int main() {
    int *ptr;
    if (rand() > 0) {
        ptr = malloc(10 * sizeof(int));
    }
    *ptr = 5;
    return 0;
}

在example.c目录:

命令:

/usr/bin/clang --analyze example.c

结果:

example.c:8:10: warning: Dereference of undefined pointer value
    *ptr = 5;
example.c:9:5: warning: Potential leak of memory pointed to by 'ptr'
    return 0;
    ^~~~~~~~
2 warnings generated.

生成的example.plist文件是Clang Static Analyzer的分析结果报告,以plist(Property List)格式保存。这个plist文件包含了代码的静态分析结果,其中记录了各种警告、错误和建议的修复方法。

在这个plist文件中,你可以找到以下信息:

警告信息:包括代码中可能存在的问题,例如空指针解引用、内存泄漏、潜在的越界访问等。

错误信息:代码中的严重问题,可能导致程序崩溃或安全漏洞。

修复建议:针对每个问题,Clang Static Analyzer会提供一些建议的修复方法,帮助开发者改进代码质量。

可以使用不同的工具或者脚本来解析example.plist文件,从中提取出有用的信息,帮助开发者定位和解决代码中的潜在问题。

  • 27
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以通过使用内存泄漏检查工具检查Linux系统中的内存泄漏问题。通常使用的工具有Valgrind、DMalloc和Mtrace等,使用它们可以定位出哪些代码、变量或调用等引起内存泄漏,并及时修复解决问题。内存泄漏问题不仅会导致系统性能下降和程序运行效率低下,还可能导致系统崩溃,因此及时解决内存泄漏问题尤为重要。 ### 回答2: Linux内存泄露指的是程序在运行过程中未及时释放内存资源所导致的问题。由于内存资源是有限的,内存泄露可能会导致程序运行变慢甚至崩溃。因此,检查和及时修复内存泄露是保证程序高效稳定运行的重要要求之一。 在Linux中,内存泄露的检查可以通过多种工具来实现。其中最常用的工具是valgrind。valgrind是一款基于动态二进制插桩技术的内存调试和分析工具,可以检测程序使用内存的情况,包括内存泄漏、未初始化的内存、读/写越界和使用已释放内存等问题。valgrind支持多种编程语言,例如C、C++、Java等。 使用valgrind进行内存泄漏检查,可以通过以下步骤实现: 1. 在终端中输入命令“valgrind --leak-check=full ./可执行文件名”,其中“--leak-check=full”表示开启内存泄漏检查模式,“./可执行文件名”表示要检查的可执行文件的路径和名称。 2. 运行程序,当程序结束时,valgrind会输出内存泄漏的相关信息,包括泄漏的内存地址、大小、泄漏时的代码位置等。同时,valgrind还会生成一个报告文件,提供更详细的泄漏信息和其他问题。 3. 根据输出信息,定位内存泄漏的原因,并进行修复。 总之,内存泄漏是一个非常常见的程序错误,也是严重的问题之一。通过使用valgrind等工具进行内存泄漏检查,可以帮助程序员快速定位并解决内存泄漏问题,从而提高程序的性能和稳定性。 ### 回答3: Linux 内存泄漏检查是一项非常重要的任务,因为内存泄漏可能导致系统的崩溃和数据的丢失,而且通常很难追踪和修复。 内存泄漏是指在分配内存时,程序未正确释放其使用的内存。 这意味着这些内存块将一直存在,直到系统重新启动或进程被杀死。由于内存泄漏会导致系统崩溃,因此必须对其进行检查。 有几种工具可用于检查 Linux 上的内存泄漏。其中最常见的是 Valgrind。 Valgrind 是一款调试和性能工具,可检查 C/C++ 代码的内存泄漏以及许多其他类型的内存问题。Valgrind 采用动态二进制翻译(DBT)技术,可以模拟 CPU,并通过这种方式将软件运行在虚拟 CPU 上。由于 Valgrind 在虚拟 CPU 上运行,因此它可以检测和拦截访问内存的软件错误,而这些错误可能会导致崩溃、内存泄漏等问题。 另一个流行的工具是 Massif。Massif 是一个 Valgrind 编写的堆分析程序,可用于检查堆的使用情况,以帮助发现内存泄漏。它会收集信息并生成有关程序使用的堆的图表和统计信息,从而帮助开发人员更容易地找出问题并修复它们。 除了 Valgrind 和 Massif,还有一些其他工具可用于检查内存泄漏,例如 AddressSanitizer 和 LeakSanitizer。无论使用哪种工具,都必须确保测试程序具有足够的复杂性和具有代表性,以使测试结果具有实用价值。 在 Linux 上进行内存泄漏检查是一项艰巨的任务,但使用正确的工具和方法可以大大简化它。通过使用这些工具和方法,您可以找出并修复程序中的内存泄漏,确保系统稳定和数据的安全。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值