很抱歉描述太长,但是问题并不那么容易......
我的项目在没有 GC 的情况下编写。最近我发现了一个我找不到的内存泄漏。我确实使用了新的 Xcode Analyzer,但没有结果。我确实逐行阅读了我的代码并验证了所有 alloc/release/copy/autorelease/mutableCopy/retain 和 pools... - 仍然没有。
序言:由于某种原因,Standard Instruments 和 Omni Leak Checker 对我不起作用(Omin Tool 拒绝了我的应用程序,Instruments.app(Leaks)占用了太多内存和 CPU,所以我没有机会使用它)。
所以我想编写并使用我自己的代码来挂钩和跟踪“所有”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) stat-array NSInteger 值,而 dealloc 调用为减量 (-1)。
作为终点,我调用先前的实现和返回值。
在概念上一切正常。
如果需要,我什至可以检测类何时是类集群的一部分(如 NSString、NSPathStore2;NSDate、__NSCFDate)...通过一些规范化功能(但对于下面描述的问题无关紧要)。
但是这种技术有一些问题:
- 并非所有类都可以被捕获,例如,[NSDate date] 在 alloc/allocWithZone 中没有捕获:但是,我可以在 GDB 中看到 alloc 调用
- 由于我试图使用自动单例检测技术(基于retainCount readind)从最终统计信息中自动排除一些对象,当启动完整的Cocoa应用程序(实际上,甚至是简单的Objective-C命令行)时,NSLocale创建冻结在预初始化阶段包含 Foundation 框架的实用程序在 main()) 之前有一些额外的初始化 - GDB 有 allocWithZone: 一个接一个地调用,....
此处上传的完整概念项目草稿源:http: //unclemif.com/external/DILeak.zip (3.5 Kb)
从Terminal.app运行make来编译它,运行./concept来展示它。
第一个问题:为什么我不能通过挂钩 alloc 和 allocWithZone: 方法来捕获所有对象分配?
第二个问题:为什么挂钩 allocWithZone: 在某些类的 CFGetRetainCount (或 [inst retainCount]) 中冻结...