为什么80%的码农都做不了架构师?>>>   

先献上PLCrashReporter的github地址:https://github.com/plausiblelabs/plcrashreporter

https://github.com/zh-ios/PLCrashReporter-UM-  注:这个是修改源码后的 pl 已经可以和umeng 共同使用 ,使用的时候 pl 的初始化请放在umeng 后面 , 下载之后编译就能直接拿到可以用的framework 。

一、PL的初始化

 PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];/* pl 的 callbacks */PLCrashReporterCallbacks cb = {.version = 0,.context = (void *) 0xABABABAB,.handleSignal = post_crash_callback};// 设置 pl 的崩溃回调 [crashReporter setCrashCallbacks:&cb];NSError *error;if ([crashReporter hasPendingCrashReport]) {// 处理崩溃信息 [self handleCrashReport];}/** 启动pl 收集崩溃日志功能 */if (![crashReporter enableCrashReporterAndReturnError:&error]) {NSLog(@"Warning: Could not enable crash reporter: %@", error);}/* A custom post-crash callback 在这个回调里面 我们可以处理自己的逻辑 例如:这里我们将页面的访问路径记录在本地以方便崩溃的复现和分析*/static void post_crash_callback (siginfo_t *info, ucontext_t *uap, void *context) {// this is not async-safe, but this is a test implementationNSLog(@"post crash callback: signo=%d, uap=%p, context=%p", info->si_signo, uap, context);// 记录页面访问路径 [[NSUserDefaults standardUserDefaults] setObject:[AHVisitPath deliverUserVisitPath] forKey:@"logsystem_visitpath"];[[NSUserDefaults standardUserDefaults] synchronize];
}

二、将崩溃的数据写入本地的方法

下面的这个方法使用来将崩溃的数据写入到本地。

/*** Write a fatal crash report.** @param sigctx Fatal handler context.* @param crashed_thread The crashed thread.* @param thread_state The crashed thread's state.* @param siginfo The signal information.** @return Returns PLCRASH_ESUCCESS on success, or an appropriate error value if the report could not be written.*/
static plcrash_error_t plcrash_write_report (plcrashreporter_handler_ctx_t *sigctx, thread_t crashed_thread, plcrash_async_thread_state_t *thread_state, plcrash_log_signal_info_t *siginfo) {plcrash_async_file_t file;plcrash_error_t err;/* Open the output file */int fd = open(sigctx->path, O_RDWR|O_CREAT|O_TRUNC, 0644);if (fd < 0) {PLCF_DEBUG("Could not open the crashlog output file: %s", strerror(errno));return PLCRASH_EINTERNAL;}/* Initialize the output context */plcrash_async_file_init(&file, fd, MAX_REPORT_BYTES);/* Write the crash log using the already-initialized writer */err = plcrash_log_writer_write(&sigctx->writer, crashed_thread, sigctx->dynamic_loader, &file, siginfo, thread_state);/* Close the writer; this may also fail (but shouldn't) */if (plcrash_log_writer_close(&sigctx->writer) != PLCRASH_ESUCCESS) {PLCF_DEBUG("Failed to close the log writer");plcrash_async_file_close(&file);return PLCRASH_EINTERNAL;}/* Finished */if (!plcrash_async_file_flush(&file)) {PLCF_DEBUG("Failed to flush output file");plcrash_async_file_close(&file);return PLCRASH_EINTERNAL;}if (!plcrash_async_file_close(&file)) {PLCF_DEBUG("Failed to close output file");return PLCRASH_EINTERNAL;}return err;
}

三、信号异常回调

下面的这个方法则是具体的回调方法里面执行的操作。

