NSSetUncaughtExceptionHandler收集崩溃日志并分析

来源:互联网 发布:盗版游戏 知乎 编辑:程序博客网 时间:2024/06/05 08:03

1. 在代码中添加手机崩溃日志代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);    [self updateAppErrorInfo];    return YES;}#pragma mark    //如果有异常崩溃信息,提交异常- (void)updateAppErrorInfo{    NSDictionary * dictionary = [NUD objectForKey:Sandbox_appErrorInfo];    DLog(@"dictionary==%@",dictionary);    //如果有异常崩溃信息,提交异常    if (dictionary&&NotNilAndNull(dictionary[@"content"]))    {        static NSString *AppErrorBaseHostURL   =    @"http://:8080/appmanage/";//提交到自己的日志平台        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];        NSString * urlString   =   [[NSString stringWithFormat:@"%@%@",AppErrorBaseHostURL,@"/app/appErrorInfo/add"]stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];        NSURL *URL = [NSURL URLWithString:urlString];        manager.requestSerializer.timeoutInterval = 5.f;   //请求时间        manager.requestSerializer   =   [AFHTTPRequestSerializer serializer];        manager.responseSerializer  =   [AFHTTPResponseSerializer serializer];        [manager POST:URL.absoluteString parameters:dictionary progress:^(NSProgress * _Nonnull downloadProgress) {        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {            NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil];            DLog(@"dic=========%@",dic);            if ([dic[@"success"] isEqualToString:@"0"]) {                [NUD removeObjectForKey:Sandbox_appErrorInfo];            }        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {        }];    }}#pragma mark    收集异常,存储到本地,下次用户打开程序时上传给我们void UncaughtExceptionHandler(NSException *exception) {    /**     *  获取异常崩溃信息     */    NSArray *callStack = [exception callStackSymbols];    NSString *reason = [exception reason];    NSString *name = [exception name];    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];    NSString * dateStr = [formatter stringFromDate:[NSDate date]];    NSString * userID   =   [NUD objectForKey:USERID];    NSString * userName =   [NUD objectForKey:USERNAME];    NSString * iOS_Version = [[UIDevice currentDevice] systemVersion];    NSString * PhoneSize    =   NSStringFromCGSize([[UIScreen mainScreen] bounds].size);    NSString * App_Version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];    NSString * iPhoneType = [RSToolNSObject getiPhoneType];    NSString *content = [NSString stringWithFormat:@"%@<br>\niOS_Version : %@----PhoneSize : %@<br>\n----iPhoneType: %@<br>\nApp_Version : %@<br>\nuserID : %@<br>\nuserName : %@<br>\nname:%@<br>\nreason:\n%@<br>\ncallStackSymbols:\n%@",dateStr,iOS_Version,PhoneSize,iPhoneType,App_Version,userID,userName,name,reason,[callStack componentsJoinedByString:@"\n"]];#if DEBUG    NSDictionary * dictionary   =   @{@"content":content,                                      @"isDebug":@(1),                                      @"packageName":@"com.thinkjoy.NetworkTaxiDriver"};#else    NSDictionary * dictionary   =   @{@"content":content,                                      @"isDebug":@(0),                                      @"packageName":@"com.thinkjoy.NetworkTaxiDriver"};#endif    [NUD setObject:dictionary forKey:Sandbox_appErrorInfo];}#pragma mark 获得设备型号+ (NSString *)getiPhoneType{    struct utsname systemInfo;    uname(&systemInfo);    NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];    if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";    if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";    if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";    if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";    if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4";    if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4";    if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";    if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5";    if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5";    if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c";    if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c";    if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s";    if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s";    if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";    if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6";    if ([platform isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";    if ([platform isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";    if ([platform isEqualToString:@"iPhone8,4"]) return @"iPhone SE";    if ([platform isEqualToString:@"iPhone9,1"]) return @"iPhone 7";    if ([platform isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";    if ([platform isEqualToString:@"iPod1,1"])   return @"iPod Touch 1G";    if ([platform isEqualToString:@"iPod2,1"])   return @"iPod Touch 2G";    if ([platform isEqualToString:@"iPod3,1"])   return @"iPod Touch 3G";    if ([platform isEqualToString:@"iPod4,1"])   return @"iPod Touch 4G";    if ([platform isEqualToString:@"iPod5,1"])   return @"iPod Touch 5G";    if ([platform isEqualToString:@"iPad1,1"])   return @"iPad 1G";    if ([platform isEqualToString:@"iPad2,1"])   return @"iPad 2";    if ([platform isEqualToString:@"iPad2,2"])   return @"iPad 2";    if ([platform isEqualToString:@"iPad2,3"])   return @"iPad 2";    if ([platform isEqualToString:@"iPad2,4"])   return @"iPad 2";    if ([platform isEqualToString:@"iPad2,5"])   return @"iPad Mini 1G";    if ([platform isEqualToString:@"iPad2,6"])   return @"iPad Mini 1G";    if ([platform isEqualToString:@"iPad2,7"])   return @"iPad Mini 1G";    if ([platform isEqualToString:@"iPad3,1"])   return @"iPad 3";    if ([platform isEqualToString:@"iPad3,2"])   return @"iPad 3";    if ([platform isEqualToString:@"iPad3,3"])   return @"iPad 3";    if ([platform isEqualToString:@"iPad3,4"])   return @"iPad 4";    if ([platform isEqualToString:@"iPad3,5"])   return @"iPad 4";    if ([platform isEqualToString:@"iPad3,6"])   return @"iPad 4";    if ([platform isEqualToString:@"iPad4,1"])   return @"iPad Air";    if ([platform isEqualToString:@"iPad4,2"])   return @"iPad Air";    if ([platform isEqualToString:@"iPad4,3"])   return @"iPad Air";    if ([platform isEqualToString:@"iPad4,4"])   return @"iPad Mini 2G";    if ([platform isEqualToString:@"iPad4,5"])   return @"iPad Mini 2G";    if ([platform isEqualToString:@"iPad4,6"])   return @"iPad Mini 2G";    if ([platform isEqualToString:@"i386"])      return @"iPhone Simulator";    if ([platform isEqualToString:@"x86_64"])    return @"iPhone Simulator";    return platform;}

