ios Crash闪退日志获取和上传至服务器

最近客户有个要求:人家谁谁有crash日志捕获和上传,我们是不是也要做一个...  人家谁谁.....还有什么什么功能........

正好最近也在研究这方面东东,所以整理一下分享给大家:如何用程序获取Crash日志 并 可以上传Crash日志。

首先我们整理经常会闪退的异常哪些:数组越界、空引用、引用未定义方法、内存空间不足等等。

友盟分享后台是可以看到crash的日志,如下图:

开始研究的时候,我有两个疑问:

1.如何获取crash闪退日志(工具和程序两种方法);

2.解析crash;

说明:这里说的crash日志不是在联调的情况下(是生产环境,通俗的说就是发布了的产品)。

如何获取crash闪退日志 -- 工具查看

先看第一个问题如何查看,我搜索的方法有以下几个:

第一个方法:XCode  的菜单Window->Organizer    选择Devices  ->  选中的手机 -> 点击手机名称左边的箭头 会等到如下图

注意对比一下红色框框内容,这个日志也基本上上告诉你crash的原因了。

第二种方法 打开手机 - > 设置 -> 通用 - > 关于本机 - > 诊断与用量 - > 诊断与用量数据  这里面就是所有应用的Crash日志。

第三种方法 通过iTunes Connect(Manage Your Applications - View Details - Crash Reports)获取用户的crash日志。方法很多这里不多列了。

解析crash

参见:http://stackoverflow.com/questions/1460892/symbolicating-iphone-app-crash-reports )

用程序获取crash日志

但是这里都是工具,没有用到程序获取,经过千方百计的查询(思路是:先找到存放crash的iphone系统路径:var/mobile/Library/Logs/CrashReporter)找到了crash存放的路径,唉,苦于无法读取(用程序读出来都是nil),当然如果是越狱手机就不一样是可以读取的。这个思路断掉了。

换个思路:自己用程序捕获crash,保存到本地可以吗?这么一试,果然........

第一步:新建一个继承自NSObject的类(Xcode新建一个空项目过程略),取名字CatchCrash,在h和m文件中写下:

.h文件

  1. #import <Foundation/Foundation.h>
  2. @interface CatchCrash : NSObject
  3. void uncaughtExceptionHandler(NSException *exception);
  4. @end

.m文件

  1. #import "CatchCrash.h"
  2. @implementation CatchCrash
  3. void uncaughtExceptionHandler(NSException *exception)
  4. {
  5. // 异常的堆栈信息
  6. NSArray *stackArray = [exception callStackSymbols];
  7. // 出现异常的原因
  8. NSString *reason = [exception reason];
  9. // 异常名称
  10. NSString *name = [exception name];
  11. NSString *exceptionInfo = [NSString stringWithFormat:@"Exception reason:%@\nException name:%@\nException stack:%@",name, reason, stackArray];
  12. NSLog(@"%@", exceptionInfo);
  13. NSMutableArray *tmpArr = [NSMutableArray arrayWithArray:stackArray];
  14. [tmpArr insertObject:reason atIndex:0];
  15. //保存到本地  --  当然你可以在下次启动的时候,上传这个log
  16. [exceptionInfo writeToFile:[NSString stringWithFormat:@"%@/Documents/error.log",NSHomeDirectory()]  atomically:YES encoding:NSUTF8StringEncoding error:nil];
  17. }
  18. @end

第二步:添加一个继承自UIViewcontroller的类,取名字为TestViewController。

第三步:注册CatchCrash异常处理方法,在Appdelegate写下如下代码:

  1. #import "AppDelegate.h"
  2. #import "CatchCrash.h"
  3. #import "TestViewController.h"
  4. @implementation AppDelegate
  5. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  6. {
  7. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  8. // Override point for customization after application launch.
  9. //注册消息处理函数的处理方法
  10. NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
  11. TestViewController *testVc = [[TestViewController alloc] init];
  12. self.window.rootViewController = testVc;
  13. self.window.backgroundColor = [UIColor whiteColor];
  14. [self.window makeKeyAndVisible];
  15. return YES;
  16. }

