2

Can anyone tell me why my program is aborting? I am compiling it with efence which aborts on malloc(0), as the GDB backtrace suggests, the regcomp is doing a malloc(0)

1218 void extractTime(int extractStartTime)
1219 {
1220         char  * charPtr, * numberFormatErr;
1221         regex_t re;
1222 
1223         ( extractStartTime == 1 ) ? ( charPtr = getenv("EF_ERRTRACK_START") ) :
1224                 ( charPtr = getenv("EF_ERRTRACK_END") );
1225 
1226         if ( charPtr == NULL )
1227                 return;
1228 
1229         double envVal = strtod(charPtr, &numberFormatErr);
1230 
1231         if ( (numberFormatErr == charPtr) || (*numberFormatErr != '\0') ) {
1232                 ( extractStartTime == 1 ) ? EF_Print("eFence exited: EF_ERRTRACK_START is not a number\n") :
1233                         EF_Print("eFence exited: EF_ERRTRACK_END is not a number\n");
1234                 exit(1);
1235         }
1236         else if ( envVal < 0 ) {
1237                 ( extractStartTime == 1 ) ? EF_Print("eFence exited: EF_ERRTRACK_START a negative number\n") :
1238                         EF_Print("eFence exited: EF_ERRTRACK_END is a negative number\n");
1239                 exit(1);
1240         }
1241 
1242         /* If we are here then it is a valid number, now lets check if it is exponential or not */
1243 
1244         regcomp(&re, "^([0-9]+[.]?[0-9]*|[0-9]*[.][0-9]+)[eE][+-]?[0-9]+$", REG_EXTENDED);
1245 
1246         if ( regexec(&re, charPtr, 0, 0, 0) == 0 )
1247         {
1248                 /* It is an exponential number, then already parsed by strtod earlier*/
1249                 sprintf(charPtr, "%lf", envVal);
1250         }
1251 

Here is the GDB backtrace:

(gdb) r
Starting program: /tmp/efence/ikatrack1_dev 
[Thread debugging using libthread_db enabled]

Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.

ElectricFence Aborting: Allocating 0 bytes, probably a bug.

[New Thread 0x4001e350 (LWP 1528)]

Program received signal SIGILL, Illegal instruction.
[Switching to Thread 0x4001e350 (LWP 1528)]

0x4008734c in kill () from /devel/lib/libc.so.6

(gdb) bt
#0  0x4008734c in kill () from /devel/lib/libc.so.6
#1  0x0000b86c in EF_Abort (pattern=0x1000 <Address 0x1000 out of bounds>)
at print.c:137
#2  0x00009564 in memalign (alignment=4, userSize=0) at efence.c:533
#3  0x0000a5bc in malloc (size=0) at efence.c:1027
#4  0x400fe5bc in re_node_set_alloc (set=0x4025cfd8, size=0)
at regex_internal.c:959
#5  0x400ff2ac in register_state (dfa=0x25, newstate=0x4025cfc8, hash=86528)
at regex_internal.c:1550
#6  0x40102d64 in re_acquire_state_context (err=0xbebd7b88, dfa=0x40196f74, 
nodes=0xbebd7b74, context=0) at regex_internal.c:1706
#7  0x4010c060 in re_compile_internal (preg=0xbebd7bf0, 
pattern=0xcb74 "^([0-9]+[.]?[0-9]*|[0-9]*[.][0-9]+)[eE][+-]?[0-9]+$", 
length=<value optimized out>, syntax=242428) at regcomp.c:989
#8  0x4010d5f8 in __regcomp (preg=0xbebd7bf0, 
pattern=0xcb74 "^([0-9]+[.]?[0-9]*|[0-9]*[.][0-9]+)[eE][+-]?[0-9]+$", 
cflags=1) at regcomp.c:480
#9  0x0000ae1c in extractTime (extractStartTime=1) at efence.c:1244
#10 0x0000aa1c in efence_ctor () at efence.c:1144
#11 0x0000c528 in __libc_csu_init (argc=1, argv=0xbebd7de4, envp=0xbebd7dec)
at elf-init.c:83
#12 0x40070fe8 in __libc_start_main (main=0x8c54 <main>, argc=1, 
ubp_av=0xbebd7de4, init=0xc4d0 <__libc_csu_init>, 
---Type <return> to continue, or q <return> to quit---
fini=0xc4c0 <__libc_csu_fini>, rtld_fini=0x4000ea50 <_dl_fini>, 
stack_end=0xbebd7de4) at libc-start.c:179
#13 0x00008bcc in _start ()

From GDB backtrace, i can see that the problem lies in frame #4:

#4 0x400fe5bc in re_node_set_alloc (set=0x4025cfd8, size=0) where it is doing a malloc(0) but how come and why is it doing?

Shawn Chin
  • 84,080
  • 19
  • 162
  • 191
RajSanpui
  • 11,556
  • 32
  • 79
  • 146

1 Answers1

4

Change your electric fence settings (EF_ALLOW_MALLOC_0) to ignore this.

malloc(0) is not illegal. Read the error message again, it says "probably a bug". It aborts so that you will investigate. Once you've determined that it isn't actually a bug, skip it and keep running.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • I can change the settings, but i wish to understand as to why it is doing a malloc(0). – RajSanpui Sep 21 '11 at 15:20
  • 1
    @kingsmasher1: According to the backtrace, you need to look at `re_node_set_alloc`, near line 959 of regex_internal.c, and maybe also `register_state`, around line 1550. Not sure where the code you did provide comes from, but it doesn't seem to be related. – Ben Voigt Sep 21 '11 at 15:25
  • There are legit reasons to do a malloc(0). See [question on malloc(0)](http://stackoverflow.com/questions/2022335/whats-the-point-in-malloc0). – David Nehme Sep 21 '11 at 15:27
  • @BenVoigt: I have seen it, it calls `884 re_node_set_alloc (set, size)` with a size of 0, don't know why, and it seems at some ocassions it calls and at others it doesn't. – RajSanpui Sep 21 '11 at 15:30
  • @BenVoigt: The file is regex_internal.c – RajSanpui Sep 21 '11 at 15:30
  • @kingsmasher1: The reason for doing `malloc(0)`, is probably to eliminate a special case when reallocating. Do you want to (a) "alloc the new, copy the data, free the old" or (b) "check if there is an allocation, if yes, alloc new, copy the data, free the old, otherwise alloc new"? – Ben Voigt Sep 21 '11 at 17:15
  • @David: I beg to differ. Almost any code calling `malloc(0)` is going to be non-portable, i.e. it's depending on `malloc(0)` returning a unique pointer. If not, `ptr=NULL;` would be just as good. Also, either way works with `realloc`. `realloc(NULL,size)` is equivalent to `malloc(size)`. – R.. GitHub STOP HELPING ICE Sep 21 '11 at 17:23
  • @R: That's true, and `free(NULL)` is also legal, so `NULL` can be substituted for `malloc(0)`. – Ben Voigt Sep 21 '11 at 17:50