SIGABRT in malloc.c, what just happened?

musicmatze picture musicmatze · Nov 1, 2012 · Viewed 13.6k times · Source

I wrote this innocent piece of code, and results in such an evil error:

static char * prefixed( char * pref, char *str ) {
    size_t newalloc_size = sizeof(char) * (strlen(pref) + strlen(str));
    char * result = (char*) malloc( newalloc_size );
    [...]

output from debug (cgdb):

Breakpoint 1, prefixed (pref=0x401345 "Env: ", str=0x4012b5 "Home") at ./src/backend/os/env.c:77
(gdb) s
(gdb) p newalloc_size 
$1 = 9
(gdb) s
envtest: malloc.c:2368: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >=
(unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)'
failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7a68fd5 in raise () from /usr/lib/libc.so.6
(gdb)  

I checked the passed arguments, too. They where just as they are supposed to be:

Breakpoint 1, prefixed (pref=0x401345 "Env: ", str=0x4012b5 "Home") at ./src/backend/os/env.c:77
(gdb) p pref
$2 = 0x401345 "Env: "
(gdb) p strlen(pref)
$3 = 5
(gdb) p str
$4 = 0x4012b5 "Home"
(gdb) p strlen(str)
$5 = 4
(gdb) 

can anybody imagine, what goes wrong here? I know there are functions to cat two strings together, but I want to do it on my own!

kind regards.

Answer

Basile Starynkevitch picture Basile Starynkevitch · Nov 1, 2012

This smells like a memory leak or buffer overflow (or some other heap corruption) elsewhere in your program. I suggest to recompile it using the -Wall -g options to gcc, to improve your program till no warnings are given by the compiler, and to use valgrind and gdb to debug the issue.

Actually, your statement

  result = (char*) malloc( newalloc_size );

is wrong (lack of space for the terminating null byte). You probably want

  result = malloc(newalloc_size+1);

but you should learn to use asprintf