第四部:在TestViewController的Xib上面添加一个按钮并给其添加一个单击事件,TestViewController.m文件中有如下代码:

  1. #import "TestViewController.h"
  2. @interface TestViewController ()
  3. @end
  4. @implementation TestViewController
  5. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  6. {
  7. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  8. if (self) {
  9. // Custom initialization
  10. }
  11. return self;
  12. }
  13. - (void)viewDidLoad
  14. {
  15. [super viewDidLoad];
  16. // Do any additional setup after loading the view from its nib.
  17. }
  18. - (void)didReceiveMemoryWarning
  19. {
  20. [super didReceiveMemoryWarning];
  21. // Dispose of any resources that can be recreated.
  22. }
  23. #pragma mark - 单击事件
  24. - (IBAction)crashTapped:(id)sender
  25. {
  26. //常见异常1---不存在方法引用
  27. //    [self performSelector:@selector(thisMthodDoesNotExist) withObject:nil];
  28. //常见异常2---键值对引用nil
  29. //    [[NSMutableDictionary dictionary] setObject:nil forKey:@"nil"];
  30. //常见异常3---数组越界
  31. [[NSArray array] objectAtIndex:1];
  32. //常见异常4---memory warning 级别3以上
  33. //    [self performSelector:@selector(killMemory) withObject:nil];
  34. //其他大家去想吧
  35. }
  36. #pragma mark - custom method
  37. - (void) killMemory
  38. {
  39. for (int i = 0; i < 300; i ++)
  40. {
  41. UILabel *tmpLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
  42. tmpLabel.layer.masksToBounds = YES;
  43. tmpLabel.layer.cornerRadius = 10;
  44. tmpLabel.backgroundColor = [UIColor redColor];
  45. [self.view addSubview:tmpLabel];
  46. }
  47. }
  48. @end

运行代码:可以看到闪退,导出error日志,我们可以看到:

  1. Exception reason:NSRangeException
  2. <span style="color:#FF0000;">Exception name:*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds for empty array</span>
  3. Exception stack:(
  4. 0   CoreFoundation                      0x2f2edfeb <redacted> + 154
  5. 1   libobjc.A.dylib                     0x39b66ccf objc_exception_throw + 38
  6. 2   CoreFoundation                      0x2f224a89 <redacted> + 176
  7. <span style="color:#FF0000;"> 3   TestCrash                           0x000e8077 -[TestViewController crashTapped:] + 126</span>
  8. 4   UIKit                               0x31b3f057 <redacted> + 90
  9. 5   UIKit                               0x31b3eff7 <redacted> + 30
  10. 6   UIKit                               0x31b3efd1 <redacted> + 44
  11. 7   UIKit                               0x31b2a737 <redacted> + 374
  12. 8   UIKit                               0x31b3ea4f <redacted> + 590
  13. 9   UIKit                               0x31b3e721 <redacted> + 528
  14. 10  UIKit                               0x31b396eb <redacted> + 758
  15. 11  UIKit                               0x31b0e8ed <redacted> + 196
  16. 12  UIKit                               0x31b0cf97 <redacted> + 7102
  17. 13  CoreFoundation                      0x2f2b925b <redacted> + 14
  18. 14  CoreFoundation                      0x2f2b872b <redacted> + 206
  19. 15  CoreFoundation                      0x2f2b6f1f <redacted> + 622
  20. 16  CoreFoundation                      0x2f221f0f CFRunLoopRunSpecific + 522
  21. 17  CoreFoundation                      0x2f221cf3 CFRunLoopRunInMode + 106
  22. 18  GraphicsServices                    0x3417a663 GSEventRunModal + 138
  23. 19  UIKit                               0x31b6d16d UIApplicationMain + 1136
  24. 20  TestCrash                           0x000e810d main + 116
  25. 21  libdyld.dylib                       0x3a073ab7 <redacted> + 2
  26. )
时间: 2024-11-07 03:33:47

ios Crash闪退日志获取和上传至服务器的相关文章

iOS Crash闪退信息捕获工具类

IOS SDK中提供了一个现成的函数 NSSetUncaughtExceptionHandler 用来做异常处理,但功能非常有限,而引起崩溃的大多数原因如:内存访问错误,重复释放等错误捕获不到,因为这些异常抛出的是Signal,所以必须要专门做Signal处理.工具类的实现源码如下: 头文件 #import <Foundation/Foundation.h> extern NSString *const UncaughtExceptionHandlerSignalKey; extern NSS

iOS闪退日志的收集和解析