/*** @internal** Signal handler callback.*/
static bool signal_handler_callback (int signal, siginfo_t *info, pl_ucontext_t *uap, void *context, PLCrashSignalHandlerCallback *next) {plcrashreporter_handler_ctx_t *sigctx = context;plcrash_async_thread_state_t thread_state;plcrash_log_signal_info_t signal_info;plcrash_log_bsd_signal_info_t bsd_signal_info;/* Remove all signal handlers -- if the crash reporting code fails, the default terminate* action will occur.** NOTE: SA_RESETHAND breaks SA_SIGINFO on ARM, so we reset the handlers manually.* http://openradar.appspot.com/11839803** TODO: When forwarding signals (eg, to Mono's runtime), resetting the signal handlers* could result in incorrect runtime behavior; we should revisit resetting the* signal handlers once we address double-fault handling.*/for (int i = 0; i < monitored_signals_count; i++) {struct sigaction sa;memset(&sa, 0, sizeof(sa));sa.sa_handler = SIG_DFL;sigemptyset(&sa.sa_mask);sigaction(monitored_signals[i], &sa, NULL);}/* Extract the thread state */// XXX_ARM64 rdar://14970271 -- In the Xcode 5 GM SDK, _STRUCT_MCONTEXT is not correctly// defined as _STRUCT_MCONTEXT64 when building for arm64; this requires the pl_mcontext_t// cast.plcrash_async_thread_state_mcontext_init(&thread_state, (pl_mcontext_t *) uap->uc_mcontext);/* Set up the BSD signal info */bsd_signal_info.signo = info->si_signo;bsd_signal_info.code = info->si_code;bsd_signal_info.address = info->si_addr;signal_info.bsd_info = &bsd_signal_info;signal_info.mach_info = NULL;/* Write the report 调用写数据方法,写入崩溃的数据 */if (plcrash_write_report(sigctx, pl_mach_thread_self(), &thread_state, &signal_info) != PLCRASH_ESUCCESS)return false;/* Call any post-crash callback 进行回调  */if (crashCallbacks.handleSignal != NULL)crashCallbacks.handleSignal(info, uap, crashCallbacks.context);}return false;
}

四、崩溃信息的处理。

崩溃信息处理的方式有两种:

1.调用PL自带的方法将崩溃信息解析成文本格式然后再用正则去截取有用的信息。

    PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];NSData *crashData;NSError *error;// Try loading the crash reportcrashData = [crashReporter loadPendingCrashReportDataAndReturnError: &error];if (crashData == nil) {NSLog(@"Could not load crash report: %@", error);[crashReporter purgePendingCrashReport];return;}PLCrashReport *report = [[PLCrashReport alloc] initWithData: crashData error: &error];if (report == nil) {NSLog(@"Could not parse crash report");[crashReporter purgePendingCrashReport];return;}// 崩溃的信息字符串 NSString *crashText = [PLCrashReportTextFormatter stringValueForCrashReport:report withTextFormat:PLCrashReportTextFormatiOS];

上报成功后可以调用下面的这个方法可以将本地的崩溃数据清除掉,以避免重复上报的现象出现。

purgePendingCrashReport

上面代码中的crashText就是崩溃信息的内容,其格式大致如下(和手机里的 device log 日志格式类似):

下面还有好多内容,限于篇幅就截取这么多。

以上的内容是 unCaughtException 收集到的崩溃信息日志,这里直接就有崩溃的堆栈信息(Last Exception Backtrace)。

提醒一下如果是信号异常的话日志的格式如下:

其内容和unCaughtException 最大的区别在于日志里并没有崩溃的堆栈信息 取而代之的是崩溃时的线程信息(也有崩溃时的偏移量和基地址),我们可以把崩溃时的线程信息当做堆栈来解析崩溃信息。

2.第二种方法是根据崩溃信息调用 PLCrashReportTextFormatter 这个类中的方法自己去解析数据。

第一种方法获取到的是 完成体 ,崩溃信息拼接好后的字符串, 第二种方法就可以更细粒度的获取崩溃的信息,如崩溃的 title reason 堆栈等都可以单独的获取到 。

以上就是PL的基本使用,功能强大而又开源的PL 你值得拥有。

转载于:https://my.oschina.net/zhxx/blog/875092

