2013-12-07 2 views
3

Обычно я люблю хорошие объясненные вопросы и ответы. Но в этом случае я действительно не могу дать больше подсказок.сигнал 11 SIGSEGV в malloc?

Вопрос: почему malloc() дает мне SIGSEGV? Отладка ниже показывает, что у программы нет времени для проверки возвращаемого указателя на NULL и выхода. Программа выходит из INSIDE MALLOC!

Я предполагаю, что мой malloc в glibc в порядке. У меня есть система debian/linux wheezy, обновленная в старой версии pentium (i386/i486).

Чтобы иметь возможность отслеживать, я создал свалку ядра. Давайте следовать за ним:

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); 

Конечно, мне нужно посмотреть на раме 2, последнее из стека, связанный с моим кодом. Но линия 4519 дает SIGSEGV! У него нет времени для тестирования на линии 4520, если paux == NULL или нет.

Здесь "Movimento" (сокращенно):

typedef struct smovimento 
{ 
    int lance[4]; //move in integer notation 
    int roque; // etc. ... 

    struct smovimento *prox;// pointer to next 
} movimento; 

Эта программа может загрузить много памяти. И я знаю, что память находится в ее пределах. Но я думал, что malloc справится лучше, когда память недоступна.

Выполнение $free -h во время исполнения, я могу видеть память до 1 МБ! Ничего страшного. У старого компьютера только 96 МБ. И 50 МБ используется ОС.

Я не знаю, с чего начать искать. Может быть, проверить доступную память перед вызовом malloc? Но это звучит как сила компьютера, поскольку malloc предположительно сделает это. sizeof (movimento) около 48 bytes. Если я проверю раньше, по крайней мере, у меня будет подтверждение об ошибке.

Любые идеи, пожалуйста, поделитесь. Благодарю.

+1

У вас есть какие-либо большие выделения в стеке в некоторых функциях до того, что SIGSEGVs? Стек имеет ограниченный размер, программа может потерпеть крах таким образом, если он превышен. – Atle

+1

Такие вещи могут быть результатом перезаписи в области памяти, которая используется внутренним malloc. Это может быть указатель «один за другим» или доступ через устаревший указатель. – wildplasser

+0

@Atle Да, у меня есть.Но я очень осторожен, чтобы проверять каждое новое распределение. Я хочу, по крайней мере, иметь возможность printf («memory full \ n»), и не получить SIGSEGV, как это. Как я буду отслеживать размер свободного стека, прежде чем он сработает? Благодарю. –

ответ

2

Любой аварии внутри malloc (или free) есть и почти верный признак кучи коррупции, которая может прийти во многих формах:

  • перелива или Опустошений кучи буфера
  • освобождая что-то дважды
  • освобождение указателя без кучи
  • письменное сообщение освобожденному блоку
  • и др.

Эти ошибки очень трудно поймать без поддержки инструмента, потому что при сбое часто приходит много тысяч инструкций и, возможно, много вызовов в malloc или бесплатно позже, в коде, который часто находится в совершенно другой части программы и очень далеко от того, где ошибка.

Хорошей новостью является то, что такие инструменты, как Valgrind или AddressSanitizer, обычно указывают на проблему.

+0

Большое спасибо за ответ. Вероятно, это лучший ответ, который я могу получить. –

Смежные вопросы