野指针扑获实战篇

一、背景

上一篇咱们知道怎么经过xcode东西去探测出野指针问题,可是面对两个严重弊端

  • 测验同学无法直接使用
  • 人工debug测验,关于一些开释后再次使用的目标来说测验周期短仍是无法获取

针对以上两个痛点,咱们需要开发一款东西,嵌入咱们的工程使随时随地能够进行野指针case扑获

二、检测原理

  • 当目标调用dealloc时,仅免除目标的引用关系,然后将该目标变为僵尸目标,一起添加NSProxy协议用于接受音讯进行音讯转发打印反常信息
  • 经过链表管理僵尸目标,目标包含指针p,原目标以及加入时刻。
  • 当僵尸目标在30秒以内被再次访问时,就会经过NSProxy转发原目标,调用办法,以及仓库信息,抛给业务层,由业务层自行处理。
  • 守时扫描僵尸目标,存留超过30秒的僵尸目标,将被清理,收回内存。

三、目标

  • 阻拦野指针防止crash
  • 阻拦野指针对战进行上报

四、计划评价

本篇计划:

这篇文章选用阻拦dealloc构造zombie目标进行音讯转发获取给已开释目标发音讯的仓库

原因

不管是使用hook c层的free办法仍是上层oc目标的dealloc办法,实践底层都是特别耗费功能的,两者比较hook c层的free办法,覆盖面表广,耗费功能也多,所以综合咱们的实践情况挑选后者

五、详细完成

中心首要流程

野指针扑获实战篇

外部使用东西

引入pod库

pod 'HuntingZombiesTool'

初始化配置

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    //当检测到野指针后的回调,由业务自行处理。可挑选上报错误,也能够直接crash
    ZombieConfig.share.throwInfo = ^(NSString * _Nonnull info) {
        @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:info userInfo:nil];
    };
    //司机侧示例代码
    ZombieConfig.share.throwInfo = ^(NSString * _Nonnull info) {
        NSLog(info);
        //能够上报到自己分析渠道
    };
    ZombieConfig.share.zombieActivityTime = 30;
    ZombieConfig.share.classes = [self ownClassesInfo];//如果这儿传空,默认是扫描所有类
    [ZombieConfig.share startZombie];
    return YES;
}
//获取本项目非系统库的类
- (NSArray <Class>*)ownClassesInfo {
    NSMutableArray *resultArray = [NSMutableArray array];
    unsigned int classCount;
    const char **classes;
    Dl_info info;
    dladdr(&_mh_execute_header, &info);
    classes = objc_copyClassNamesForImage(info.dli_fname, &classCount);
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    dispatch_apply(classCount, dispatch_get_global_queue(0, 0), ^(size_t iteration) {
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSString *className = [NSString stringWithCString:classes[iteration] encoding:NSUTF8StringEncoding];
        Class class = NSClassFromString(className);
        [resultArray addObject:class];
        dispatch_semaphore_signal(semaphore);
    });
    return resultArray.mutableCopy;
}

测验类

# 该类设置mrc
- (void)tmpBtnClickd:(UIButton *)sender {
    UIView* testObj = [[UIView alloc] init];
    [testObj release];
    [testObj setNeedsLayout];
}

效果

野指针扑获实战篇

六、依靠信息

野指针扑获pod库及demo

到这儿就完毕了,感谢您的阅览,欢迎阅览我的其他文章!