博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
valgrind +gdb 调试
阅读量:6271 次
发布时间:2019-06-22

本文共 4909 字,大约阅读时间需要 16 分钟。

hot3.png

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

valgrind的结构图

 

Valgrind包括如下一些工具:

 

 

  1. Memcheck。这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。这也是本文将重点介绍的部分。
  2. Callgrind。它主要用来检查程序中函数调用过程中出现的问题。
  3. Cachegrind。它主要用来检查程序中缓存使用出现的问题。
  4. Helgrind。它主要用来检查多线程程序中出现的竞争问题。
  5. Massif。它主要用来检查程序中堆栈使用中出现的问题。
  6. Extension。可以利用core提供的功能,自己编写特定的内存调试工具

linux下内存空间布置:

典型内存空间布局

下面下valgrind 中memcheck 和callgrind 的简单使用;--db-attach=yes 可以在发现问题的时候进入

gdb调试,注意经过实践发现随着memcheck,callgrind option 越多将影响内存分布,多线程调用顺序.使得毕现的crash变成偶现,或者偶现问题变得毕现.

下面是valgrind 对内存reachable的分类及说明,根据valgrind output 中内存泄露的类型可以预测

内存丢失的场景.

Pointer chain            AAA Leak Case   BBB Leak Case     -------------            -------------   -------------(1)  RRR ------------> BBB                    DR(2)  RRR ---> AAA ---> BBB    DR              IR(3)  RRR               BBB                    DL(4)  RRR      AAA ---> BBB    DL              IL(5)  RRR ------?-----> BBB                    (y)DR, (n)DL(6)  RRR ---> AAA -?-> BBB    DR              (y)IR, (n)DL(7)  RRR -?-> AAA ---> BBB    (y)DR, (n)DL    (y)IR, (n)IL(8)  RRR -?-> AAA -?-> BBB    (y)DR, (n)DL    (y,y)IR, (n,y)IL, (_,n)DL(9)  RRR      AAA -?-> BBB    DL              (y)IL, (n)DLPointer chain legend:- RRR: a root set node or DR block- AAA, BBB: heap blocks- --->: a start-pointer- -?->: an interior-pointerLeak Case legend:- DR: Directly reachable- IR: Indirectly reachable- DL: Directly lost- IL: Indirectly lost- (y)XY: it's XY if the interior-pointer is a real pointer- (n)XY: it's XY if the interior-pointer is not a real pointer- (_)XY: it's XY in either case

Every possible case can be reduced to one of the above nine. Memcheck merges some of these cases in its output, resulting in the following four leak kinds.

  • "Still reachable". This covers cases 1 and 2 (for the BBB blocks) above. A start-pointer or chain of start-pointers to the block is found. Since the block is still pointed at, the programmer could, at least in principle, have freed it before program exit. "Still reachable" blocks are very common and arguably not a problem. So, by default, Memcheck won't report such blocks individually.

  • "Definitely lost". This covers case 3 (for the BBB blocks) above. This means that no pointer to the block can be found. The block is classified as "lost", because the programmer could not possibly have freed it at program exit, since no pointer to it exists. This is likely a symptom of having lost the pointer at some earlier point in the program. Such cases should be fixed by the programmer.

  • "Indirectly lost". This covers cases 4 and 9 (for the BBB blocks) above. This means that the block is lost, not because there are no pointers to it, but rather because all the blocks that point to it are themselves lost. For example, if you have a binary tree and the root node is lost, all its children nodes will be indirectly lost. Because the problem will disappear if the definitely lost block that caused the indirect leak is fixed, Memcheck won't report such blocks individually by default.

  • "Possibly lost". This covers cases 5--8 (for the BBB blocks) above. This means that a chain of one or more pointers to the block has been found, but at least one of the pointers is an interior-pointer. This could just be a random value in memory that happens to point into a block, and so you shouldn't consider this ok unless you know you have interior-pointers.

(Note: This mapping of the nine possible cases onto four leak kinds is not necessarily the best way that leaks could be reported; in particular, interior-pointers are treated inconsistently. It is possible the categorisation may be improved in the future.)

Furthermore, if suppressions exists for a block, it will be reported as "suppressed" no matter what which of the above four kinds it belongs to.

Example:

note: --trace-origins= yes 在memcheck 中可以用来追踪被使用的未初始化数据,是在何时创建分配的.

valgrind --trace-children=yes --tool=memcheck  --show-reachable=yes --leak-check=full --keep-stacktraces=alloc-then-free --db-attach=yes ./x264 -v   --pass 1 --bitrate 2000 -o test.264 --input-res 1280x720 --input-csp i420 ./1280_720_frame_10.yuv 

 

 

 

 

 

callgrind:

下面是一个callgrind 的的调用截图,callgrind 的check结果默认会保存在callgrind.out.pid 问题件中.

如果你调试的程序是多线程,你也可以在命令行中加一个参数 -separate-threads=yes。这样就会为每个线程单独生成一个性能分析文件。如下:

valgrind --tool=callgrind --separate-threads=yes ./app

 

valgrind --trace-children=yes --tool=callgrind   --db-attach=yes ./x264 -v   --pass 1 --bitrate 2000 -o test.264 --input-res 1280x720 --input-csp i420 ./1280_720_frame_10.yuv 

1,运行命令,可以从命令打印中看出下个版本db-attach 将被--vgdb-error=1 取代.

194546_8lS5_269082.png

2,valgrind 检测处问题,询问是否启动gdb ?按键c 继续不起懂,按键y 启动gdb调试

194724_QTwk_269082.png

3,按键y 进入gdb 调试,看出可能在数组定义的时候出现问题

195000_s7qg_269082.png

4,查看当前backtrace 中fram 0 的源码.

195124_7DBp_269082.png

5,打印nal_unit_type_str 发现定义了13 个char* ,只初始化了11个.

195210_GcDw_269082.png

 

 

 

 

杂记:

show commands 可以助记之前的命令.

211506_bov6_269082.png

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/269082/blog/832657

你可能感兴趣的文章
JavaWeb下载文件response
查看>>
Laravel的三种安装方法总结
查看>>
SpringMVC加载配置Properties文件的几种方式
查看>>
C#设计模式总结 C#设计模式(22)——访问者模式(Vistor Pattern) C#设计模式总结 .NET Core launch.json 简介 利用Bootstrap Paginat...
查看>>
java 项目相关 学习笔记
查看>>
numpy opencv matlab eigen SVD结果对比
查看>>
WPF获取某控件的位置,也就是偏移量
查看>>
Boost C++ 库 中文教程(全)
查看>>
solr查询优化(实践了一下效果比较明显)
查看>>
jdk目录详解及其使用方法
查看>>
说说自己对RESTful API的理解s
查看>>
通过layout实现可拖拽自动排序的UICollectionView
查看>>
服务器错误码
查看>>
javascript中的面向对象
查看>>
Splunk作为日志分析平台与Ossec进行联动
查看>>
yaffs文件系统
查看>>
Mysql存储过程
查看>>
NC营改增
查看>>
Lua
查看>>
Mysql备份系列(3)--innobackupex备份mysql大数据(全量+增量)操作记录
查看>>