malloc() Causes a Segfault at _malloc_unlocked
I ran into a strange bug this week in the code to the C project I’ve been working on. Seemingly randomly, I was encountering a segfault in a call to malloc() while allocating memory for a new struct. The problem had me completely baffled, and web searches turned up no useful information, since most people encounter this problem when dealing with multithreading, which I was not.
I fired up gdb and ran a backtrace from the fault:
#1 0×08055e4a in _malloc_unlocked () at src/file.c:263
…
This didn’t help much, but my guess was that I had corrupted the heap somehow somewhere in the code before the allocation. After a bit of careful code browsing, I found the culprit:
memcpy(ptr, &obj->data.data[19], obj->data.length); ptr += obj->data.length;
A simple memory bounds error. My intention here was to copy all of the data from position 19 through the end of the data.data buffer into the buffer pointed at by ptr. But I had left off the 19-byte adjustment from the size argument to memcpy and the subsequent pointer incrementation. Correcting the bounds fixed the problem and the program went on its merry way:
memcpy(ptr, &obj->data.data[19], obj->data.length - 19); ptr += obj->data.length - 19;
The problem with these kinds of errors is that they often don’t reveal themselves until later on in the execution of the program, in an area of code that has nothing to do with the actual problem. The code above is used in a loop and executes successfully for a while, until malloc() tried to deal with an area of memory that was accidentally written over by memcpy(). At that point, bad things happen.
Be careful with memcpy().
No comments yet.