Страниц: [1]
  Печать  
Автор Тема: Нормально ли, что падает libc.so.2 и что сделано неправильно?  (Прочитано 5908 раз)
Ilyak
Гость
« : Сентября 18, 2003, 09:27:00 pm »

Пытаюсь собрать одну программу, которая стабильно делает
170             hashTable->entries = uio_calloc(hashTable->size,
(gdb) p hashTable->size
$20 = 8
(gdb) p hashTable->entries
$21 = (CharHashTable_HashEntry **) 0x0
(gdb) next

Program received signal SIGSEGV, Segmentation fault.
0xb031b543 in _block_memalign () from /x86/lib/libc.so.2

Причем это функция вызывается неоднократно, но валися только один раз.

в hashTable->entries писать можно.

Что именно падает? Почему? Являются ли падения в таком интимном месте системы исключением - или же, просто следствием наших кривых рук?
Записан
dmi
QOR.Admin
*****
Offline Offline

Сообщений: 470



Просмотр профиля
« Ответ #1 : Сентября 19, 2003, 02:05:00 am »

Обычно такие вылеты означают либо повторное освобождение памяти, либо переполнение буфера libc'шных функций.
Точнее сказать сложно.
Сейчас работаю над написанием трассировщика - будет проще диагностировать такие проблемы.
Записан
Ilyak
Гость
« Ответ #2 : Сентября 19, 2003, 10:35:00 am »

Хорошо, потому что, как это отлаживать и что делать - совершенно не представляю...
Записан
dmi
QOR.Admin
*****
Offline Offline

Сообщений: 470



Просмотр профиля
« Ответ #3 : Сентября 19, 2003, 03:02:00 pm »

А как выравнивается hashTable?

P.S.: С трассировщиком большой затык - в 6.2.1 вдруг перестали работать точки останова.
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #4 : Сентября 19, 2003, 03:16:00 pm »

Это специфика libc. Причем связанная с GNU компилятором. В общем в двух словах проблема в каком-то из delete - была убита убитая память или не та, что была выделена. Нарушилась цепочка в хипе и при первом же alloc все это дело накрывается медным тазом.
Записан

lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #5 : Сентября 19, 2003, 03:32:00 pm »


Хорошо, потому что, как это отлаживать и что делать - совершенно не представляю...

А отлаживать это у кого фантазии на что хватает, от ++ средств, до тупой проверки на C в виде

if ((table->entry)!=NULL)
{
  free(table->entry);
  table->entry=NULL;
}
else
{
  assert(...);
}

для каждого free. Либо с самого начала писать правильно и грамотно, тогда таких проблем не будет.
Записан

dmi
QOR.Admin
*****
Offline Offline

Сообщений: 470



Просмотр профиля
« Ответ #6 : Сентября 19, 2003, 03:42:00 pm »


Ilyak пишет:
Хорошо, потому что, как это отлаживать и что делать - совершенно не представляю...


А зря не представляете. Загляните в руководство разработчика, в часть про описание библиотеки malloc_g (или g_malloc?). Очень хороший способ отладки сложных приложений с проблемами выделения/высвобождения памяти.
Замечательно детектирует утечки памяти, двойное освобождение (double free, на самом деле повторное), наложения участков памяти и т.д.
Только убедитесь при использовании, что загрузилась действительно _та_ библиотека. Это во-первых при компиляции -lmalloc_g
И при запуске LD_LIBRARY_PATH=/lib/malloc_g ./program
И не запыть проинициализировать бибилиотеку перед первым malloc
Записан
Ilyak
Гость
« Ответ #7 : Октября 11, 2003, 08:49:00 pm »

/src/lib/c/alloc/band.c:81 - fatal alloc error - lnp address
zsh: segmentation fault (core dumped)  ./uqm --contentdir=conten

Либо с самого начала писать правильно и грамотно, тогда таких проблем не будет.

1) Код этот писал не я.
2) На всех остальных ос, включая win32, linux и mac os X, все работает. Второй раз уже так - валится только QNX...

А зря не представляете. Загляните в руководство разработчика, в часть про описание библиотеки malloc_g (или g_malloc?).

Спасибо. Почитал еще тогда, однако руки дошли только сегодня.
Подключил. Нормально. Пересобрал. Результат:
==
The Ur-Quan Masters v0.3 (compiled Oct 11 2003 16:59:32)
This software comes with ABSOLUTELY NO WARRANTY;
for details see the included 'COPYING' file.

MALLOC Warning from free() (called from instruction preceding 0x0810496D):
Data has overrun beyond requested number of bytes
This error is *probably* associated with the following allocation:

   A call to malloc for         27 bytes in an unknown file near    810493E.
   This was the 173rd call to malloc.

