valgrind检查C/C++内存泄漏
valgrind --tool=memcheck --leak-check=full ./httptest
valgrind --tool=memcheck --leak-check=full --track-origins=yes --show-reachable=yes ./httptest
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]
// Automatic objects are not destroyed as a result of calling exit()
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <vector>
#include <algorithm>
#include <sstream>
#include <string>
int fail(const std::string str)
{
std::cerr<< str << std::endl;
exit();
}
const std::string usage()
{
std::string a = "a";
return a;
}
int main()
{
fail(usage());
;
}
$ g++ -std=c++0x main.cpp -o xmain
$ valgrind ./xmain
==18699== definitely lost: 0 bytes in 0 blocks
==18699== indirectly lost: 0 bytes in 0 blocks
==18699== possibly lost: 26 bytes in 1 blocks
==18699== still reachable: 0 bytes in 0 blocks
==18699== suppressed: 0 bytes in 0 blocks
==18699== Rerun with --leak-check=full to see details of leaked memory
coredump文件
什么是coredump?
通常情况下coredmp包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息等。可以理解为把程序工作的当前状态存储成一个文件。许多程序和操作系统出错时会自动生成一个core文件。
造成程序coredump的原因很多,这里根据以往的经验总结一下:
1 内存访问越界
a) 由于使用错误的下标,导致数组访问越界
b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符
c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。
2 多线程程序使用了线程不安全的函数。
应该使用下面这些可重入的函数,尤其注意红色标示出来的函数,它们很容易被用错:
asctime_r(3c) gethostbyname_r(3n) getservbyname_r(3n)
ctermid_r(3s) gethostent_r(3n) getservbyport_r(3n) ctime_r(3c)
getlogin_r(3c) getservent_r(3n) fgetgrent_r(3c) getnetbyaddr_r(3n)
getspent_r(3c) fgetpwent_r(3c) getnetbyname_r(3n) getspnam_r(3c) fgetspent_r(3c)
getnetent_r(3n) gmtime_r(3c) gamma_r(3m) getnetgrent_r(3n) lgamma_r(3m)
getauclassent_r(3) getprotobyname_r(3n) localtime_r(3c) getauclassnam_r(3)
etprotobynumber_r(3n) nis_sperror_r(3n) getauevent_r(3)
getprotoent_r(3n) rand_r(3c) getauevnam_r(3)
getpwent_r(3c) readdir_r(3c) getauevnum_r(3) getpwnam_r(3c)strtok_r(3c)
getgrent_r(3c) getpwuid_r(3c) tmpnam_r(3s) getgrgid_r(3c) getrpcbyname_r(3n)
ttyname_r(3c) getgrnam_r(3c) getrpcbynumber_r(3n) gethostbyaddr_r(3n)
getrpcent_r(3n)
3 多线程读写的数据未加锁保护。
对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump
4 非法指针
a) 使用空指针
b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型
的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它
时就很容易因为bus error而core dump. 总线错误(bus error)通常是指针强制转换,导致CPU读取数据违反了一定的总线规则。《c专家编程》
|
#include <stdlib.h> #include <stdio.h> #if defined(__GNUC__) # if defined(__i386__) /* Enable Alignment Checking on x86 */ __asm__("pushf\norl $0x40000,(%esp)\npopf"); # elif defined(__x86_64__) /* Enable Alignment Checking on x86_64 */ __asm__("pushf\norl $0x40000,(%rsp)\npopf"); # endif #endif int main() { union{ char a[10]; int i; }u; int *p =(int*)&(u.a[1]); *p =17; printf("%d\n", *p); } |
原因是:
x86体系结构会把地址对齐之后,访问两次,然后把第一次的尾巴和第二次的头拼起来。
如果不是x86,那种体系结构下的机器不肯自动干这活,就会产生core。
如果在代码中将对齐检查功能打开,运行后能显示bus error。
5 堆栈溢出
不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。
内存泄漏memory leak
在通常的编程开发与应用中,宽泛地讲,内存泄漏是分配了内存但是没有在程序终止前释放。严格且更有实际意义地讲,内存泄漏是分配了某块内存但是随后程序不再拥有指向该内存的任何指针了。内存泄露检测工具valgrind使用的便是严格意义上内存泄露检测原则。下文如果没有特殊说明,一概指严格定义的内存泄露。内存泄露潜在地引起显著的堆消耗,特别对于长久持续运行的程序。关于“still reachable”类型的Valgrind内存泄露检测报告仅适用于宽泛定义的内存泄露。假如使用valgrind工具检测到了程序出现“still reachable”,说明程序没有释放这种类型的内存块,但是并不代表这些内存块永远的丢失了,不能被释放了,因为程序依然拥有指向这些内存块的指针。一般而言,它们不会引起严格意义上的内存泄露造成的问题(潜在的堆空间消耗以致无内存可用),所以不用担心这些“still
reachable”内存块。这是因为这些内存块通常申请一次,在进程的整个生命周期内一直保持着引用。当然,你也可以全程确保你的程序释放掉所有分配的内存。因为OS会在进程终止后回收进程的所有内存,因此这样做的意义不大。相反,如果存在真正的内存泄露,也许仅仅引起进程消耗的内存多于所需,也许程序运行时间足够长,引起一个进程耗尽内存。
valgrind检查C/C++内存泄漏的更多相关文章
- Valgrind工具------可以分析内存泄漏
Valgrind 是个开源的工具,功能很多.例如检查内存泄漏工具---memcheck. 安装: 1)官网下载:http://www.valgrind.org/downloads/ , 下载tar.b ...
- 移植Valgrind检测Android JNI内存泄漏
1.相关工具 Valgrind:从Valgrind官网下载最新的源码包,我这里用的是:valgrind 3.14.0 (tar.bz2) [17MB] - 9 October 2018. Ubuntu ...
- 调不尽的内存泄漏,用不完的Valgrind
调不尽的内存泄漏,用不完的Valgrind Valgrind 安装 1. 到www.valgrind.org下载最新版valgrind-X.X.X.tar.bz2 2. 解压安装包:tar –jxvf ...
- 检查c# 内存泄漏
c# 内存泄漏检查心得 系统环境 windows 7 x64 检查工具:ANTS Memory Profiler 7 或者 .NET Memory Profiler 4.0 开发的软件为winform ...
- c# 内存泄漏检查心得
系统环境 windows 7 x64 检查工具:ANTS Memory Profiler 7 或者 .NET Memory Profiler 4.0 开发的软件为winform / windows s ...
- 利用 LeakCanary 来检查 Android 内存泄漏
前言 你被概率性的 OOM 困扰么?有时候,OOM 像幽灵一样,挥之不去,可真想把它揪出来时,又捉之不着.或许,是时候用 LeakCanary 来诊断一下了.它是一个用来检查 Android 下内存泄 ...
- 使用 Android Studio 检测内存泄漏与解决内存泄漏问题
本文在腾讯技术推文上 修改 发布. http://wetest.qq.com/lab/view/63.html?from=ads_test2_qqtips&sessionUserType=BF ...
- 一个跨平台的 C++ 内存泄漏检测器
2004 年 3 月 01 日 内存泄漏对于C/C++程序员来说也可以算作是个永恒的话题了吧.在Windows下,MFC的一个很有用的功能就是能在程序运行结束时报告是否发生了内存泄漏.在Linux下, ...
- 【c++】内存检查工具Valgrind介绍,安装及使用以及内存泄漏的常见原因
转自:https://www.cnblogs.com/LyndonYoung/articles/5320277.html Valgrind是运行在Linux上一套基于仿真技术的程序调试和分析工具,它包 ...
随机推荐
- 【shell 每日一练7】一键安装mysql5.7,以及密码及策略修改
一.一键安装Mysql脚本 [root@uat01 ~]# cat InstallMysql01.sh #!/bin/bash #-- #旅行者-Travel #.安装wget yum -y inst ...
- Machine Learning笔记整理 ------ (一)基本概念
机器学习的定义:假设用P来评估计算机程序在某任务类T上的性能,若一个程序通过利用经验E,使其在T中任务获得了性能改善,我们则说关于任务类T和P,该程序对经验E进行了学习(Mitchell, 1997) ...
- python分割文件目录/文件名和后缀
import os file_path = "D:/test/test.py" (filepath,tempfilename) = os.path.split(file_path) ...
- 王者荣耀交流协会-小组互评Alpha版本
小组分工如下: 1.探路者---贪吃蛇(测评人:王玉玲) 链接:http://www.cnblogs.com/WYLFZ/p/7805520.html http://www.cnblogs.co ...
- AVL树 算法思想与代码实现
AVL树是高度平衡的二叉搜索树,按照二叉搜索树(Binary Search Tree)的性质,AVL首先要满足: 若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不为空, ...
- lintcode-413-反转整数
413-反转整数 将一个整数中的数字进行颠倒,当颠倒后的整数溢出时,返回 0 (标记为 32 位整数). 样例 给定 x = 123,返回 321 给定 x = -123,返回 -321 标签 整数 ...
- C++ auto_ptr智能指针的用法
C++中指针申请和释放内存通常采用的方式是new和delete.然而标准C++中还有一个强大的模版类就是auto_ptr,它可以在你不用的时候自动帮你释放内存.下面简单说一下用法. 用法一: std: ...
- linux应用自启动配置
Linux在启动时,会自动执行/etc/rc.d目录下的初始化程序,因此我们可以把启动任务放到该目录下: 1.因为其中的rc.local是在完成所有初始化之后执行,因此可以把启动脚本写到里面: 2.用 ...
- webgl helloworld
之前的webgl 初识1, 初识2 已经介绍了webgl的基本概念,工作原理. 没有理解的自己yy. 现呈上例子一枚 <!DOCTYPE html> <html lang=" ...
- 如何在DBGrid里实现Shift+“选择行”区间多选的功能!
DELPHI 的TDBGrid 控 件 主 要 用 来 处 理 数 据 表, 它 的 属 性 中 有 一 个dgMultiSelect, 若 此 属 性 设 定 为TRUE, 则 可 以 选 中 多 ...