C++程序常碰到内存double free引起程序崩溃的问题,有时候通过分析代码来发现造成内存重复释放的地方是比较困难的。幸好通过systemtap我们可以轻松地找到造成内存重复释放的地方,下面通过一个简单的例子来说明检测方法。

systemtap检测内存double free代码

//doubleFreeCheck.stp
global ptr2bt
global ptr2countprobe begin {warn("Start tracing. Wait for 10 sec to complete.\n")
}probe process("/usr/lib64/libc.so.6").function("__libc_malloc").return {if (pid() == target()) {//printf("malloc: %p (bytes %d)\n", $return, $bytes)ptr = $returnif(ptr != 0) {ptr2count[ptr] = 1}}
}probe process("/usr/lib64/libc.so.6").function("__libc_free") {if (pid() == target()) {//printf("free: %p\n", $mem)ptr = $memif(ptr != 0) {bt = ptr2bt[ptr]if(ptr2count[ptr] == 0) {printf("double free detected!\n");printf("===================current free stack================================\n")print_ustack(ubacktrace())printf("=====================================================================\n")printf("===================previous free stack===============================\n")print_ustack(bt)printf("=====================================================================\n")} else {ptr2count[ptr] = 0bt = ubacktrace()ptr2bt[ptr] = bt}}}
}probe end {delete ptr2btdelete ptr2count
}

测试demo程序

//g++ -g test.cpp -o test#include <unistd.h>char *p = NULL;void func1(int i) {if(i%3 == 0)p = new char[10];
}void func2(int i) {if(i%3 == 1) delete[] p;
}void func3(int i) {if(i%10 == 0) delete[] p;
} int main() {for(int i=0;i<60;i++) {func1(i);func2(i);func3(i);sleep(1);}return 0;
}

测试命令:stap -d /home/dongsongz/debug/stap/doubleFree/test -d /usr/lib64/libstdc++.so.6.0.19 ./doubleFreeCheck.stp -c ./test

测试结果如下,可见首次内存释放在于func3,再次释放在func2,发生了double free引起程序崩溃。

stap -d /home/dongsongz/debug/stap/doubleFree/test -d /usr/lib64/libstdc++.so.6.0.19 ./doubleFreeCheck.stp -c ./test
WARNING: Start tracing. Wait for 10 sec to complete.
*** Error in `./test': double free or corruption (fasttop): 0x00000000023d0010 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x81329)[0x7fd67fb45329]
./test[0x4006a4]
./test[0x40071a]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fd67fae6555]
./test[0x400559]
======= Memory map: ========
00400000-00401000 r-xp 00000000 fd:00 20827024                           /home/dongsongz/debug/stap/doubleFree/test
00600000-00601000 r--p 00000000 fd:00 20827024                           /home/dongsongz/debug/stap/doubleFree/test
00601000-00602000 rw-p 00001000 fd:00 20827024                           /home/dongsongz/debug/stap/doubleFree/test
023d0000-023f1000 rw-p 00000000 00:00 0                                  [heap]
7fd678000000-7fd678021000 rw-p 00000000 00:00 0
7fd678021000-7fd67c000000 ---p 00000000 00:00 0
7fd67fac4000-7fd67fc88000 r-xp 00000000 fd:00 355066                     /usr/lib64/libc-2.17.so
7fd67fc88000-7fd67fe87000 ---p 001c4000 fd:00 355066                     /usr/lib64/libc-2.17.so
7fd67fe87000-7fd67fe8b000 r--p 001c3000 fd:00 355066                     /usr/lib64/libc-2.17.so
7fd67fe8b000-7fd67fe8d000 rw-p 001c7000 fd:00 355066                     /usr/lib64/libc-2.17.so
7fd67fe8d000-7fd67fe92000 rw-p 00000000 00:00 0
7fd67fe92000-7fd67fea7000 r-xp 00000000 fd:00 85                         /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7fd67fea7000-7fd6800a6000 ---p 00015000 fd:00 85                         /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7fd6800a6000-7fd6800a7000 r--p 00014000 fd:00 85                         /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7fd6800a7000-7fd6800a8000 rw-p 00015000 fd:00 85                         /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7fd6800a8000-7fd6801a9000 r-xp 00000000 fd:00 355074                     /usr/lib64/libm-2.17.so
7fd6801a9000-7fd6803a8000 ---p 00101000 fd:00 355074                     /usr/lib64/libm-2.17.so
7fd6803a8000-7fd6803a9000 r--p 00100000 fd:00 355074                     /usr/lib64/libm-2.17.so
7fd6803a9000-7fd6803aa000 rw-p 00101000 fd:00 355074                     /usr/lib64/libm-2.17.so
7fd6803aa000-7fd680493000 r-xp 00000000 fd:00 355165                     /usr/lib64/libstdc++.so.6.0.19
7fd680493000-7fd680693000 ---p 000e9000 fd:00 355165                     /usr/lib64/libstdc++.so.6.0.19
7fd680693000-7fd68069b000 r--p 000e9000 fd:00 355165                     /usr/lib64/libstdc++.so.6.0.19
7fd68069b000-7fd68069d000 rw-p 000f1000 fd:00 355165                     /usr/lib64/libstdc++.so.6.0.19
7fd68069d000-7fd6806b2000 rw-p 00000000 00:00 0
7fd6806b2000-7fd6806d4000 r-xp 00000000 fd:00 355059                     /usr/lib64/ld-2.17.so
7fd6808b7000-7fd6808bc000 rw-p 00000000 00:00 0
7fd6808d1000-7fd6808d3000 rw-p 00000000 00:00 0
7fd6808d3000-7fd6808d4000 r--p 00021000 fd:00 355059                     /usr/lib64/ld-2.17.so
7fd6808d4000-7fd6808d5000 rw-p 00022000 fd:00 355059                     /usr/lib64/ld-2.17.so
7fd6808d5000-7fd6808d6000 rw-p 00000000 00:00 0
7ffc8ca6a000-7ffc8ca8b000 rw-p 00000000 00:00 0                          [stack]
7ffc8cb76000-7ffc8cb78000 r-xp 00000000 00:00 0                          [vdso]
7fffffffe000-7ffffffff000 --xp 00000000 00:00 0
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
WARNING: Child process exited with signal 6 (Aborted)
double free detected!
===================current free stack================================0x7fd67fb49b60 : free+0x0/0xe0 [/usr/lib64/libc-2.17.so]0x4006a4 : _Z5func2i+0x48/0x4a [/home/dongsongz/debug/stap/doubleFree/test]0x40071a : main+0x25/0x4b [/home/dongsongz/debug/stap/doubleFree/test]0x7fd67fae6555 : __libc_start_main+0xf5/0x1c0 [/usr/lib64/libc-2.17.so]0x400559 : _start+0x29/0x30 [/home/dongsongz/debug/stap/doubleFree/test]
=====================================================================
===================previous free stack===============================0x7fd67fb49b60 : free+0x0/0xe0 [/usr/lib64/libc-2.17.so]0x4006f3 : _Z5func3i+0x4d/0x4f [/home/dongsongz/debug/stap/doubleFree/test]0x400724 : main+0x2f/0x4b [/home/dongsongz/debug/stap/doubleFree/test]0x7fd67fae6555 : __libc_start_main+0xf5/0x1c0 [/usr/lib64/libc-2.17.so]0x400559 : _start+0x29/0x30 [/home/dongsongz/debug/stap/doubleFree/test]
=====================================================================
WARNING: /usr/bin/staprun exited with status: 1
Pass 5: run failed.  [man error::pass5]

Linux系统C++调试利器systemtap定位内存double free相关推荐

  1. python 监控linux硬盘,Python3监控windows,linux系统的CPU、硬盘、内存使用率和各个端口的开启情况详细代码实例...

    由于项目的需要,需要做一个简单监控服务器的CPU利用率.CPU负载.硬盘使用率.内存利用率和服务器的各个端口的开启情况的程序,并把结果通知到监控平台,如果出现异常,监控平台打电话或者发短信通知给具体的 ...

  2. Linux系统查看当前主机CPU、内存、机器型号及主板信息

    Linux系统查看当前主机CPU.内存.机器型号及主板信息: 查看CPU信息(型号) # cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 查 ...

  3. Linux系统中消息队列,共享内存、信号和线程的基本操作使用方法

    Linux系统中消息队列,共享内存.信号和线程高级操作 第十一章 消息队列 10.1消息队列定义 10.2 消息队列特点 10.3 key值 10.4 创建消息队列 10.4.1 发送消息 10.4. ...

  4. linux下使用命令行辅助定位内存泄漏问题

    文章目录 前言 一.free命令: 命令 内容解释 其它 二.top命令 命令 其它 三. cat /proc/$pid/status 命令 内容解释 总结 前言 最近自己正在做的一款产品,因内存泄漏 ...

  5. linux查找用户前三进程_查看 Linux 系统中进程和用户的内存使用情况 | Linux 中国...

    有一些命令可以用来检查 Linux 系统中的内存使用情况,下面是一些更好的命令.-- Sandra Henry-stocker 有许多工具可以查看 Linux 系统中的内存使用情况.一些命令被广泛使用 ...

  6. linux系统状态(磁盘大小、内存、进程、cpu使用率、网络连接)

    分享一下自己做的一个获取Linux系统状态的类(c++)(代码整理后的,在物理机上测试可以,在vm虚拟机上测试,磁盘计算有问题) 头文件 #ifndef LINUXSERVERSTATE_H #def ...

  7. linux系统 qt调试,Linux下Qt Creator远程调试(redhat5+mini6410)

    当我们开发嵌入式系统下的Qt应用程序时,有时候不能在虚拟机上进行调试,这时候我们需要通过远程调试的方式在PC上调试嵌入式系统下的Qt应用程序.这样就产生了交叉调试. 本文环境介绍: 虚拟机:vmwar ...

  8. Linux系统【五】进程间通信-共享内存mmap

    mmap函数 #include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags,int fd, ...

  9. Unix/Linux操作系统分析实验二 内存分配与回收:Linux系统下利用链表实现动态内存分配

    Unix/Linux操作系统分析实验一 进程控制与进程互斥 Unix/Linux操作系统分析实验三 文件操作算法: 实现在/proc目录下添加文件 Unix/Linux操作系统分析实验四 设备驱动: ...

最新文章

  1. php删除目录下的所有文件和目录
  2. DICOM医学图像处理:Dcmtk与fo-dicom保存文件的不同设计模式之“同步VS异步”+“单线程VS多线程”...
  3. Android中自定义xmlns
  4. linux服务器无网络确认,Linux服务器故障排查实用指南
  5. 使计算机工作必不可缺的软件,探讨测绘工程中计算机制图的运用问题(原稿)
  6. Java NIO编程基础
  7. mysql canvert mongo_如何在MongoDB中的$match中使用聚合运算符(例如$year或$dayOfMonth)?...
  8. react 返回一个页面_react-router-dom 怎么让第二个页面返回到第一个页面使得第一个页面不重新加载...
  9. 数据挖掘在电信欺诈侦测中的应用
  10. html手机端图片点击放大缩小快捷键,PS放大缩小图片的快捷键是什么?PS放大缩小图片的操作技巧...
  11. IM 产品设计思考(4)- 问答机器人
  12. office2010 启动man_解决word2010启动慢的两种方法
  13. 扫雷android设计思路,Flash扫雷游戏设计思路与步骤(4)
  14. 全球首个区块链经理人指数发布: 3月BMI 62.7 行业景气整体向好
  15. 解决Layui表格头部工具栏事件绑定失效,上传文件按钮失效问题
  16. 如何创建一个原始Mac OS镜像
  17. 应用内添加原生广告,变现与用户体验可兼得
  18. 按键控制LED灯开关
  19. 董宝珍:巴菲特是如何选股的?——从底层逻辑看巴菲特核心重仓股的思路、原则和条件...
  20. 前端通用SEO技术优化指南

热门文章

  1. python 读取jpg_Python OpenCV读取png图像转成jpg图像存储的方法
  2. 3.10 Maya历法
  3. 激光slam基础入门笔记2——位姿表示与变换矩阵
  4. uniapp-微信小程序-ios音乐播放没声音
  5. python magic number_编程中的「魔数」(magic number)是什么意思?平时我们能接触到哪些魔数?...
  6. 卷积神经网络残差计算
  7. LruCache缓存图片+清除本地缓存
  8. 麒麟V10SP1的国产化Qt适配
  9. RNA-Seq质控工具RseQC安装使用
  10. 分享课丨微软研究院资深主任研究员郑宇教授:多源数据融合与时空数据挖掘(一)...