Как найти причину ошибки malloc "double free"? - PullRequest
80 голосов
/ 09 июня 2009

Я программирую приложение в Objective-C и получаю эту ошибку:

MyApp (2121,0xb0185000) malloc: & ast; ** ошибка для объекта 0x1068310: двойное освобождение
*** установить точку останова в malloc_error_break для отладки

Это происходит, когда я выпускаю NSAutoreleasePool, и я не могу понять, какой объект я выпускаю дважды.

Как мне установить его точку останова?

Есть ли способ узнать, что это за "объект 0x1068310"?

Ответы [ 13 ]

45 голосов
/ 11 июня 2009

Когда объект «дважды освобожден», наиболее распространенной причиной является то, что вы (излишне) освобождаете объект с автоматическим освобождением, и он позднее автоматически освобождается, когда очищенный пул автоматического выпуска освобождается.

Я обнаружил, что лучший способ отследить дополнительную версию - это использовать переменную окружения NSZombieEnabled для уязвимого исполняемого файла в XCode. Для краткого изложения о том, как его использовать, проверьте эту вики-страницу CocoaDev . (В дополнение к этой странице Apple документировала несколько невероятно полезных советов по отладке кода в XCode, некоторые из которых спасли мой бекон несколько раз. Я предлагаю ознакомиться с этим Техническим примечанием для разработчика .apple.com - ссылка переходит в раздел, посвященный основам Cocoa).

Редактировать: Вы часто можете отследить нарушающий объект в отладчике XCode, но зачастую гораздо проще, если вы используете инструменты, чтобы помочь вам. В Xcode выберите Run & rarr; Начните с инструмента повышения производительности & rarr; Распределение объектов , и вы должны быть в состоянии отследить вызывающий объект обратно туда, где он был создан. (Это будет работать лучше всего, если вы включили зомби, как описано выше.) Примечание: Snow Leopard добавляет инструмент «Зомби» к инструментам, доступный также из меню «Выполнить». Может стоить только 29 долларов! ; -)

Здесь также есть связанный с этим вопрос .

37 голосов
/ 09 июня 2009

Вы узнаете, что это за объект, когда сломаете отладчик. Просто посмотрите на стек вызовов, и вы найдете, где вы его освободите. Это скажет вам, что это за объект.

Самый простой способ установить точку останова:

  1. Перейти к Выполнить -> Показать -> Точки останова ( ALT - Команда - B )
  2. Прокрутите до конца списка и добавьте символ malloc_error_break
12 голосов
/ 03 ноября 2010

Я просто хочу добавить свой опыт в дополнение к ответу Куинн Тейлор.

В одном из моих приложений мне нужно проанализировать и сохранить данные в основных объектах данных, а затем заставить эти объекты отображаться в представлениях. На самом деле, приложение работает просто отлично и не дает сбоев, пока я не попытался провести стресс-тест навигации по несколько раз назад и попытался открыть несколько видов как можно быстрее. Приложение вылетает с сообщением выше.

Я перепробовал все методы, которые Куинн предложил в своем ответе, и все еще не смог выяснить, где была точная причина.

Я установил NSZombieEnabled = YES и NSStackLogging = YES, запустил командную оболочку malloc_history, чтобы выяснить почему, но все равно не повезло. Он всегда указывает на то, где я сохраняю данные в основных объектах данных, на самом деле я проверял в тысячу раз больше выпущенных объектов, ничего странного.

Запуск в инструментах с различными инструментами (распределение, утечки и т. Д.) По-прежнему не помог. Включить охрану Маллок все равно ничего не получил.

Окончательное спасение: я попытался вернуться к представлениям, где объекты были взяты из Базовых данных, и отправил сообщение сохранения всем этим объектам, и принял к сведению эти изменения. Это решило проблему !!!

Итак, я обнаружил, что мне не удалось сохранить один, именно в этом причина. Просто хочу поделиться своим опытом, чтобы у вас было еще одно спасение для вашего приложения.

9 голосов
/ 11 июня 2009

Откройте консоль отладчика, нажав Cmd + Shift + R. Там наберите

break malloc_error_break

для установки точки останова в начале функции malloc_error_break.

Если вы хотите узнать, какой объект находится по адресу 0x1068310, вы можете ввести в консоль отладчика следующее:

print-object 0x1068310

Конечно, вы должны сделать это, пока объект еще жив - если объект уже был освобожден к тому времени, когда вы это делаете, это не будет работать.

4 голосов
/ 17 декабря 2011

Добавление символической точки останова в Xcode 4

Просто обновление, чтобы сделать это актуальным для Xcode 4 ...

Из Xcode 4 Руководство пользователя :

Чтобы добавить символическую точку останова. , .

  1. В левом нижнем углу навигатора точки останова нажмите кнопку Добавить. кнопка.
  2. Выберите Добавить символическую точку останова.
  3. Введите имя символа в Поле символов.
  4. Нажмите Готово.
4 голосов
/ 09 июля 2011

Для меня проблема была решена

(gdb) call (void)_CFAutoreleasePoolPrintPools()

сразу после аварии. Адрес наверху стека был адресом преступника. Вбросил retain и вуаля.

Адрес, указанный в лог-сообщении, никуда меня не доставил. Это никогда не обнаруживалось ни в одном из различных Инструментов. Видимо указатель на некоторые внутренние данные, которые уже были освобождены.

3 голосов
/ 05 августа 2009

Так выглядит точка останова malloc_error_break в окне точек останова в Xcode. Нужно поставить галочки, чтобы все заработало.

альтернативный текст http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png

2 голосов
/ 25 мая 2017

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

1) Нажмите « Точка останова ».
2) Затем нажмите Кнопка « + », расположенная ниже.
3) Добавьте символ «». Точка останова ..."из списка.
4) Добавьте Ключевое слово " malloc_error_break " в опции " Symbol ".

Или вы также можете обратиться к представленной ниже GIF-презентации.

GIF represenation

2 голосов
/ 11 ноября 2010

Проверьте ваши классы и посмотрите под методом dealloc. Убедитесь, что вы все равно звоните [super dealloc].

У меня была точно такая же проблема, и я узнал, что звоню [self dealloc]. Просто не обращая внимания.

1 голос
/ 10 мая 2017

Это обычно вызывается каким-то инспектором, таким как сафари или предварительный просмотр сафари. См. сообщение или сообщение и вопрос .

Снимите флажок AutoMatically Show Web ...., удалит эту проблему.

Обратите внимание, что только закрытие сафари или предварительный просмотр сафари не устранят эту проблему. И вы должны отменить выбор как сафари, так и предварительного просмотра сафари.

Если этого не произойдет, обратитесь к этому ответу или post для его отладки.

deselect automatically inspect on safari preview

...