记录一次启动crash排查

2018-11-28  本文已影响16人  站在下一刻

1. 尝试查看手机Crash Logs

当时就觉得应该是传入的参数不合法导致的,然后写了一个NSJSonSerialization的category,覆盖掉dataWithJSONObject,每次返回nil,发现就不crash了,定位到确实是这个方法导致。

1. 尝试hook造成crash的系统方法

  @implementation NSJSONSerialization (ABSExtension)

+ (BOOL)lh_swizzleClassMethod:(SEL)origSel withMethod:(SEL)altSel {
    return [object_getClass((id)self) lh_swizzleMethod:origSel withMethod:altSel];
}

+ (BOOL)lh_swizzleMethod:(SEL)origSel withMethod:(SEL)altSel {
    Method origMethod = class_getInstanceMethod(self, origSel);
    Method altMethod = class_getInstanceMethod(self, altSel);
    if (!origMethod || !altMethod) {
        return NO;
    }
    class_addMethod(self,
                    origSel,
                    class_getMethodImplementation(self, origSel),
                    method_getTypeEncoding(origMethod));
    class_addMethod(self,
                    altSel,
                    class_getMethodImplementation(self, altSel),
                    method_getTypeEncoding(altMethod));
    method_exchangeImplementations(class_getInstanceMethod(self, origSel),
                                   class_getInstanceMethod(self, altSel));
    return YES;
}

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self lh_swizzleClassMethod:@selector(dataWithJSONObject:options:error:) withMethod:@selector(lh_dataWithJSONObject:options:error:)];
    });
}

+ (NSData *)lh_dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError * _Nullable __autoreleasing *)error{
   if (obj && ([obj isKindOfClass:[NSArray class]]||
                [obj isKindOfClass:[NSDictionary class]]||
                [obj isKindOfClass:[NSString class]])) {
        return [self lh_dataWithJSONObject:obj options:opt error:error];
    }else{
        return nil;
    }
}
@end

添加了以上代码后,发现还是发生crash,所以传入的参数应该是合法的,问题还是没有定位到,接着添加NSLog打印所有启动的参数传入,在Devices And Simulators中点击Open Console,发现启动过程的所有调用传入的参数都是合法的,而且数量很多,不知道是哪一条的问题。

3. 添加try catch代码块

+ (NSData *)lh_dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError * _Nullable __autoreleasing *)error{
   NSData *res = nil;
    @try {
        res = [self lh_dataWithJSONObject:obj options:opt error:error];
    } @catch (NSException *exception) {
        NSLog(@"lh -- exception is %@,%@",exception,obj);
    } @finally {
        return res;
    }
}

既然上面步骤已经跟踪到是这个系统方法的问题,就想到加上try catch,这样应该可以抓到异常,同时也可以避免crash,运行了一遍,发现确实走到catch代码块里面,也打印了异常信息和对应传入的参数,最后发现传入的参数是个字典,但是某个key对应的value是个NSNumber,由于通知拉起的跳转逻辑,导致它是NAN,所以不能解析就crash了,然后找到对应的位置,修复了这个问题,最后决定保留这块代码记录一个数据点,上传今后类似异常信息

4.总结

上一篇下一篇

猜你喜欢

热点阅读