内存检测工具 内存问题检测就用它 - 华清远见
内存检测工具 内存问题检测就用它
内存问题在C/C++等底层语言中,是非常难解决的问题。对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题。已经有许多技术被研究出来以应对这个问题。平时写c++程序,内存泄漏问题都比较难以排查,一般都要等到程序出bug了,才能慢慢的检查出来。本篇文章就来给大家介绍一下内存检测工具,内存问题检测就用它吧。
一般内存问题检测,初学者最常用的是逐步打印log信息但其效率不是太高,也比较的繁琐,尤其是在运行成本高或重现概率低的情况下。另外,静态检查也是一类方法,有很多工具(lint, cppcheck, klockwork, splint, o, etc.)。但缺点是误报很多,不适合针对性问题。另外误报率低的一般还需要收费。最后,就是动态检查工具。下面介绍几个Linux平台下主要的运行时内存检查工具。绝大多数都是开源免费且支持x86和ARM平台的。
首先,比较常见的内存问题有下面几种: ? memory overrun:写内存越界 ? double free:同一块内存释放两次 ? use after free:内存释放后使用 ? wild free:释放内存的参数为非法值
? access uninitialized memory:访问未初始化内存
? read invalid memory:读取非法内存,本质上也属于内存越界 ? memory leak:内存泄露
? use after return:caller访问一个指针,该指针指向callee的栈内内存 ? stack overflow:栈溢出
针对上面的问题,主要有以下几种方法:
1. 为了检测内存非法使用,需要hook内存分配和操作函数。hook的方法可以是用C-preprocessor,也可以是在链接库中直接定义(因为Glibc中的malloc/free等函数都是weak symbol),或是用LD_PRELOAD。另外,通过hook strcpy(),memmove()等函数可以检测它们是否引起buffer overflow。
2. 为了检查内存的非法访问,需要对程序的内存进行bookkeeping,然后截获每次访存操作并检测是否合法。bookkeeping的方法大同小异,主要思想是用shadow memory来验证某块内存的合法性。至于instrumentation的方法各种各样。有run-time的,比如通过把程序运行在虚拟机中或是通过binary translator来运行;或是compile-time的,在编译时就在访存指令时就加入检查操作。另外也可以通过在分配内存前后加设为不可访问的guard page,这样可以利用硬件(MMU)来触发SIGSEGV,从而提高速度。
3. 为了检测栈的问题,一般在stack上设置canary,即在函数调用时在栈上写magic number或是随机值,然后在函数返回时检查是否被改写。另外可以通过mprotect()在stack的顶端设置guard page,这样栈溢出会导致SIGSEGV而不至于破坏数据。
以上方法有些强于功能,有些胜在性能,有些则十分方便易用,总之各有千秋。以下是几种常用工具在Linux x86_64平台的实验结果,注意其它平台可能结果有差异。
另外也可能由于版本过老,编译环境差异,总之各种原因造成遗漏,如有请谅解
Tool\\Problem memory overrun double free use after free wild free access uninited read invalid memory memory leak use after return stack overflow
Memory checking tools in Glibc Yes Yes Yes Yes(if use memcpy, strcpy, etc) TCMalloc(Gperftools) Yes
Valgrind Yes Yes Yes Yes Yes Yes Yes Yes Yes
Address Sanitizer(ASan) Yes Yes Yes Yes (Memory Sanitizer) Yes Yes Yes Yes Memwatch Yes Yes Yes
Dr.Memory Yes Yes Yes Yes Yes Yes Yes Yes Electric Fence Yes Yes Yes Yes Dmalloc Yes Yes Yes Yes Yes
下面简单介绍一下这些工具以及基本用法。更详细用法请参见各自manual。 Memory checking tools in Glibc
Glibc中自带了一些Heap consistency checking机制。 MALLOC_CHECK_
用mallopt()的M_CHECK_ACTION可以设置内存检测行为,设MALLOC_CHECK_环境变量效果也是一样的。从Glibc 2.3.4开始,默认为3。即打印出错信息,stack trace和memory mapping,再退出程序。设置LIBC_FATAL_STDERR_=1可以将这些信息输出到stderr。比如运行以下有double free的程序: $ MALLOC_CHECK_=3 ./bug 会打印如下信息然后退出:
*** Error in `./bug': free(): invalid pointer: 0x00000000010d6010 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7338f)[0x7f367073238f] /lib/x86_64-linux-gnu/libc.so.6(+0x81fb6)[0x7f3670740fb6] ./bug[0x400845] ./bug[0x400c36]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f36706e0ec5] ./bug[0x400729]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:01 2893041 /home/jzj/code/bug 00601000-00602000 r--p 00001000 08:01 2893041 /home/jzj/code/bug 00602000-00603000 rw-p 00002000 08:01 2893041 /home/jzj/code/bug 010d6000-010f7000 rw-p 00000000 00:00 0 [heap]
7f36704a8000-7f36704be000 r-xp 00000000 08:01 4203676 /lib/x86_64-linux-gnu/libgcc_s.so.1 7f36704be000-7f36706bd000 ---p 00016000 08:01 4203676 /lib/x86_64-linux-gnu/libgcc_s.so.1 7f36706bd000-7f36706be000 r--p 00015000 08:01 4203676 /lib/x86_64-linux-gnu/libgcc_s.so.1 7f36706be000-7f36706bf000 rw-p 00016000 08:01 4203676 /lib/x86_64-linux-gnu/libgcc_s.so.1 …
Aborted (core dumped) mcheck
mcheck是Glibc中的堆内存一致性检查机制。使用时只要加上头文件: #include
再在要开始检查的地方加上: if (mcheck(NULL) != 0) {
fprintf(stderr, \
exit(EXIT_FAILURE); } …
编译时加-lmcheck然后运行即可:
$ g++ -Wall -g problem.cpp -o bug -lmcheck _FORTIFY_SOURCE
宏_FORTIFY_SOURCE提供轻量级的buffer overflow检测。设置后会调用Glibc里带_chk后缀的函数,做一些运行时检查。主要检查各种字符串缓冲区溢出和内存操作。比如memmove, memcpy, memset, strcpy, strcat, vsprintf等。注意一些平台上编译时要加-O1或以上优化。这样就可以检查出因为那些内存操作函数导致的缓冲溢出问题:
$ g++ -Wall -g -O2 -D_FORTIFY_SOURCE=2 problem.cpp -o bug *** buffer overflow detected ***: ./bug terminated ======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7338f)[0x7f9976e1638f]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7f9976eadc9c] /lib/x86_64-linux-gnu/libc.so.6(+0x109b60)[0x7f9976eacb60] mtrace
mtrace可以用于检查malloc/free是否正确配对。用时用mtrace()和muntrace()表示开始和结束内存分配trace(如果检测到结束结尾的话可以不用muntrace())。但这是简单地记录没有free对应的malloc,可能会有一些false alarm。 #include mtrace(); // … muntrace(); 然后编译:
$ g++ -Wall -g problem.cpp -o bug 运行时先设输出的log文件:
$ export MALLOC_TRACE=output.log 用mtrace命令将输出文件变得可读: $ mtrace …… 此处隐藏:3525字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [互联网资料]2022年厦门大学机电工程系824机械设计
- [互联网资料]东南大学2022年硕士研究生拟录取名单公
- [互联网资料]能源调研报告(精选多篇)
- [互联网资料]初三英语下学期 中考英语 语法填空训练
- [互联网资料]2022内蒙古选调生行测常识备考:新事物
- [互联网资料]自驾必备!在新西兰租什么样的车自驾游
- [互联网资料]佛教素食菜谱44页未完
- [互联网资料]盈利能力分析外文翻译
- [互联网资料]2022年南昌航空大学音乐学院736马克思
- [互联网资料]优选外贸跟单实习报告总结(精品版)
- [互联网资料]银行新员工培训总结
- [互联网资料]2_year_visa_new_guidance_190316
- [互联网资料]天津市五校宝坻一中静海一中杨村一中芦
- [互联网资料]2007--2008学年第一学期高三数学宁波市
- [互联网资料]Chromatic framework for vision in ba
- [互联网资料]幼儿园大班上学期美术教案《心愿树》含
- [互联网资料]2022年华中农业大学信息学院820微型计
- [互联网资料]硬盘坏道的表现 __硬盘使用久了
- [互联网资料]江苏省2016年会计从业资格考试《会计基
- [互联网资料]公共场所卫生监督试卷全解
- 高级英语第一册所有修辞方法及例子总结
- 综合交通枢纽规划与城市发展
- 沃尔玛的企业文化案例分析
- 美国Thanksgiving Day 感恩节 介绍
- PEP六年级英语上册Unit6How do you fee
- 最齐全的中国大型商场购物中心名单
- 数据结构实验报告八—哈夫曼编译码
- 杭州市余杭区人民政府(通知)
- 七年级语文成语运用专项训练
- 微观经济学第三章 消费者行为 课后习题
- 对_钱学森之问_的思考
- Excel_三级联动_下拉菜单
- 办公用品需求计划申请表
- 对外汉语教材必须要知道的发展史
- 挑战杯大学生学术科技作品竞赛作品申报
- 举办民办教育培训机构应具备下列条件
- 太阳能路灯项目设计方案
- 2013年八年级上最新人教版新教材Unit3I
- 【历史】 6-4 《近代科学之父牛顿》 课
- 高中生物《第四章 第二节 探讨加酶洗衣




