Ошибка в OS X 10.5 malloc? - PullRequest
       31

Ошибка в OS X 10.5 malloc?

2 голосов
/ 10 февраля 2011

Я пишу программу на C. У меня есть две основные машины для разработки, обе Mac. Один работает под управлением OS X 10.5 и является 32-битной машиной, другой работает под управлением OS X 10.6 и имеет 64-разрядную версию. Программа отлично работает при компиляции и запуске на 64-битной машине. Однако, когда я собираю ту же самую программу на 32-битной машине, она некоторое время запускается, а затем вылетает где-то внутри malloc. Вот обратный след:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xeeb40fe0
0x9036d598 in small_malloc_from_free_list ()
(gdb) bt
#0  0x9036d598 in small_malloc_from_free_list ()
#1  0x90365286 in szone_malloc ()
#2  0x903650b8 in malloc_zone_malloc ()
#3  0x9036504c in malloc ()
#4  0x0000b14c in xmalloc (s=2048) at Common.h:185
...

xmalloc - это моя пользовательская оболочка, которая просто вызывает exit, если malloc возвращает NULL, так что памяти не хватает.

Если я свяжу тот же код с -ltcmalloc, он будет работать нормально, поэтому я сильно подозреваю, что это ошибка где-то внутри стандартного распределителя OS X 10.5. Возможно, моя программа где-то вызывает повреждение памяти и что tcmalloc каким-то образом не срабатывает. Я попытался воспроизвести ошибку, выполнив ту же последовательность malloc s и free s в другой программе, но это сработало нормально.

Итак, мои вопросы:

  • Кто-нибудь видел эту ошибку раньше? Или, альтернативно

  • Как мне отладить что-то подобное? Например, есть ли отладочная версия OS X malloc?

Кстати, это связанные библиотеки:

$ otool -L ./interp 
./interp:
    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.5)

Обновление : Да, это повреждение кучи из-за записи за конец массива, теперь оно работает. Я должен был запустить valgrind, прежде чем отправлять вопрос. Тем не менее я был заинтересован в методах (кроме valgrind), как защитить себя от такого рода коррупции, так что спасибо за это.

Ответы [ 2 ]

4 голосов
/ 10 февраля 2011

Вы читали страницу руководства для malloc() в MacOS X? В частности, это говорит:

ОШИБКИ ОТЛАДКИ ОТЛОЖЕНИЯ

Для устранения ошибок распределения в приложениях предоставляется ряд средств. Эти объекты в основном контролируются с помощью переменных среды. Распознанные переменные среды и их значения описаны ниже.

ЭКОЛОГИЯ

Следующие переменные среды изменяют поведение функций, связанных с распределением.

  • MallocLogFile <f>

    Создание / добавление сообщений к указанному пути файла вместо записи в стандартная ошибка.

  • MallocGuardEdges

    Если установлено, добавьте защитную страницу до и после каждого большого блока.

  • MallocDoNotProtectPrelude

    Если установлено, не добавляйте защитную страницу перед большими блоками, даже если Задана переменная окружения MallocGuardEdges.

  • MallocDoNotProtectPostlude

    Если установлено, не добавляйте защитную страницу после больших блоков, даже если Задана переменная окружения MallocGuardEdges.

  • MallocStackLogging

    Если установлено, запишите все стеки, чтобы можно было использовать такие инструменты, как утечки.

  • MallocStackLoggingNoCompact

    Если установлено, запишите все стеки способом, совместимым с Программа malloc_history.

  • MallocStackLoggingDirectory

    Если установлено, стек записей записывается в каталог, указанный вместо сохранения их расположение по умолчанию (/tmp).

  • MallocScribble

    Если установлено, заполнить память, которая была выделена 0xaa байтов. это увеличивает вероятность того, что программа, делающая предположения о содержании только что выделенной памяти, потерпит неудачу. Также, если установлено, заполните память это было освобождено с 0x55 байтов. Это увеличивает вероятность что программа потерпит неудачу из-за доступа к памяти, которая больше не выделяется.

  • MallocCheckHeapStart <s>

    Если установлено, указывает количество выделений <s>, чтобы ждать, прежде чем начать периодические проверки кучи каждые <n>, как указано в MallocCheckHeapEach. Если MallocCheckHeapStart установлен, но MallocCheckHeapEach не указан, повторение проверки по умолчанию - 1000.

  • MallocCheckHeapEach <n>

    Если установлено, запускать проверку согласованности в куче каждые <n> операций. MallocCheckHeapEach имеет смысл только если MallocCheckHeapStart также комплект.

  • MallocCheckHeapSleep <t>

    Устанавливает количество секунд ожидания (ожидание подключения отладчика). когда установлен MallocCheckHeapStart и обнаружено повреждение кучи. по умолчанию 100 секунд. Установка этого в ноль означает не спать вообще. Установка этого в отрицательное число означает спать (для положительного числа секунд) только при первом обнаружении повреждения кучи.

  • MallocCheckHeapAbort <b>

    Когда установлено значение MallocCheckHeapStart и для него установлено ненулевое значение, вызывает abort (3) при обнаружении повреждения кучи вместо любой спящий.

  • MallocErrorAbort

    Если установлено, вызывает abort (3) при возникновении ошибки вmalloc (3) или free (3), например, вызов free (3) для указателя ранее освобожден.

  • MallocCorruptionAbort

    Аналогичен MallocErrorAbort, но не прерывает работу в условиях нехватки памяти, что делает более полезным отлавливать только те ошибки, которые вызывают повреждение памяти. MallocCorruptionAbort всегда устанавливается для 64-битных процессов.


Тем не менее, я все равно сначала буду использовать valgrind.

1 голос
/ 10 февраля 2011

Кто-нибудь видел эту ошибку раньше

Да, это распространенная ошибка программирования и почти наверняка есть в вашем коде.См. http://www.efnetcpp.org/wiki/Heap_Corruption

Как мне отладить что-то подобное?

См. Раздел Инструменты выше по ссылке.

...