源码下载地址

注:官方地址下载不了,可能不再维护了,此是一个老项目

efence中相关环境变量控制:

302     /*
303 * See if the user wants to allow malloc(0).
304 */
305 if ( EF_ALLOW_MALLOC_0 == -1 ) {
306 if ( (string = getenv("EF_ALLOW_MALLOC_0")) != 0 )
307 EF_ALLOW_MALLOC_0 = (atoi(string) != 0);
308 else
309 EF_ALLOW_MALLOC_0 = 0;
310 }

gdb的局限性:

有的时候,gbd 给出的 crash 上下文其实并不是真正发生问题的第一现场,在多线程程序设计中,这种情景会让 bug 的追查陷入误区。

内存调试工具Electric Fence

使用 electric-fence 调试内存越界

Electric-fence 介绍

electric-fence 原理如下:

  • 重写malloc、free、realloc、calloc、valloc 函数,对于C++ 应使用 extern “C”; C 使用 extern 来导出符号;以确保应用程序使用  electric-fence 的malloc等函数
  • 系 统调用malloc会多分配一个page(注意是 虚存)  然后根据是否EF_PROTECT_BELOW 设置来决定返回新分配内存区的高地址(或低地址)给user;同时,调用 mprotect((caddr_t)address, size, PROT_NONE) 来设置多分配的page页为不可访问;这样一旦程序越界便会进入不可访问区间,因此coredump。同时,EF_ALIGNMENT 也会影响到该处。
  • electric-fence  内存管理的实现基本思路为:a. 每次向操作系统申请MEMORY_CREATION_SIZE(当前为1M)字节内存,使用mmap完成; b. 存在一片内存区 用于存放 所有 slot 信息, slot 用于管理被分配的内存信息,如返回给用户的地址以及其内部实际地址、size等; c. 分配时从当前slot 中查找是否有能满足分配需求的内存区,这里注意的是每次实际分配的内存区大小比用户请求的至少要大 一个page,大致公式为:  real_size = user_size + (alignment – (user_size  % alignment )) + page_size;   若存在则拆分内存区,修改相关slot信息 d. free  内存时不会将内存交给操作系统,而是设置free或者标志PROTECTED,PROTECTED意味着该片内存不会被再次分配,由 EF_PROTECT_FREE 控制。 若设置了EF_FREE_WIPES,还会用0xbd填充用户free的区域。

electric-fence 也有如下的缺点:

  1. 每一次分配都是利用一个 semaphore 同步,没有 thread local 的分配
  2. malloc 和 free 在 slot 都是线性查找,这也造成了整体性能的落后
  3. 内存消耗大,这个是显然的,特别对于频繁的小内存分配

2,3 点都是造成整个 lib 性能较低的原因。简单说,这还是一个比较简陋的工具,如果能借鉴 tcmalloc, jemalloc 等设计可能会更好一点。

注意:我在hi3520下使用时有如下错误:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x40ce94c0 (LWP 779)]
memalign (alignment=4, userSize=56) at efence.c:498
498 && slot->internalSize >= internalSize ) {
(gdb) bt
#0 memalign (alignment=4, userSize=56) at efence.c:498
#1 0x0074a2d4 in malloc (size=55) at efence.c:821
#2 0x4038cc60 in operator new(unsigned int) () from /lib/libstdc++.so.6
#3 0x40369e68 in std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) () from /lib/libstdc++.so.6
#4 0x4036a818 in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned int) () from /lib/libstdc++.so.6
#5 0x4036b39c in std::string::reserve(unsigned int) ()
from /lib/libstdc++.so.6
#6 0x4036b5e8 in std::string::append(char const*, unsigned int) ()
from /lib/libstdc++.so.6
#7 0x00135c24 in Thread::trace (this=0x403ebfd8, name=0x783070 "loop",
file=0x783075 "util/trace/tracer.cpp", line=505, func=0x782fa0 "run",
time=1478188527) at util/trace/tracer.cpp:88
#8 0x00135de0 in Tracer::trace (this=0x403b8fac, name=0x783070 "loop",
file=0x783075 "util/trace/tracer.cpp", line=505, func=0x782fa0 "run",
time=1478188527) at util/trace/tracer.cpp:725
#9 0x0013456c in traceOut (name=0x783070 "loop",
file=0x783075 "util/trace/tracer.cpp", line=505, func=0x782fa0 "run")
at util/trace/if_trace.cpp:110
#10 0x0013559c in Logger::run (arg=<optimized out>)
at util/trace/tracer.cpp:505
#11 0x401e2f9c in start_thread () from /lib/libpthread.so.0
#12 0x40245b58 in clone () from /lib/libc.so.0
#13 0x40245b58 in clone () from /lib/libc.so.0
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) q 496     for ( slot = allocationList, count = slotCount ; count > 0; count-- ) {
497         if ( slot->mode == FREE
498          && slot->internalSize >= internalSize ) {
499             if ( !fullSlot
500              ||slot->internalSize < fullSlot->internalSize){
501                 fullSlot = slot;
502                 if ( slot->internalSize == internalSize                                                                                                                                                  
503                  && emptySlots[0] )
504                     break;  /* All done, */
505             }
506         }
507         else if ( slot->mode == NOT_IN_USE ) {
508             if ( !emptySlots[0] )
509                 emptySlots[0] = slot;
510             else if ( !emptySlots[1] )
511                 emptySlots[1] = slot;
512             else if ( fullSlot
513              && fullSlot->internalSize == internalSize )
514                 break;  /* All done. */
515         }
516         slot++;
517     } extern C_LINKAGE void *
malloc(size_t size)
{
        void  *allocation;   
 
        if ( allocationList == 0 ) {
                pthread_mutex_init(&mutex, NULL);
                initialize();   /* This sets EF_ALIGNMENT */
        }       
        lock();
        allocation=memalign(EF_ALIGNMENT, size);         unlock();
                                                                                                                                                                                                             
▸   return allocation;
}

