Включение функций отладки Malloc

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

Включение защиты Malloc

Защитный Malloc является специальной версией malloc библиотеки, заменяющей стандартную библиотеку во время отладки. Охраняйте использование Malloc несколько методов, чтобы попытаться разрушить Ваше приложение в отдельном моменте, где происходит ошибка памяти. Например, когда память освобождена, это помещает отдельные выделения памяти на различных страницах виртуальной памяти и затем удаляет всю страницу. Последующие попытки получить доступ к освобожденной памяти вызывают непосредственное исключение памяти, а не слепой доступ в память, которая могла бы теперь содержать другие данные. Когда катастрофический отказ происходит, можно тогда пойти и проверить точку отказа в отладчике для идентификации проблемы.

Чтобы позволить отладить Защиту использования Malloc, сконфигурируйте свой проект выполнить с Защитой Malloc в редакторе схемы XCode. Можно использовать эту опцию для приложений Mac и приложений для iOS, работающих в средстве моделирования.

Для получения дополнительной информации о типах проблем памяти, которые Защита Malloc может помочь Вам разыскать, посмотрите libgmalloc страница справочника в Страницах справочника OS X.

Конфигурирование переменных окружения Malloc

malloc библиотека обеспечивает функции отладки, чтобы помочь Вам разыскать ошибки разрушения памяти, повреждение «кучи», ссылки на освобожденную память и переполнение буфера. Вы включаете эти параметры отладки через ряд переменных окружения. За исключением MallocCheckHeapStart и MallocCheckHeapEach, значение для большинства этих переменных окружения проигнорировано. Для отключения переменной от Терминала используйте unset команда. Таблица 1 перечисляет некоторые ключевые переменные окружения и описывает их основную функцию. Для полного списка переменных посмотрите malloc страница справочника.

Таблица 1  переменные окружения Malloc

Переменная

Описание

MallocStackLogging

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

MallocStackLoggingNoCompact

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

MallocScribble

Если установлено, free наборы каждый байт каждого выпущенного блока к значению 0x55.

MallocPreScribble

Если установлено, malloc наборы каждый байт недавно выделенного блока к значению 0xAA. Это увеличивает вероятность, что программа, делающая предположения о недавно выделенной памяти, перестала работать.

MallocGuardEdges

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

MallocDoNotProtectPrelude

Мелкозернистое управление поведением MallocGuardEdges: Если установлено, malloc не помещает защитную страницу во главе каждого большого блочного выделения.

MallocDoNotProtectPostlude

Мелкозернистое управление поведением MallocGuardEdges: Если установлено, malloc не помещает защитную страницу в хвосте каждого большого блочного выделения.

MallocCheckHeapStart

Установите эту переменную в число выделений прежде malloc начнет проверять «кучу». Если не набор, malloc не проверяет «кучу».

MallocCheckHeapEach

Установите эту переменную в число выделений прежде malloc должен проверить «кучу». Если не набор, malloc не проверяет «кучу».

Следующий пример включает журналирование штабеля и «кучу», регистрируясь в текущей оболочке прежде, чем запустить приложение. Значение для MallocCheckHeapStart установлен в 1, но не важен и может быть установлен в любое значение, которое Вы хотите. Если Вы действительно уверены, Вы могли также установить эти переменные от файла запуска своей оболочки, несмотря на то, что export каждая переменная.

% MallocStackLogging=1
% MallocCheckHeapStart=1000
% MallocCheckHeapEach=100
% ./my_tool

Если Вы хотите выполнить свою программу в gdb, можно установить переменные окружения от консоли отладки XCode с помощью команды set env, как показано в следующем примере:

% gdb
(gdb) set env MallocStackLogging 1
(gdb) run

Некоторые инструменты производительности требуют, чтобы эти опции были приведены в порядок для сбора их данных. Например, malloc_history инструмент может идентифицировать сайт выделения определенных блоков если MallocStackLogging флаг установлен. Этот инструмент может также описать блоки, ранее выделенные в адресе если MallocStackLoggingNoCompact переменная окружения установлена. leaks инструмент командной строки назовет сайт выделения пропущенного буфера если MallocStackLogging установлен. См. страницы справочника для leaks и malloc_history для большего количества подробных данных.

Обнаружение дважды освобожденной памяти

malloc библиотека сообщает о попытках вызвать free на уже освобожденном буфере. Если Вы включили MallocStackLoggingNoCompact опция, можно использовать зарегистрированные данные стека для обнаружения где в коде второе free вызов был выполнен. Можно тогда использовать эту информацию, чтобы установить надлежащую точку останова в отладчике и разыскать проблему.

malloc библиотека сообщает информацию stderr.

Обнаружение повреждения «кучи»

Для включения проверки «кучи» присвойте значения MallocCheckHeapStart и MallocCheckHeapEach переменные окружения. Необходимо установить обе из этих переменных для включения проверки «кучи». MallocCheckHeapStart переменная говорит malloc библиотеке сколько malloc вызовы для обработки прежде, чем инициировать первую проверку «кучи». Установите второе в число malloc вызовы для обработки между проверками «кучи».

MallocCheckHeapStart когда повреждение «кучи» происходит в предсказуемое время, переменная полезна. Как только это поражает надлежащую стартовую точку, malloc библиотека начинает регистрировать сообщения выделения к Окну терминала. Можно наблюдать число выделений и использовать ту информацию для определения приблизительно, где повреждается «куча». Скорректируйте значения для MallocCheckHeapStart и MallocCheckHeapEach по мере необходимости сужать реальную точку повреждения.

Обнаружение ошибок разрушения памяти

Для нахождения ошибок разрушения памяти включите MallocScribble переменная. Эта переменная пишет недопустимые данные в освобожденные блоки памяти, выполнение которых заставляет исключение происходить. При использовании этой переменной необходимо также установить MallocStackLogging и MallocStackLoggingNoCompact переменные для журналирования расположения исключения. Когда исключение происходит, можно тогда использовать malloc_history команда для разыскивания кода, выделившего блок памяти. Можно тогда использовать эту информацию, чтобы отследить через код и искать любые непрекращающиеся указатели на этот блок.