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

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

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

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

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

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

13 ответов


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

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

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

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

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

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

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


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

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

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

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

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

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. См.в должности или в должности и вопрос.

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

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

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

deselect automatically inspect on safari preview


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

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

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

GIF represenation


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

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


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

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

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


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

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

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