源码下载地址

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

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 == FREE498          && slot->internalSize >= internalSize ) {499             if ( !fullSlot500              ||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 ( fullSlot513              && 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机制实现的,具体需要进一步研究

转载于:https://www.cnblogs.com/jingzhishen/p/6025702.html

内存调试工具Electric Fence相关推荐

  1. 多核心CPU并行编程中为什么要使用内存屏障 memory barriers / 内存栅栏 memory fence

    文章目录 前言 现代Intel® CPU架构 指令集 CISC, RICS ... Intel各个时期的CPU微架构(microarchitecture)特点 P6 Family Microarchi ...

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

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

  3. C/C++之内存调试工具GDB与Valgrind

    0 背景 写 C++的同学想必有太多和内存打交道的血泪经验了,常常被 C++的内存问题搅的焦头烂额.(写 core 的经验了)有很多同学一见到 core 就两眼一抹黑,不知所措了.笔者 入" ...

  4. usaco Electric Fence

    一开始枚举点,交一次发现少判断一种情况最后实在没有耐心了去百度了原来还有这么个东西 皮克定理  皮克定理说明了其面积S和内部格点数目a.边上格点数目b的关系:S = a + b/2 - 1. 根据三角 ...

  5. 3.4.3 Electric Fence电网 USACO(毕克定理) USACO

    题目描述 在这道题目中,"格点"指的是整点(整数坐标点). 为了管理他的牛们,FJ用几条通着电的铁丝建造了一个三角形的围栏,从原点(0,0)到整点(n,m),再到x正半轴上的点(p ...

  6. usaco 3.4 Electric Fence 皮克定理

    一条直线((0,0),(n,m))上的格点数(包含端点)等于n与m的最大公约数+1 皮克定理: 面积A和内部格点数目i.边上格点数目b的关系:A = i + b/2 - 1 #include < ...

  7. 掌握 Linux 调试技术【转】

    转自:https://www.ibm.com/developerworks/cn/linux/sdk/l-debug/index.html 您可以用各种方法来监控运行着的用户空间程序:可以为其运行调试 ...

  8. 掌握 Linux 调试技术

    在 Linux 上找出并解决程序错误的主要方法 Steve Best (sbest@us.ibm.com)JFS 核心小组成员,IBM Steve Best 目前在做 Linux 项目的日志纪录文件系 ...

  9. linux c 内存泄露 检查工具

    Linux下编写C或者C++程序,有很多工具,但是主要编译器仍然是gcc和g++.最近用到STL中的List编程,为了检测写的代码是否会发现内存泄漏,了解了一下相关的知识. 所有使用动态内存分配(dy ...

  10. 内存泄漏检测工具(转载)

    内存泄漏检测工具2007年08月08日 1.     ccmalloc-Linux和Solaris下对C和C++程序的简单的使用内存泄漏和malloc调试库. 2.     Dmalloc-Debug ...

最新文章

  1. Ubuntu 修改本地磁盘名称
  2. RHEL7 kvm虚拟机桥接网络配置
  3. H5存储------localStorage和sessionStorage
  4. 逻辑回归还能这样解?关于Kernel Logistic Regression的详细解释
  5. 用JS解决多行溢出文本的省略问题
  6. 2019 微软Build大会预告:值得开发者期待的是哪些?
  7. 认识定制:JSON绑定概述系列
  8. golang json判断类型
  9. spring mvc对异步请求的处理
  10. c++ 快速排序_C语言必学的12个排序算法:归并排序(第8篇)
  11. springboot启动mybatis
  12. cenyos7安装 yum不可用_小区阳台隐形网横管不可用扁管,要改再去安装,还有问题...
  13. wincc控件包下载_Simatic HMI WinCC V7.4 SP1 组态软件下载
  14. [转]计算机经典书籍
  15. pytorch中tensor转numpy
  16. Python算法教程第三章知识点:求和式、递归式、侏儒排序法和并归排序法
  17. Newline required at end of file but not found
  18. 这几本值得你一看再看的程序员素养必备好书
  19. Parallels Desktop克隆出来的虚拟机拥有相同的SSH KEY的修改方法
  20. 使用B站API:http://api.bilibili.com/x/space/upstat?mid=2026561407获取播放量、点赞量的返回报文中data数据缺失问题排查(已解决)

热门文章

  1. 大白话vue——slot的作用与使用
  2. controller报错MissingServletRequestParameterException: Required xxx parameter ‘xxx’ is not present
  3. 解决兼容低版本浏览的痛:IE中的CSS3不完全兼容方案
  4. GDAL建立GeoTIFF金字塔文件
  5. ⭐图例结合超硬核讲解shiro⭐
  6. Python 函数参数传递的困惑
  7. 每天一道剑指offer-从上往下打印二叉树
  8. python使用redis实现session_redis与python交互session的redis存储配置
  9. mysql安装 linux rpm_linux MySQL5.7 rpm安装
  10. 主成分分析法怎么提取图片中的字_视频图像的MATLAB处理(2)两种主成分分析方法...