1、查看对应的错误点,发现相关变量都是正常的

2、frame 1到frame 0中的size莫名奇妙的发生了变化

3、基于这些原因,最终没有应用起来,不知道为什么?是否程序真的有越界行为导致

问题:

若出现segment fault错误,对应的pc指针是否为导致该错误的直接原因,还是这个pc指针是随机的?

答:pc仅能作为参考,segment fault应是通过signal机制实现的,具体需要进一步研究

内存调试工具Electric Fence的更多相关文章

  1. USACO 3.4 Electric Fence

    Electric FenceDon Piele In this problem, `lattice points' in the plane are points with integer coord ...

  2. Valgrind,内存调试工具

    Valgrind是一款用于内存调试.内存泄漏检测以及性能分析的软件开发工具 官网:http://valgrind.org/ 用户开发手册地址:http://valgrind.org/docs/manu ...

  3. valgrind 内存调试工具

    一.valgrind 是运行在linux系统下的内存调试工具,支持很多对象:memcheck.addrcheck.cachegrind.Massif.helgrind.Callgrind等.使用val ...

  4. JVM常用启动参数+常用内存调试工具

    一.JVM常用启动参数 -Xms:设置堆的最小值. -Xmx:设置堆的最大值. -Xmn:设置新生代的大小. -Xss:设置每个线程的栈大小. -XX:NewSize:设置新生代的初始值. -XX:M ...

  5. 【TOJ 5103】Electric Fence(皮克定理)

    描述 In this problem, `lattice points' in the plane are points with integer coordinates. In order to c ...

  6. Linux内存调试工具初探-MEMWATCH

    C 语言作为 Linux 系统上标准的编程语言给予了我们对动态内存分配很大的控制权.这种自由可能会导致严重的内存管理问题,可能导致程序崩溃或随时间的推移导致性能降级. 内存泄漏(即 malloc()  ...

  7. 初试valgrind内存调试工具

    虽然GDB调试工具功能强大,但对于平时做题调试的使用并不方便,这里尝试学习使用比较简单的valgrind工具 Valgrind是一个提供程序调试及性能分析的工具集.其包含的工具主要有Memcheck, ...

  8. Linux内存调试工具初探-MEMWATCH(转)

    C 语言作为 Linux 系统上标准的编程语言给予了我们对动态内存分配很大的控制权.这种自由可能会导致严重的内存管理问题,可能导致程序崩溃或随时间的推移导致性能降级. 内存泄漏(即 malloc()  ...

  9. linux下内存调试工具——valgrind

    1.valgrind之memcheck  最常用的工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete的调用都会被捕获.所以,它 ...

随机推荐

  1. win激活查询及修改

    slmgr.vbs -dlv 命令可以查询到Win8.1的激活信息,包括:激活ID.安装ID.激活截止日期!   slmgr.vbs -dli 命令可以查询到操作系统版本.部分产品密钥.许可证状态! ...

  2. 火车站(codevs 2287)

    题目描述 Description 火车从始发站(称为第1站)开出,在始发站上车的人数为a,然后到达第2站,在第2站有人上.下车,但上.下车的人数相同,因此在第2站开出时(即在到达第3站之前)车上的人数 ...

  3. Android常用查询网站

    一.老罗的Android之旅爱生活,爱Android http://blog.csdn.net/luoshengyang 二.Android中文API http://www.android-doc.c ...

  4. ***阿里云linux 下怎么配置虚拟主机

    最近有个问题,本人在阿里云买了linux服务器,用wordpress做了一个博客网站www.bravetiger.cn,现在想加一个电商系统进去,假设二级域名为:shop.bravetiger.cn, ...

  5. 项目如何脱离TFS 2010的管理

    在VS 里,文件->源代码管理->更改源代码管理->取消绑定.

  6. 翻阅《数据结构与算法javascript描述》--数组篇

    导读: 这篇文章比较长,介绍了数组常见的操作方法以及一些注意事项,最后还有几道经典的练习题(面试题). 数组的定义: JavaScript 中的数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性 ...

  7. Linux常用命令_(文件权限)

    Linux权限管理: 二.权限管理1.3种基本权限在Linux中,将使用系统资源的人员分为4类:超级用户.文件或目录的属主.属主的同组人和其他人员.超级用户拥有对Linux系统一切操作权限,对 于其他 ...

  8. vi-11

    vi编辑器linux命令大全 作者:xiaoru  出处:本站整理  发布时间:2013-04-29 13:20:23 -     vi就是linux命令行下的最著名的编辑器之一,Vim常被称作“程序 ...

  9. WMS移动仓库管理系统 PDA仓库管理系统

    电子仓库管理系统,简称WMS系统,英文名Warehouse Management System,是应用条码和RFID自动识别技术的现代化仓库管理系统,能有效地对仓库流程和空间进行管理,实现批次管理.快 ...

  10. POJ 1155 (树形DP+背包+优化)

    题目链接: http://poj.org/problem?id=1155 题目大意:电视台转播节目.对于每个根,其子结点可能是用户,也可能是中转站.但是用户肯定是叶子结点.传到中转站或是用户都要花钱, ...