2. 收集到的崩溃日志如下

name:NSInvalidArgumentException<br>reason:*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]<br>callStackSymbols:0   CoreFoundation                      0x2141a303 <redacted> + 1501   libobjc.A.dylib                     0x20be6dff objc_exception_throw + 382   CoreFoundation                      0x21337e2b <redacted> + 3423   CoreFoundation                      0x21337caf <redacted> + 504   NetworkTaxiDriver                   0x0012ff29 NetworkTaxiDriver + 3233695   NetworkTaxiDriver                   0x0013019f NetworkTaxiDriver + 3239996   UIKit                               0x25695d29 <redacted> + 29767   UIKit                               0x2569507b <redacted> + 3788   UIKit                               0x2569c995 <redacted> + 3289   UIKit                               0x25735f45 <redacted> + 48810  NetworkTaxiDriver                   0x0013013b NetworkTaxiDriver + 32389911  UIKit                               0x255b1d79 <redacted> + 102812  UIKit                               0x255b1959 <redacted> + 2413  UIKit                               0x2566f4d5 <redacted> + 28014  UIKit                               0x2566e8e5 <redacted> + 9615  UIKit                               0x2566e51b <redacted> + 83416  UIKit                               0x2566e16d <redacted> + 5217  UIKit                               0x2566e0e7 <redacted> + 21418  UIKit                               0x255ada83 <redacted> + 71419  QuartzCore                          0x23689ad5 <redacted> + 12820  QuartzCore                          0x236851d1 <redacted> + 35221  QuartzCore                          0x23685061 <redacted> + 1622  QuartzCore                          0x23684581 <redacted> + 36823  QuartzCore                          0x23684233 <redacted> + 61424  UIKit                               0x255b08d7 <redacted> + 551825  CoreFoundation                      0x213dd257 <redacted> + 1426  CoreFoundation                      0x213dce47 <redacted> + 45427  CoreFoundation                      0x213db1af <redacted> + 80628  CoreFoundation                      0x2132dbb9 CFRunLoopRunSpecific + 51629  CoreFoundation                      0x2132d9ad CFRunLoopRunInMode + 10830  GraphicsServices                    0x225a7af9 GSEventRunModal + 16031  UIKit                               0x25619fb5 UIApplicationMain + 14432  NetworkTaxiDriver                   0x0013f46d NetworkTaxiDriver + 38615733  libdyld.dylib                       0x20fe0873 <redacted> + 2
dSYM符号表获取

xcode->window->organizer->右键你的应用 show finder->右键.xcarchive 显示包内容->dSYMs->test.app.dYSM

atos命令

atos命令来符号化某个特定模块加载地址
atos [-arch 架构名] [-o 符号表] [-l 模块地址] [方法地址]

使用终端计算
1.没有模块地址,需要自己计算。
4   NetworkTaxiDriver                   0x00116f29 NetworkTaxiDriver + 323369
0x00116f29 = 1142569;   //将方法地主转化为十进制1142569-323369 = 819200;//减去偏移地址,得到模块地址819200 = 0xc8000;  //得到的模块地址在转为十六进制

终端示例:

//打开文件cd /Users/thinkjoy/Desktop/出租车/出租车V1.6崩溃分析/NetworkTaxiDriver.app.dSYM //根据模块地址和方法地址计算问题代码位置atos -arch armv7 -o /Users/thinkjoy/Desktop/出租车/出租车V1.6崩溃分析/NetworkTaxiDriver.app.dSYM/Contents/Resources/DWARF/NetworkTaxiDriver -l 0xc8000 0x00116f29//问题代码的位置-[RSUserMessageVC messageListAry] (in NetworkTaxiDriver) (RSUserMessageVC.m:54)thinkjoytekiMacBook-Pro:NetworkTaxiDriver.app.dSYM thinkjoy$

注意:使用armv7arm64定位到的代码完全不同。

2.有模块地址,可以直接计算。
test 0x00000001018157dc 0x100064000 + 24844252

0x00000001018157dc代码地址,0x100064000模块地址;


原创粉丝点击