我写了一个在dynamic分配时有内存问题的代码片段; 当用-lefence
选项编译时,似乎没有效果。 这里是代码段:
int main(int argc, char *argv[]) { int *a = (int *)malloc(2*sizeof(int)); for(int i = 0; i <=2; ++i){ a[i] = i; printf ("%d\n",a[i]); } free(a); return 0; }
和编译选项:
gcc -g3 -Wall -std=c99 outOfBound.c -lefence
预期的结果是,当执行a.out
时, i
将分配给2并且调用a[i]=i
之后会有一个核心转储。
那么为什么 – -lefence
不起作用?
我也把循环上限增加到了9,但是还没有electric-fence
调用的核心转储。 (实际上默认是有一个核心转储,但是这可能是由于MALLOC_CHECK_
env可取的,因为当我export MALLOC_CHECK_=0
,将不会有更多的核心转储)。
更新 : nm -A a.out
的全部结果如下:
a.out:08049f28 d _DYNAMIC a.out:08049ff4 d _GLOBAL_OFFSET_TABLE_ a.out:0804864c R _IO_stdin_used a.out: w _Jv_RegisterClasses a.out:08049f18 d __CTOR_END__ a.out:08049f14 d __CTOR_LIST__ a.out:08049f20 d __DTOR_END__ a.out:08049f1c d __DTOR_LIST__ a.out:08048718 r __FRAME_END__ a.out:08049f24 d __JCR_END__ a.out:08049f24 d __JCR_LIST__ a.out:0804a01c A __bss_start a.out:0804a014 D __data_start a.out:08048600 t __do_global_ctors_aux a.out:08048480 t __do_global_dtors_aux a.out:0804a018 d __dso_handle a.out: w __gmon_start__ a.out:080485f2 t __i686.get_pc_thunk.bx a.out:00000000 a __init_array_end a.out:00000000 a __init_array_start a.out:080485f0 T __libc_csu_fini a.out:08048580 T __libc_csu_init a.out: U __libc_start_main a.out:0804a01c A _edata a.out:0804a024 A _end a.out:0804862c T _fini a.out:08048648 R _fp_hw a.out:080483b4 T _init a.out:08048450 T _start a.out:0804a01c b completed.6159 a.out:0804a014 W data_start a.out:0804a020 b dtor_idx.6161 a.out:080484e0 t frame_dummy a.out: U free a.out:08048504 T main a.out: U malloc a.out: U printf
(我在Ubuntu 12.04 32bit上使用debian软件包, gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
)
对于由debian(testing分支,即jessie)打包的2.2.4
版本的electric-fence
,它工作正常。
你可能会遇到这个问题。
…它必须将分配的大小增加到字长的倍数。 另外,函数memalign()和valloc()必须符合内存分配对齐的明确规范,而且这也只能通过增加分配的大小来实现。 因此,将会出现内存分配的结尾包含一些填充空间的情况,即使超出了该填充空间的访问也不会被检测到。
尝试超越界限,并看到超时检测在什么时候开始。
一旦你编译和执行上面的程序,而没有与电子围栏库链接,它可能运行没有任何分段错误。
所以最好把它与电子围栏库连接起来,然后通过在gdb中加载运行它,给出以下命令
$ gdb a.out .... (gdb)run Starting program: /home/arif/sysprog-2017/processmgmt/nonlocalgoto/a.out [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Electric Fence 2.2 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com> 0 1 Program received signal SIGSEGV, Segmentation fault. 0x000055555555484d in main (argc=1, argv=0x7fffffffe228) at temp.c:8 8 a[i] = i;
所以从上面的gdb输出你可以找出导致问题的源代码行数,如果你在这个时候打印我的值,它将是2 🙂