【问题标题】:gcc with electric fence library does not take effect带电围栏库的gcc不生效
【发布时间】:2013-04-16 02:42:48
【问题描述】:

我写了一个sn-p,动态分配时出现内存问题;编译时使用-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 virable,因为当我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 包 electric-fencegcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

更新(20140801):

对于由 debian(测试分支,即 jessie)打包的 2.2.4 版本的 electric-fence,它可以工作。

【问题讨论】:

  • 不确定这是否有帮助,但对我来说它按预期工作(即生成段错误)。但是,我使用来自here 的源代码,使用Makefile 构建它,而且我必须将-lpthread 添加到链接器选项中,否则它不会链接。另外,我在 Fedora 上。
  • @jogojapan 谢谢。确实有可能是deb没有打包好。

标签: c linux gcc ubuntu debian


【解决方案1】:

上面的程序在没有与电围栏库链接的情况下编译并执行后,它可以运行而不会出现任何分段错误。

最好将它与电子围栏库链接,然后通过在 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 的上述输出中,您可以找出导致问题的源行号,如果您此时打印 i 的值,它将是 2 :)

【讨论】:

    【解决方案2】:

    你可能会遇到这种情况。

    ...它必须将分配的大小增加到 字长。此外,函数 memalign() 和 valloc() 必须 遵守关于内存对齐的明确规范 分配,而这也只能通过增加 分配的大小。因此,会出现以下情况 内存分配的末尾包含一些填充空间,并且 不会检测到对该填充空间的访问,即使它们是 超限。

    多尝试超出界限,看看溢出检测在什么时候开始。

    【讨论】:

    • 检查您从哪里获取 malloc 的定义。他们应该来自-lence。使用“nm -A | grep -i malloc”。
    • 你说的来自-lefence是什么意思?我检查了nm -A ./a.out|less,没有找到像fence 这样的子字符串。那么我是否以错误的方式使用了链接选项?
    • 我只是要求您确认您选择的 malloc() 定义来自 -lefence 库。因为只有在链接了正确的 malloc() 定义时,您正在尝试的操作才会起作用。我告诉您需要执行的命令才能找到它。执行“nm -A a.out | grep -i malloc”并将结果粘贴到此处。
    • 刚试过。对我来说,a[2] 处的 Seg 故障。当您运行代码“Electric Fence 2.2 版权所有 (C) 1987-1999 Bruce Perens ”时,您是否在输出中看到以下行?这似乎证实正在使用正确版本的 malloc()。
    • 不,没有关于Electric Fence 的字符串,sn-p 运行没有任何错误并退出。甚至退出状态码也是0
    猜你喜欢
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    相关资源
    最近更新 更多