signal 11 SIGSEGV in malloc?
c, memory-management, segmentation-fault
Solution
Any crash inside `malloc` (or `free`) is an almost sure sign of heap corruption, which can come in many forms:
- overflowing or underflowing a heap buffer
- freeing something twice
- freeing a non-heap pointer
- writing to freed block
- etc.
These bugs are very hard to catch without tool support, because the crash often comes many thousands of instructions, and possibly many calls to `malloc` or `free` later, in code that is often in a completely different part of the program and very far from where the bug is.
The good news is that tools like Valgrind or AddressSanitizer usually point you straight at the problem.
Problem
I usually love good explained questions and answers. But in this case I really can't give any more clues. The question is: why malloc() is giving me SIGSEGV? The debug bellow show the program has no time to test the returned pointer to NULL and exit. The program quits INSIDE MALLOC! I'm assuming my malloc in glibc is just fine. I have a debian/linux wheezy system, updated, in an old pentium (i386/i486 arch). To be able to track, I generated a core dump. Lets follow it: ``` iguana$gdb xadreco core-20131207-150611.dump Core was generated by `./xadreco'. Program terminated with signal 11, Segmentation fault. #0 0xb767fef5 in ?? () from /lib/i386-linux-gnu/libc.so.6 (gdb) bt #0 0xb767fef5 in ?? () from /lib/i386-linux-gnu/libc.so.6 #1 0xb76824bc in malloc () from /lib/i386-linux-gnu/libc.so.6 #2 0x080529c3 in enche_pmovi (cabeca=0xbfd40de0, pmovi=0x...) at xadreco.c:4519 #3 0x0804b93a in geramov (tabu=..., nmovi=0xbfd411f8) at xadreco.c:1473 #4 0x0804e7b7 in minimax (atual=..., deep=1, alfa=-105000, bet...) at xadreco.c:2778 #5 0x0804e9fa in minimax (atual=..., deep=0, alfa=-105000, bet...) at xadreco.c:2827 #6 0x0804de62 in compjoga (tabu=0xbfd41924) at xadreco.c:2508 #7 0x080490b5 in main (argc=1, argv=0xbfd41b24) at xadreco.c:604 (gdb) frame 2 #2 0x080529c3 in enche_pmovi (cabeca=0xbfd40de0, pmovi=0x ...) at xadreco.c:4519 4519 movimento *paux = (movimento *) malloc (sizeof (movimento)); (gdb) l 4516 4517 void enche_pmovi (movimento **cabeca, movimento **pmovi, int c0, int c1, int c2, int c3, int p, int r, int e, int f, int *nmovi) 4518 { 4519 movimento *paux = (movimento *) malloc (sizeof (movimento)); 4520 if (paux == NULL) 4521 exit(1); ``` Of course I need to look at frame 2, the last on stack related to my code. But the line 4519 gives SIGSEGV! It does not have time to test, on line 4520, if paux==NULL or not. Here it is "movimento" (abbreviated): ``` typedef struct smovimento { int lance[4]; //move in integer notation int roque; // etc. ... struct smovimento *prox;// pointer to next } movimento; ``` This program can load a LOT of memory. And I know the memory is in its limits. But I thought malloc would handle better when memory is not available. Doing a `$free -h` during execution, I can see memory down to as low as 1MB! Thats ok. The old computer only has 96MB. And 50MB is used by the OS. I don't know to where start looking. Maybe check available memory BEFORE a malloc call? But that sounds a wast of computer power, as malloc would supposedly do that. `sizeof (movimento)` is about `48 bytes`. If I test before, at least I'll have some confirmation of the bug. Any ideas, please share. Thanks.