SIGABRT in malloc.c, what just happened?
Asked Answered
C

3

8

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.

Cattle answered 1/11, 2012 at 16:19 Comment(3)
That looks like heap corruption. The actual error could be just about anywhere in your code, possibly far, far away from that block.Detach
Libc punished you for casting the return value of malloc().Carbide
just by-the-way: newalloc_size = ... + 1 to allow for terminating 0Kyphosis
A
12

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

Agma answered 1/11, 2012 at 16:21 Comment(2)
valgrind is really the way to go here.Hypopituitarism
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.Cattle
I
4

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.

Inutility answered 1/11, 2012 at 16:27 Comment(0)
R
-1

I was trying to allocate too much memory and got the evil error too (error code: EXC_I386_INVOP).

I tracked it down through the diagnosis tools (in XCode 6.1.1) in Product/Scheme/Edit Scheme... and then in Run/Diagnosis.

Rudy answered 5/2, 2015 at 17:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.