[MarkDown]还是使用tcmalloc检查内存错误
2016-01-05 12:31
405 查看
Google的tcmalloc可以做内存越界检查,也就是查野指针。
野指针是应用程序最难查的崩溃的问题。google真的很强大,赞!
基本原理就是在分配时分配到页的底部,这样越界时就会报错了。也就是PAGE_FENCE,这个选项是可以通过环境变量设置的,代码在:
可以直接将代码改掉:
或者设置环境变量:
编译出静态库(若需要使用so库需要安装):
编译选项加上:
使用gdb调试,在越界的地方就会停下来。
下面的代码有越界,但是执行是没有问题的:
执行是没有问题,一般linux会多分配,而且越界的地方并非只读:
加上tcmalloc的debug库之后,就可以看到越界的地方了:
真的很牛逼:
靠人来找这种问题,找死了都找不到。
野指针是应用程序最难查的崩溃的问题。google真的很强大,赞!
基本原理就是在分配时分配到页的底部,这样越界时就会报错了。也就是PAGE_FENCE,这个选项是可以通过环境变量设置的,代码在:
src/debugallocation.cc: 101
DEFINE_bool(malloc_page_fence, EnvToBool("TCMALLOC_PAGE_FENCE", false), "Enables putting of memory allocations at page boundaries " "with a guard page following the allocation (to catch buffer " "overruns right when they happen).");
可以直接将代码改掉:
将 EnvToBool("TCMALLOC_PAGE_FENCE", false) 改成了 EnvToBool("TCMALLOC_PAGE_FENCE", true) 脚本: sed -i "s/EnvToBool(\"TCMALLOC_PAGE_FENCE\", false)/EnvToBool(\"TCMALLOC_PAGE_FENCE\", true)/g" src/debugallocation.cc
或者设置环境变量:
env TCMALLOC_PAGE_FENCE=1 ./your_application
编译出静态库(若需要使用so库需要安装):
cd gperftools-2.0 && ./configure --enable-frame-pointers && make
编译选项加上:
LibTcMalloc="-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free ${SMT_OBJS}/gperftools-2.0/.libs/libtcmalloc_debug.a"
使用gdb调试,在越界的地方就会停下来。
下面的代码有越界,但是执行是没有问题的:
/** g++ memory.error.notcmalloc.cpp -g -O0 -o memory.error.notcmalloc */ #include <unistd.h> #include <string.h> #include <stdio.h> void foo(char* p){ memcpy(p, "01234567890abcdef", 16); } int main(int argc, char** argv){ char* p = new char[10]; foo(p); printf("p=%s\n", p); return 0; }
执行是没有问题,一般linux会多分配,而且越界的地方并非只读:
[winlin@dev6 code]$ ./memory.error.notcmalloc p=01234567890
加上tcmalloc的debug库之后,就可以看到越界的地方了:
/** (unzip -q ../../3rdparty/gperftools-2.1.zip && cd gperftools-2.1 && ./configure --enable-frame-pointers && make) g++ memory.error.tcmalloc.cpp -g -O0 \ -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc \ -fno-builtin-free ./gperftools-2.1/.libs/libtcmalloc_debug.a \ -o memory.error.tcmalloc -lpthread */ #include <unistd.h> #include <string.h> #include <stdio.h> void foo(char* p){ memcpy(p, "01234567890abcdef", 16); } int main(int argc, char** argv){ char* p = new char[10]; foo(p); printf("p=%s\n", p); return 0; }
[winlin@dev6 code]$ env TCMALLOC_PAGE_FENCE=1 gdb memory.error.tcmalloc (gdb) r Program received signal SIGSEGV, Segmentation fault. (gdb) bt #0 memcpy () at ../sysdeps/x86_64/memcpy.S:120 #1 0x0000000000405436 in foo (p=0x7ffff7ff9ff6 "01234567\253\253") at memory.error.tcmalloc.cpp:14 #2 0x0000000000405461 in main (argc=1, argv=0x7fffffffe388) at memory.error.tcmalloc.cpp:18
真的很牛逼:
(gdb) f 1 #1 0x0000000000405436 in foo (p=0x7ffff7ff9ff6 "01234567\253\253") at memory.error.tcmalloc.cpp:14 14 memcpy(p, "01234567890abcdef", 16); (gdb) l 9 #include <unistd.h> 10 #include <string.h> 11 #include <stdio.h> 12 13 void foo(char* p){ 14 memcpy(p, "01234567890abcdef", 16); 15 } 16 int main(int argc, char** argv){ 17 char* p = new char[10]; 18 foo(p); (gdb)
靠人来找这种问题,找死了都找不到。
相关文章推荐
- iOS开发之计算文件大小
- 第1章线性表
- php读mysql中文乱码问题解决方法
- 25 个 Java 机器学习工具和库
- 会员卡管理系统技术解析(十八)Timer定时监听
- 基于Android 下载文件时,更新UI简单帮助类
- H5实现拍照并上传
- ListView下拉刷新
- 微服务:分解应用以实现可部署性和可扩展性
- Android平台实现与Apache Tomcat服务器数据交互(MySql数据库)
- 【基于Jsoup】无节操图片段子APP
- 也谈阻塞、非阻塞、同步、异步
- 试题识别与生成
- ORB特征检测与匹配
- EditText中imeOptions属性使用及设置无效解决
- Windows图形编程笔记
- GTA V - Graphics Study
- MAC EI Capitan上更新系统自带SVN版本(关闭SIP方能sudo rm)
- suid和sgid的个人理解
- 2015年是虚假繁荣,认清自己,切勿盲目乐观