PLCrashReporter的使用相关推荐

  1. PLCrashReporter使用

    在didFinishLaunchingWithOptions里面调用init_crash_reporter.如果直接上传崩溃文件好查看些,要转换就麻烦了. void save_crash_report ...

  2. 【转】iOS实时卡顿监控

    转自http://www.tanhao.me/code/151113.html/ 在移动设备上开发软件,性能一直是我们最为关心的话题之一,我们作为程序员除了需要努力提高代码质量之外,及时发现和监控软件 ...

  3. 检测iOS的APP性能的一些方法

    首先如果遇到应用卡顿或者因为内存占用过多时一般使用Instruments里的来进行检测.但对于复杂情况可能就需要用到子线程监控主线程的方式来了,下面我对这些方法做些介绍: Time Profiler ...

  4. iOS之性能优化·优化App界面的渲染与流畅度

    一.界面渲染流程 ① 渲染流程分析 计算机中的显示过程通常是通过 CPU.GPU.显示器协同工作来将图片显示到屏幕上,如下图所示: 苹果为了解决图片撕裂的问题使用了 VSync + 双缓冲区的形式,就 ...

  5. 手游频繁崩溃”闪退”? 从程序上找原因

    手游频繁崩溃"闪退"? 从程序上找原因 作为玩家,当游戏crash的时候是什么心情,如果这个游戏玩起来还不错的话,那我可能还会打开第二次,如果这个游戏一般的话我可能直接怒删了.当多 ...

  6. 捕获系统异常崩溃的方法

    2019独角兽企业重金招聘Python工程师标准>>> 1.使用PLCrashReporter框架 PLCrashReporterConfig *config = [[PLCrash ...

  7. RunLoop总结:RunLoop的应用场景(四)

    今天要介绍的RunLoop使用场景非常有意思,在做长期项目.须要跟踪解决用户问题非常实用. 使用RunLoop 监測主线程的卡顿,并将卡顿时的线程堆栈信息保存下来,下次上传到服务器. 參考资料 关于今 ...

  8. 漫谈iOS Crash收集框架

    为了能够第一时间发现程序问题,应用程序需要实现自己的崩溃日志收集服务,成熟的开源项目很多,如 KSCrash,plcrashreporter,CrashKit 等.追求方便省心,对于保密性要求不高的程 ...

  9. iOS 之如何利用 RunLoop 原理去监控卡顿?

    [CSDN 编者按]简单来说APP卡顿,就是FPS达不到60帧率,丢帧现象,就会卡顿,但是很多时候,我们只知道丢帧了,具体为什么丢帧,却不是很清楚,那么我们要怎么监控呢? 作者 | 枫叶无处漂泊    ...

  10. iOS平台一套完善的Crash Report解决方案

    原文:http://blog.csdn.net/langresser_king/article/details/8593845 最开始想iOS和Android都做了,后面尝试了下android上面的崩 ...

最新文章

  1. 使用canvas操作图像
  2. 多维矩阵/数组变成一维数组
  3. JStorm与Storm源码分析(五)--SpoutOutputCollector与代理模式
  4. 被墙怎么搭建安卓开发环境
  5. 图解 Java 线程的生命周期,看完再也不怕面试官问了
  6. yarn add webpack webpack-cli 报错
  7. 【转】SOAR从概念到落地
  8. 钢琴块2电脑版_快陪练教师端电脑版下载_快陪练教师端pc版免费下载[在线教学]...
  9. java数据库程序实例_Java连接各种数据库的实例大全
  10. 大屏设计-大数据综合展示可视化平台
  11. php顶级框架,10个顶级PHP开源项目「2019」
  12. xmind8 安装方法(old)
  13. C#与SQL实现医院信息管理系统
  14. 孢子社群:今日推荐人工智能微信群:TensorflowNews.com 9群
  15. 提高MySQL微信三公源码的7个技巧
  16. python datetime计算时间差_python计算时间差的方法
  17. mezzanine 历险记
  18. 金蝶erp系统服务器端,金蝶ERP软件二次开发.doc
  19. html 标准通用标记语言下,HTML超文本标记语言常用的一些标签
  20. matlab 根式化简,薛定宇教授大讲堂(卷Ⅳ):MATLAB最优化计算最新章节_薛定宇著_掌阅小说网...

热门文章

  1. Pandas读取excel中的数据,并利用现有列数据生成新列
  2. 【linux系统学习笔记】运行startx后Ubuntu密码正确进不去的问题
  3. PSP模块Tensorflow/Pytorch实现小结
  4. 【LeetCode】【字符串】题号:*551. 学生出勤记录 I
  5. 从零基础入门Tensorflow2.0 ----六、32cifar10数据训练
  6. 从零基础入门Tensorflow2.0 ----五、21交叉特征实战
  7. Java之strictfp关键字
  8. linux下压缩解压缩见解
  9. kubernetes集群搭建(二进制方式)
  10. 别再写 main 方法测试了,太 Low,这才是专业 Java 测试方法