Извините за длинное описание, но вопросы не такие простые ...
Мой проект написан без GC. Недавно я обнаружил утечку памяти, которую не могу найти. Я безрезультатно использовал новый Xcode Analyzer. Я прочитал свой код построчно и проверил все alloc / release / copy / autorelease / mutableCopy / keep и пулы ... - по-прежнему ничего.
Преамбула: Стандартные инструменты и Omni Leak Checker по какой-то причине у меня не работают (Omin Tool отклоняет мое приложение, Instruments.app (Leaks) съедает слишком много памяти и ЦП, поэтому у меня нет возможности его использовать).
Итак, я хочу написать и использовать свой собственный код для перехвата и отслеживания «всей» статистики сообщений alloc / allocWithZone: / dealloc, чтобы написать некоторую простую собственную библиотеку проверки утечек (основная цель - только пометить имена классов объектов с возможными утечками).
Основная техника захвата, которую я использую:
Method originalAllocWithZone = class_getClassMethod([NSObject class],@selector(allocWithZone:));
if (originalAllocWithZone)
{
imp_azo = (t_impAZOriginal)method_getImplementation(originalAllocWithZone);
if (imp_azo)
{
Method hookedAllocWithZone = class_getClassMethod([NSObject class],@selector(hookedAllocWithZone:));
if (hookedAllocWithZone)
{
method_setImplementation(originalAllocWithZone,method_getImplementation(hookedAllocWithZone));
fprintf(stderr,"Leaks Hook: allocWithZone: ; Installed\n");
}
}
}
- код, подобный этому, для перехвата метода alloc и dealloc как метод категории NSObject.
Я сохраняю IMP для реализации предыдущих методов, затем регистрирую и вычисляю все вызовы alloc / allocWithZone: как приращение (+1) значений статического массива NSInteger, а вызовы dealloc как декремент (-1).
В качестве конечной точки я называю предыдущую реализацию и возвращаемое значение.
По идее все работает нормально.
При необходимости я могу даже определить, является ли класс частью кластера классов (например, NSString, NSPathStore2; NSDate, __NSCFDate) ... с помощью некоторой функции нормализации (но это не имеет значения для проблем, описанных ниже).
Однако у этого метода есть некоторые проблемы:
- Не все классы могут быть пойманы, например, [NSDate date] не улавливается в alloc / allocWithZone: вообще, однако я вижу вызов alloc в GDB
- Поскольку я пытаюсь использовать технику автоматического обнаружения одиночных объектов (на основе keepCount readind) для автоматического исключения некоторых объектов из окончательной статистики, создание NSLocale зависает на этапе предварительной инициализации при запуске полного приложения Cocoa (на самом деле, даже простой командной строки Objective-C утилита с включенным фреймворком Foundation имеет некоторую дополнительную инициализацию перед main ()) - GDB использует allocWithZone: вызовы один за другим, ....
Полные исходники проекта концептуального проекта загружены здесь: http://unclemif.com/external/DILeak.zip (3.5 Кб)
Запустите make из Terminal.app, чтобы скомпилировать его, запустите ./concept, чтобы показать его в действии.
1-й вопрос: почему я не могу уловить все распределения объектов, подключив методы alloc и allocWithZone:?
2-й вопрос: зачем подключили allocWithZone: зависает в CFGetRetainCount (или [inst keepCount]) для некоторых классов ...