2

I have written a snippet that has memory problems when dynamically allocating; when compiled with -lefence option, it seems that there is no effect. Here is the code segment:

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;
}

And the compilation options:

gcc -g3 -Wall -std=c99 outOfBound.c -lefence

The expected result is that when a.out is executed there would be a core dump after i is assigned to 2 and a[i]=i is invoked.

So Why -lefence has no effect?

I have also increased the upper bound in the loop to 9, but there is still no core dump thatelectric-fence invoked. (Actually there is indeed a core dump by default, but this might due to the MALLOC_CHECK_ env virable since when I export MALLOC_CHECK_=0, there would be no more core dump).

UPDATE: the whole result of nm -A a.out is as below:

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

(I am using a debian package electric-fence on Ubuntu 12.04 32bit, gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3)

Update(20140801):

For electric-fence of version 2.2.4 packaged by debian(testing branch, i.e. jessie), it works.

Hongxu Chen
  • 5,240
  • 2
  • 45
  • 85
  • Not sure if this helps, but for me it works as expected (i.e. generates a segfault). However, I used the source from [here](http://linux.softpedia.com/get/Programming/Debuggers/Electric-Fence-3305.shtml), built it using the Makefile, and also I had to add `-lpthread` to the linker options, otherwise it wouldn't link. Also, I am on Fedora. – jogojapan Apr 23 '13 at 03:00
  • @jogojapan Thanks. There is indeed a possibility that the deb is not packed well. – Hongxu Chen Apr 23 '13 at 04:33

2 Answers2

0

It is possible you are running into this.

... it must increase the size of the allocation to a multiple of the word size. In addition, the functions memalign() and valloc() must honor explicit specifications on the alignment of the memory allocation, and this, as well can only be implemented by increasing the size of the allocation. Thus, there will be situations in which the end of a memory allocation contains some padding space, and accesses of that padding space will not be detected, even if they are overruns.

Try exceed the bounds a bit more, and see at what point the overrun detection kicks in.

Ziffusion
  • 8,779
  • 4
  • 29
  • 57
  • Check where you are picking up the definitions for malloc from. They should be coming from -lefence. Use "nm -A | grep -i malloc". – Ziffusion Apr 23 '13 at 03:11
  • What do you mean by say _comming from -lefence_? I checked with `nm -A ./a.out|less` and didn't find any substring like `fence`. So am I using the linkage option the wrong way? – Hongxu Chen Apr 23 '13 at 03:39
  • I am just asking you to confirm that the malloc() definition you are picking up is coming from the -lefence library. Because what you are trying will only work if the correct malloc() definition is being linked in. I am telling you the command you need to execute to find this out. Execute "nm -A a.out | grep -i malloc" and paste result here. – Ziffusion Apr 23 '13 at 03:42
  • Just tried it. Seg faults at a[2] for me. Do you get the following line in the output when you run the code "Electric Fence 2.2 Copyright (C) 1987-1999 Bruce Perens "? That seems to confirm that the right version of malloc() is being used. – Ziffusion Apr 23 '13 at 04:05
  • No, no string about `Electric Fence`, the snippet run without any errors and exit. Even the exit status code is `0`. – Hongxu Chen Apr 23 '13 at 04:11
  • So maybe the debian package is not packed well? – Hongxu Chen Apr 23 '13 at 04:12
  • Not sure. All I know is that I get that line printed out when I run the program. It's absence is kind of suspicious. – Ziffusion Apr 23 '13 at 04:27
0

Once you compile and execute above program without linking it with electric fence library, it may run without any segmentation fault.

So better to link it with electric fence library and then Run it by loading it in gdb giving the following command

$ 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;

So from above output of gdb you can make out the source line number which is causing the problem if you print the value of i at this instant it will be 2 :)

Arif Butt
  • 1
  • 1