@ [0x0804BD14]
@ (main+0x0000097B)[0x0804CF07]
@ [0x0804BEA9]
@ [0x0804C314]
@ [0x0804C417]
@ (main+0x000B067D)[0x080FCC09]
@ (main+0x000B0849)[0x080FCDD5]
@ (main+0x000B0C55)[0x080FD1E1]
@ (main+0x000B0E6C)[0x080FD3F8]
@ (main+0x000B838B)[0x08104917]
@ (main+0x000B83E1)[0x0810496D]
@ libmalloc.so.2:(free+0x00000023)[0xB8207CA3]
@ libmalloc.so.2:(debug_free+0x00000032)[0xB8207D5A]
@ libmalloc.so.2:(__debug_free+0x00000028)[0xB8207D20]
@ libmalloc.so.2:(DBFfree+0x000001CD)[0xB8207F41]
MALLOC Warning from free() (called from instruction preceding 0x0810496D):
Malloc region doesn't have a valid CRC in header
@ [0x0804BD14]
@ (main+0x0000097B)[0x0804CF07]
@ [0x0804BEA9]
@ [0x0804C314]
@ [0x0804C417]
@ (main+0x000B067D)[0x080FCC09]
@ (main+0x000B0849)[0x080FCDD5]
@ (main+0x000B0C55)[0x080FD1E1]
@ (main+0x000B0E6C)[0x080FD3F8]
@ (main+0x000B838B)[0x08104917]
@ (main+0x000B83E1)[0x0810496D]
@ libmalloc.so.2:(free+0x00000023)[0xB8207CA3]
@ libmalloc.so.2:(debug_free+0x00000032)[0xB8207D5A]
@ libmalloc.so.2:(__debug_free+0x00000028)[0xB8207D20]
@ libmalloc.so.2:(DBFfree+0x000001CD)[0xB8207F41]
/src/lib/c/alloc/band.c:81 - fatal alloc error - lnp address
==
Кто-нибудь поможет расшифровать эту клинопись?

Да, 0x0810493E - это вот:
==
       // Linux's and FreeBSD's struct dirent are defined with a
       // maximum d_name field (NAME_MAX).
       // However, POSIX doesn't require this, and in fact
       // at least QNX defines struct dirent with an empty d_name field.
       // This should take care of it:
       result->direntBuffer = uio_malloc(
                       sizeof (struct dirent)
                       - ((sizeof (((struct dirent *) 0)->d_name) + 3) & 3)
                       + (((NAME_MAX + 1) + 3) & 3));
                       // Take the length of the dirent structure as it is defined,
                       // subtract the length of the d_name field, and add the length
                       // of the maximum length d_name field (NAME_MAX plus 1 for
                       // the '').
                       // The '(... +3) & 3' is to take into account that fields
                       // will be aligned on 4 bytes.
                       // (What about 64 bits machines?)
==
Похоже, был какой-то воркароунд, но он сломался.

Да! Падает=то оно совсем в другом месте.. Но понятно, что может быть взаимосвязь...

Ладно. Ночью буду мучать деволупоперов этого дела...

Хелп не знает такого понятия, как lnp. Что это может быть, как можно дальше продиагностировать? У малолок_г есть какая-то функция, пишущая отчОт в файл, ее, что-ли, попробовать?..

Очень хороший способ отладки сложных приложений с проблемами выделения/высвобождения памяти.
Замечательно детектирует утечки памяти, двойное освобождение (double free, на самом деле повторное), наложения участков памяти и т.д.

Еще бы  в ней разобраться до конца... Как все  эти прекрасные возможности получить?
Записан
dmi
QOR.Admin
*****
Offline Offline

Сообщений: 470



Просмотр профиля
« Ответ #8 : Октября 13, 2003, 02:36:00 am »

Так выравнивание памяти на сколько бит идёт? Какая версия системы?
Разверните всю эту математику нафиг.

[ Это Сообщение было отредактировано: dmi в 2003-10-12 23:37 ]
Записан
zeus
Участник
*
Offline Offline

Сообщений: 0


Просмотр профиля
« Ответ #9 : Октября 13, 2003, 08:19:00 am »

Глюкоматика, блин...
от размера структуры отымается сумма выравненных по отдельности до двойного слова поля и ASCIIZ строки. При определенных условиях полученное значение будет меньше необходимого на несколько байт. Однако, это может привести к тому, что, если нет выравнивания полей структуры по двойному слову (long которое), при некоторых операциях будет портиться следующая выделенная структура.
(added later) Собственно об этом прямо и сообщается: неправильная CRC-сумма выделенного региона!
Ай-яй-яй.
Работоспособность на Linux и Win может объясняться тем, что оные имеют немаленькую гранулярность выделения памяти, т.е. хоть и закажем 5 байт, а дадут где-то около 64... (но это только догадка, как обстоит на самом деле - хз)
Workaround: прибавить к полученному значению место на 2 long...


[ Это Сообщение было отредактировано: zeus в 2003-10-13 05:24 ]
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #10 : Октября 13, 2003, 11:45:00 am »


2) На всех остальных ос, включая win32, linux и mac os X, все работает. Второй раз уже так - валится только QNX...

1) В QNX выделение памяти работает по-другому, чем в linux/win32. Что-то с маленьким размером хипа by default. Отчего происходит частое довыделение памяти, часто с размером page. Отчего многие софтинки, которые привыкли к safety pool, какой встречается в win32/linux/freebsd часто просто падают при overrun за границы массива. Я такие баги исправлял в десятках приложений во время портирования, причем авторы были в шоке, тот код обычно под пяток лет не трогался

2) Может попробовать под win32 rational purify/clarify, много интересного откроешь для себя


A call to malloc for 27 bytes in an unknown file near 810493E. This was the 173rd call to malloc.
Кто-нибудь поможет расшифровать эту клинопись?


Этого достаточно вполне. Укажи ключик gcc для генерации map файла и изучай.
Записан

Страниц: [1]
  Печать  
 
Перейти в: