在日常开发中,遇到段错误是很常见的事,其中一种情况 Out of memory(OOM),内存泄露问题一般不好查找,但是可以借助工具来快速定位。

这里介绍的工具是valgrind,这个工具在buildroot有提供,如下图,选中,然后重新编译

valgrind 工具

memcheck :检测程序中的内存问题,如内存泄漏,越界,非法指针等

callgrind:检测程序代码的运行时间和调用过程,以及分析程序性能。

cachegrind:分析CPU的cache命中率,丢失率,用于进行代码优化。

helgrind:用于检测多线程程序中出现的竞争问题

Massif:堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理和栈的大小。

先上个测试案例 1.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void main()
{char *p = malloc(1024);char *p1 = malloc(512);char buf[3] = {0};strcpy(buf,"1234");printf("buf==%s\n",buf);p = NULL;while(1);
}

这个例子在给两个指针分配内存后,p直接指向了NULL,程序退出。

编译程序:

gcc 1.c -g -o 1,其中-g是为了保留符号表,可以定位到代码中具体某一行

valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --undef-value-errors=no --log-file=1.log  ./1

tool=memcheck 表示检测内存问题。

leak-check=full 表示完全检测内存泄漏

–log-file=log 表示信息会输入到log文件中(有时文件内容比较多,这样方便分析)

等程序退出或者通过kill 方式再查看log信息。

==17242== Memcheck, a memory error detector
==17242== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17242== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==17242== Command: ./1
==17242== Parent PID: 12570
==17242==
==17242==
==17242== Process terminating with default action of signal 2 (SIGINT)
==17242==    at 0x4005CF: main (1.c:13)
==17242==
==17242== HEAP SUMMARY:
==17242==     in use at exit: 1,536 bytes in 2 blocks
==17242==   total heap usage: 3 allocs, 1 frees, 2,560 bytes allocated
==17242==
==17242== 512 bytes in 1 blocks are still reachable in loss record 1 of 2
==17242==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17242==    by 0x400594: main (1.c:8)
==17242==
==17242== 1,024 bytes in 1 blocks are definitely lost in loss record 2 of 2
==17242==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17242==    by 0x400586: main (1.c:7)
==17242==
==17242== LEAK SUMMARY:
==17242==    definitely lost: 1,024 bytes in 1 blocks
==17242==    indirectly lost: 0 bytes in 0 blocks
==17242==      possibly lost: 0 bytes in 0 blocks
==17242==    still reachable: 512 bytes in 1 blocks
==17242==         suppressed: 0 bytes in 0 blocks
==17242==
==17242== For counts of detected and suppressed errors, rerun with: -v
==17242== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

其中最重要的是 HEAP SUMMARY:  表示你的程序内存泄漏的大小

如上面显示有1536 bytes,后面就是泄露的详细信息,并且都有定位到行号。

LEAK SUMMARY关键字。表示内存泄漏的类型:

definitely lost:确定的内存泄漏,已经不能访问这块内存

indirectly lost:指向该内存的指针都位于内存泄露处

possibly lost:可能的内存泄露,仍然存在某个指针能够访问某快内存,但该指针指向的已经不是                         该内存首位置

still reachable:内存指针还在还有机会使用或者释放,指针指向的动态内存还没有被释放就退出了

通过ctrl+c退出了程序,512字节内存仍然由p1指向,但p指向NULL,所以p1部分为are still reachable,但p为are definitely lost。

valgrind还有更多强大的功能,具体可以查看 valgrind -h

关于内存还存在越界的问题。还是上面的案例,数组buf只有3个字节,但是strcpy的时候给了4个,造成越界损坏其它数据的可能性。

如何查找这种情况呢?

可以在编译的时候加上 -fsanitize=address 选项

如:gcc 1.c -fsanitize=address  -g -o 1

然后运行./1  ,就会发现

=================================================================
==32083==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd32182b33 at pc 0x7f55e23cc904 bp 0x7ffd32182af0 sp 0x7ffd32182298
WRITE of size 5 at 0x7ffd32182b33 thread T0
    #0 0x7f55e23cc903 in __asan_memcpy (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x8c903)
    #1 0x400993 in main /1.c:10
    #2 0x7f55e1f9683f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
    #3 0x400818 in _start (/RD/alan.wang/1+0x400818)

Address 0x7ffd32182b33 is located in stack of thread T0 at offset 35 in frame
    #0 0x4008f5 in main /RD/alan.wang/1.c:6

This frame has 1 object(s):
    [32, 35) 'buf' <== Memory access at offset 35 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 __asan_memcpy
Shadow bytes around the buggy address:
  0x100026428510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100026428520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100026428530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100026428540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100026428550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100026428560: 00 00 f1 f1 f1 f1[03]f4 f4 f4 f3 f3 f3 f3 00 00
  0x100026428570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100026428580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100026428590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000264285a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000264285b0: 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 right 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
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==32083==ABORTING

运行的时候发现越界,有地址被覆盖的提示,并且会终止程序。

Linux快速定位内存泄露和内存越界相关推荐

  1. Java内存泄露和内存溢出、JVM命令行工具、.JDK可视化工具、Java Class文件

    1.Java内存泄露和内存溢出对比 1.1 Java 内存泄露 内存泄露是指一个不再被程序使用的对象或变量还在内存中占用空间. 1.1.1判断内存空间是否符合垃圾回收的标准 在Java语言中,判断一个 ...

  2. Java基础恶补——内存泄露、内存溢出

     Java基础恶补--内存泄露.内存溢出 (2010-09-15 15:56:26) 转载 标签: 杂谈 要点 内存泄露是指程序中间动态分配了内存,但在程序结束时没有释放这部分内存,从而造成那部分 ...

  3. java内存泄露和内存溢出

    内存泄露 是指:对象没有被用到,但是又无法被GC回收就是内存泄露: 分类:经常发生: 发生内存泄露的代码会被多次执行,每次执行,泄露一块内存偶然发生: 在某些特定情况下才会发生一次性: 发生内存泄露的 ...

  4. jvm故障 内存泄露和内存溢出总结

    目录 内存泄漏memory leak 内存泄漏的分类(按发生方式来分类) 内存泄露的场景 静态集合类 / 长生命周期的对象持有短生命周期对象的引用 / 单例模式 /类加载器 各种连接,如数据库连接.网 ...

  5. C/C++什么是内存泄露,内存泄露如何避免?

    C/C++什么是内存泄露,内存泄露如何避免? 1. 内存溢出 2. 内存泄漏 3. 造成内存泄露常见的三种情况 3.1 指针重新赋值 3.2 错误的内存释放 3.3 返回值的不正确处理 4. 如何避免 ...

  6. java 解决内存泄露_Java内存泄露的理解与解决

    Java内存管理机制 在C++语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期.从申请分配.到使用.再到最后的释放.这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记 ...

  7. Java内存泄露系列--内存泄露的原因及解决方案(大全)

    原文网址:Java内存泄露系列--内存泄露的原因及解决方案(大全)_IT利刃出鞘的博客-CSDN博客 简介 简介 本文介绍Java中内存泄露的一些原因与解决方案. 如果内存泄露的空间足够大,就会导致内 ...

  8. java什么时候可能产生内存溢出_JAVA内存泄露和内存溢出

    1)概念: 内存溢出:指在指定大小的内存空间,写入了超出大小的数据,从而导致了内存溢出. 内存溢出:指程序运行过程中无法申请到足够的内存而导致的一种错误. 内存溢出通常发生于OLD段或Perm段垃圾回 ...

  9. C++内存机制中内存泄露、内存溢出、内存越界和内存泄漏原因分析

    在用C++做底层驱动时,经常会遇到内存不足的警告,往往是因为内存出现溢出.泄露或者越界等原因. 内存溢出(out of memory) 是指程序在申请内存时,没有足够的内存空间供其使用. 内存泄漏(m ...

最新文章

  1. 关于ognl+struts-tag与el+jstl互相代替,以及el和jstl的学习笔记
  2. luogu P1345 [USACO5.4]奶牛的电信Telecowmunication(建图技巧 - “割点”模板 、最小割)
  3. monocross 环境搭建:MonoTouch Mono for Android
  4. 为什么是string.join(list)而不是list.join(string)?
  5. python3 判断字符串是否包含指定字符
  6. 记录mysql客户端所有的操作
  7. 让linux系统做网关,代理上网!!!
  8. 130塔式服务器系统,PowerEdge T130塔式服务器怎么样
  9. react结合redux的开发步骤
  10. linux执行脚本查找ip,linux 查看ip、用户、时间对应执行的命令
  11. STM32的串口通信
  12. wordpress主题-一款功能强大的综合类型wordpress模板
  13. 图像处理中各种边缘检测的微分算子简单比较(Sobel,Robert, Prewitt,Laplacian,Canny) 【转】
  14. TCMalloc小记【转】
  15. Oracle数据同步接口,增量数据从ERP系统到本地临时表封装解决方案
  16. 简单理解t检验与秩和检验
  17. mysql改列名_mysql怎么修改列名
  18. 最优控制理论 八、CasADi求解路径约束轨迹优化的多重打靶法
  19. SAP ABAP BASE64 MD5 加解密
  20. GridPanel中表头全选框的小问题

热门文章

  1. 信息系统项目管理师(软考高项)备考总结
  2. 速卖通排序规则,优化产品信息,让店铺引流更精准
  3. 华为新影像优秀作品亮相Paris Photo,再创全球影响力
  4. 【模拟】洛谷 P1000 超级玛丽游戏
  5. 微信小程序:娱乐小工具微信小程序源码下载支持多种流量主
  6. 推荐信模版(英文)计算机专业
  7. 机器学习(Dog vs Cat)猫狗大战
  8. 安卓最新系统_诺基亚安卓手机均已升级为安卓9 谷歌“干儿子”果然名不虚传...
  9. vba 定义类_在类中定义和触发自己的事件(上)
  10. 西南民族大学计算机基础技能应用培训基地,第六届计算机基础技能应用培训基地开班典礼顺利举行...