Как найти причину ошибки malloc "double free"?
я программирую приложение в Objective-C и я получаю эту ошибку:
MyApp(2121, 0xb0185000) malloc: *** ошибка для объекта 0x1068310: double free
*** установите точку останова в malloc_error_break для отладки
это происходит, когда я выпускаю NSAutoreleasePool, и я не могу понять, какой объект я выпускаю дважды.
Как мне установить его останова?
есть ли способ узнать, что это "объект 0x1068310"?
13 ответов:
вы узнаете, что это за объект, когда вы сломаете отладчик. Просто посмотрите на стек вызовов, и вы найдете, где вы его освободите. Это скажет вам, какой это объект.
самый простой способ установить точку останова:
- перейти к Run - > Show - > точки останова ( ALT -команда -B)
- прокрутите список до конца и добавьте символ
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:
добавить символическую точку останова . . .
- в левом нижнем углу навигатора точек останова нажмите кнопку Добавить кнопка.
- Выберите Добавить Символическую Точку Останова.
- введите имя символа в Поле символов.
- клик Сделанный.
вот как выглядит точка останова 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 для отладки.
пожалуйста, найдите следующие шаги для того, как найти объект, который является бесплатным и сбой приложения.
1) нажать на "навигатор точки останова".
2) затем нажмите на кнопку "+", которая находится ниже.
3) Добавить "символические Точка прерывания..." из списка.
4) Добавить "malloc_error_break" ключевое слово на "символ опции".или вы также можно обратиться к приведенной ниже презентации GIF.
в Xcode щелкните слева от номера строки, чтобы установить точку останова. Затем вы можете запустить его, выполнив "сборку и отладку".
рекомендуется не иметь объект, который вы создаете быть
autorelease
Так как память является товаром на iPhone. Apple рекомендует явно вызыватьrelease
.
чтобы найти такие проблемы с памятью и указателем в целом, вы хотите запустить свой код против проверки ошибок памяти во время выполнения, например Valgrind. Это должно быть в состоянии указать на многие вещи, которые ваш код делает неправильно, помимо тех, которые вызывают его сбой.
отчет может работать на OSX (хотя он говорит, что это "неподдерживаемый и неполный и багги"), и с небольшим взломом кто-то получил его для работы над iPhone SDK исполняемые файлы.
еще лучше вы можете попробовать инструменты, которые являются частью XCode. Есть учебник для его запуска здесь.