在开发过程中往往会遇见有个别用户或者测试人员反馈app的闪退现象,而项目一般集成的统计闪退的第三方库是笼统的统计了所有的闪退信息,无法去定位某一个用户提出的某一个时间点的某一个闪退问题,于是乎这个时候需要我们能快速的去获取指定用户提出的指定闪退,并能够解析闪退日志,快速的定位到问题.下面将自己的做法大概的做个总结(可能还有别的方法,但是我觉得下面讲述的方法已经足够了). 一.收集闪退日志 先和用户确定iPhone是否打开如下设置(以iOS12.0的iPhone为参考): 设置->隐私->分析-

iOS开发-闪退问题-解决之前上架的 App 在 iOS 9 会闪退问题

最新更新:(2015.10.02) 开发环境: Delphi 10 Seattle OS X El Capitan v10.11 需使用下列 HotfixID: 30398, PAServer Hotfix for Delphi, C++Builder and RAD Studio 10 Seattle Xcode v7.0.1 iOS SDK v9.0 真机测试(以下机种皆不闪退): iPhone 3GS v6.1.2 (32 bit) iPhone 4 v7.1.2 (32 bit) iPh

HTML5网页录音和上传到服务器,支持PC、Android,支持IOS微信

准备做一个网页版聊天界面,表情啊.图片啊.上传文件啊都应该要有,视频就算了,语音还是要的. 本文记录的是在网页上用GitHub上的Recorder进行在线录音和上传到服务器. 录音代码 本示例代码支持PC.Android.IOS(仅Safari)中使用,如果用RecordApp可增加对IOS(微信浏览器.小程序)的支持. 看万遍代码不如行动一遍,新建一个html文件,把下面三段代码复制到文件内,双击浏览器打开就能进行测试. <!-- 先加载js录音库,注意:你应该把js clone到本地使用 -

将android客户端的错误日志压缩上传到服务器

原文:将android客户端的错误日志压缩上传到服务器 源代码下载地址:http://www.zuidaima.com/share/1550463760370688.htm

避免SIGPIPE导致的iOS应用闪退/Avoiding SIGPIPE signal crash in iOS(mach_msg_trap、SIGPIPE信号)

问题描述: 应用运行时,锁屏后再打开有一定几率闪退.通过真机调试发现程序会中断在此处: libsystem_kernel.dylib`mach_msg_trap: 解决思路: 通过这篇文章了解是进程收到 SIGPIPE  信号,该信号默认行为是终止进程. The process received a SIGPIPE . The default behaviour for this signal is to end the process. A SIGPIPE is sent to a proce

iOS视频压缩存储至本地并上传至服务器-b

最近做了一个项目,我把其中的核心功能拿出来和大家分享一下,重点还是自己梳理一下. 这里关于视频转码存储我整理了两个方法,这两个方法都是针对相册内视频进行处理的. 1.该方法没有对视频进行压缩,只是将视频原封不动地从相册拿出来放到沙盒路径下,目的是拿到视频的NSData以便上传 这里我传了一个URL,这个URL有点特别,是相册文件URL,所以我说过只针对相册视频进行处理 //将原始视频的URL转化为NSData数据,写入沙盒     + (void)videoWithUrl:(NSString *

iOS视频压缩存储至本地并上传至服务器

最近做了一个项目,我把其中的核心功能拿出来和大家分享一下,重点还是自己梳理一下. 这里关于视频转码存储我整理了两个方法,这两个方法都是针对相册内视频进行处理的. 1.该方法没有对视频进行压缩,只是将视频原封不动地从相册拿出来放到沙盒路径下,目的是拿到视频的NSData以便上传 这里我传了一个URL,这个URL有点特别,是相册文件URL,所以我说过只针对相册视频进行处理 //将原始视频的URL转化为NSData数据,写入沙盒 + (void)videoWithUrl:(NSString *)url

iOS Crash获取闪回日志和上传server

首先我们整理常常会闪退的异常哪些:数组越界.空引用.引用没有定义方法.内存空间不足等等. 怎样获取crash闪退日志 -- 工具查看 先看第一个问题怎样查看,我搜索的方法有下面几个: 第一个方法:XCode  的菜单Window->Organizer    选择Devices  ->  选中的手机 -> 点击手机名称左边的箭头 会等到例如以下图 注意对照一下红色框框内容,这个日志也基本上上告诉你crash的原因了. 另外一种方法 打开手机 - > 设置 -> 隐私 - >