Как найти причину ошибки «double free» malloc?
Я программирую приложение в Objective-C, и я получаю эту ошибку:
MyApp (2121,0xb0185000) malloc: *** ошибка для объекта 0x1068310: double free
*** установить точку останова в malloc_error_break для отладки
Это происходит, когда я выпускаю NSAutoreleasePool, и я не могу понять, какой объект я выпускаю дважды.
- Установка объектов на Null / Nothing после использования в .NET.
- распределение памяти типов значений и ссылочных типов в инфраструктуре .net
- В каких случаях я использую malloc vs new?
- Как выделить выровненную память только с использованием стандартной библиотеки?
- Когда следует использовать malloc в C, а когда нет?
Как установить его точку останова?
Есть ли способ узнать, что это за «объект 0x1068310»?
- Что произойдет, если я попытаюсь получить доступ к памяти за пределами области malloc ()?
- Файлы Mex: как вернуть уже выделенный массив Matlab
- @property сохранять, назначать, копировать, неатомически в Objective-C
- Сведения о переполнении памяти Linux
- Адрес памяти C # и переменная
- В чем разница между слабой ссылкой и неизменной ссылкой?
- Разделение памяти Android
- Как я могу дать eclipse больше памяти, чем 512M?
Вы узнаете, что представляет собой объект, когда вы входите в отладчик. Просто найдите стек вызовов, и вы найдете, где его освободите. Это скажет вам, какой именно объект.
Самый простой способ установить точку останова:
- Перейдите в Run -> Show -> Breakpoints ( ALT – Command – B )
- Прокрутите список до конца и добавьте символ
malloc_error_break
Когда объект «дважды освобожден», наиболее распространенной причиной является то, что вы (без необходимости) освобождаете объект с автореализацией, и позже его автореализовываете, когда пул резервных копий сохраняется.
Я обнаружил, что лучший способ отследить дополнительный выпуск – использовать переменную среды NSZombieEnabled для уязвимого исполняемого файла в Xcode. Для краткого изложения того, как его использовать, ознакомьтесь с этой вики-страницей CocoaDev . (В дополнение к этой странице Apple задокументировала некоторые невероятно неясные, но полезные советы по отладке кода в Xcode, некоторые из которых сохранили мой бекон более чем несколько раз. Я предлагаю проверить эту Техническую ноту на developer.apple.com – link переходит в раздел «Основы Фонда Какао»).
Изменить: вы часто можете отслеживать оскорбительный объект в отладчике Xcode, но часто бывает намного проще, если вы используете инструменты, чтобы помочь вам. В Xcode выберите « Выполнить»> «Начать с инструментария производительности» → «Распределение объектов», и вы сможете отслеживать объект-нарушитель обратно туда, где он был создан. (Это будет работать лучше всего, если вы включили зомби, как описано выше.) Примечание: Snow Leopard добавляет инструмент Zombies для инструментов, ansible из меню «Выполнить». Может стоить только $ 29! 😉
Здесь также есть связанный вопрос SO .
Я просто хочу добавить свой опыт в дополнение к ответу Куинна Тейлора.
В одном из моих приложений я должен разбирать и сохранять данные в основных объектах данных, а затем получать эти объекты для отображения в представлениях. На самом деле приложение работает нормально и вообще не сбой, пока я не попытался выполнить стресс-тест по навигации взад и вперед несколько раз, попытался как можно быстрее открыть несколько просмотров. Приложение завершилось с сообщением выше.
Я пробовал все методы, предложенные Куинном в его ответе, и до сих пор не смог выяснить, где была точная причина.
Я установил NSZombieEnabled = YES и NSStackLogging = YES, запустил командную оболочку malloc_history, чтобы узнать, почему, но все равно не повезло. Он всегда указывает на то, где я сохраняю данные в основных объектах данных, на самом деле, я проверил тысячу раз над выпущенными объектами, ничего странного.
Работа в Инструментах с различными инструментами (Распределение, Утечки и т. Д.) Все еще не помогла. Включить Guard Malloc все равно ничего не получилось.
Окончательное спасение: я попытался вернуться к представлениям, где объекты были взяты из Core Data, и отправил сообщение сохранения всем этим объектам и принял к сведению эти изменения. Он решил проблему !!!
Итак, я узнал, что я не смог его сохранить, это именно причина. Просто хочу поделиться своим опытом, чтобы у вас было другое спасение для вашего приложения.
Откройте консоль отладчика, нажав Cmd + Shift + R. Там, введите
break malloc_error_break
установить malloc_error_break
останова в начале функции malloc_error_break
.
Если вы хотите узнать, какой объект находится по адресу 0x1068310, вы можете ввести следующее в консоль отладчика:
print-object 0x1068310
Конечно, вы должны сделать это, пока объект все еще жив – если объект уже был освобожден к тому моменту, когда вы это сделаете, это не сработает.
Для меня проблема была решена
(gdb) call (void)_CFAutoreleasePoolPrintPools()
сразу после аварии. Адрес в верхней части стека был адресом виновника. Бросил в retain
и вуаля.
Адрес, указанный в сообщении журнала, меня нигде не доставил. Он никогда не появлялся ни в одном из различных Instrumets. По-видимому, указатель на некоторые внутренние данные, которые уже были освобождены.
Добавление символьной точки останова в Xcode 4
Просто обновление, чтобы сделать это актуальным для Xcode 4 …
Из руководства пользователя Xcode 4 :
Чтобы добавить символическую точку останова. , ,
- В левом нижнем углу навигатора точки останова нажмите кнопку «Добавить».
- Выберите Добавить символическую точку останова.
- Введите имя символа в поле «Символ».
- Нажмите Готово.
Вот как выглядит точка останова malloc_error_break в окне Breakpoints в Xcode. Необходимо проверить флажки, чтобы они работали.
alt text http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png
Проверьте свои classы и посмотрите на метод dealloc. Удостоверьтесь, что вам нужно позвонить [super dealloc].
У меня была такая же проблема, и я узнал, что я называю [self dealloc]
. Просто не обращая внимания.
Обычно это вызвано некоторым инспектором, таким как предварительный просмотр safari или safari. См. Сообщение, сообщение и вопрос .
Удалите выбор AutoMatically Show Web …., удалите эту проблему.
Обратите внимание, что только закрытие safari или предварительного просмотра safari не устранит эту проблему. И вы должны отменить выбор safari и safari.
Если этого не произойдет, обратитесь к этому ответу или сообщению, чтобы его отладить.
Ниже вы найдете инструкции о том, как найти бесплатный объект и свернуть приложение.
1) Нажмите « Навигатор точки останова ».
2) Затем нажмите кнопку « + », которая находится ниже.
3) Добавьте в список « Символическую точку останова … ».
4) Добавьте ключевое слово « malloc_error_break » в опции « Символ ».
Или вы также можете обратиться к ниже представленной презентации GIF.
В Xcode нажмите левую часть номера строки, чтобы установить точку останова. Затем вы можете запустить его, выполнив «Построение и отладка».
Рекомендуется не создавать объект, который вы создаете, autorelease
поскольку память является товаром на iPhone. Apple рекомендует явно вызывать release
.
Чтобы найти такие проблемы с памятью и указателями в целом, вы хотите запустить свой код с помощью проверки ошибок памяти во время выполнения, например Valgrind . Это должно указывать на то, что ваш код делает неправильно, помимо тех, которые приводят к его сбою.
Valgrind может работать на OSX (хотя он говорит, что это «неподдерживаемый и неполный и багги»), и с небольшим взломом кто-то получил его для работы с исполняемыми файлами iPhone SDK .
Еще лучше вы можете попробовать инструменты, которые являются частью XCode. Здесь есть учебник для запуска.
Если malloc_error_break
не помогает …
Лучший способ решить эту ошибку – запустить инструменты с NSZombies
. Инструменты будут отмечать вас, когда Zombie отправлен в сообщение, и вы можете напрямую отследить строку кода.
Требуется снежный барс, какой спасатель!