Как найти причину ошибки malloc "double free"?


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

MyApp(2121, 0xb0185000) malloc: *** ошибка для объекта 0x1068310: double free
*** установите точку останова в malloc_error_break для отладки

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

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

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

13 78

13 ответов:

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

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

  1. перейти к Run - > Show - > точки останова ( ALT -команда -B)
  2. прокрутите список до конца и добавьте символ malloc_error_break

когда объект "дважды освобожденный", наиболее частой причиной является то, что вы (необоснованно) выпуская объект autoreleased, и это позже autoreleased когда содержащие autorelease пул опустошается.

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

Edit: вы часто можете отслеживать объект-нарушитель в отладчике Xcode, но это часто намного проще, если вы используете инструменты, чтобы помочь вам. Из Xcode, выберите Run → Start With Performance Tool → Выделение Объектов и вы должны быть в состоянии проследить объект нарушителя туда, где он был создан. (Это будет работать лучше всего, если вы включены зомби, как описано выше.)Примечание: Snow Leopard добавляет инструмент зомби к инструментам, доступным также из меню Run. Может быть стоит $29 в покое! ; -)

есть еще и связанный так вопрос здесь.

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

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

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

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

запуск в инструментах с использованием различных инструментов(выделение, протечек и т. д...) еще не помощь. Включить охранника Мэллоку все равно нечем.

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

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

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

break malloc_error_break

установить точку останова в начале

для меня вопрос был решен

(gdb) call (void)_CFAutoreleasePoolPrintPools()

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

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

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

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

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

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

  1. в левом нижнем углу навигатора точек останова нажмите кнопку Добавить кнопка.
  2. Выберите Добавить Символическую Точку Останова.
  3. введите имя символа в Поле символов.
  4. клик Сделанный.

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

alt текст http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png

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

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

обычно это вызвано каким-либо инспектором, например safari или Safari preview. См. post или post и вопрос.

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

Примечание, просто закройте safari или safari preview не удалит эту проблему. И вы должны отменить выбор как safari, так и safari preview.

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

deselect automatically inspect on safari preview

пожалуйста, найдите следующие шаги для того, как найти объект, который является бесплатным и сбой приложения.

1) нажать на "навигатор точки останова".
2) затем нажмите на кнопку "+", которая находится ниже.
3) Добавить "символические Точка прерывания..." из списка.
4) Добавить "malloc_error_break" ключевое слово на "символ опции".

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

GIF represenation

в Xcode щелкните слева от номера строки, чтобы установить точку останова. Затем вы можете запустить его, выполнив "сборку и отладку".

рекомендуется не иметь объект, который вы создаете быть autorelease Так как память является товаром на iPhone. Apple рекомендует явно вызывать release.

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

отчет может работать на OSX (хотя он говорит, что это "неподдерживаемый и неполный и багги"), и с небольшим взломом кто-то получил его для работы над iPhone SDK исполняемые файлы.

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

Если malloc_error_break не помогает...

лучший способ решить эту ошибку, чтобы запустить инструменты С NSZombies включен. Инструменты будут отмечать вас, когда зомби будет отправлено сообщение, и вы можете проследить непосредственно до строки кода.

требуется Снежный Барс, какой спасатель, хотя!