SIGABRT in malloc.c, what just happened?

15,649

Solution 1

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

Solution 2

From your code, the most likely answer is that you are using null-terminated strings and not allowing space for the terminating null in the buffer you allocate.

Try this instead of the line you have:

size_t newalloc_size = sizeof(char) * (strlen(pref) + strlen(str) + 1);

The terminating null is being written outside of your malloc'd buffer, where it is probably overwriting part of malloc's internal bookkeeping. This will cause heap corruption, which will sooner or later cause malloc to break.

Share:
15,649
musicmatze
Author by

musicmatze

Updated on July 31, 2022

Comments

  • musicmatze
    musicmatze almost 2 years

    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.

  • Jonas Schäfer
    Jonas Schäfer over 11 years
    valgrind is really the way to go here.
  • musicmatze
    musicmatze over 11 years
    Thank you. The missing zero-char was not added in the code up there, but is already in my code. Just copied before adding the +1! Anyway thanks! I will have a look at valgrind and asprintf.