前言 上一篇给大家介绍了Android Crash中的Java Crash分析,我们可以知道Java Crash一般会弹出提示框告诉我们程序崩溃了,通常使用Crash工具都能够捕获到;本篇博客来谈谈如何针对 Native Crash进行分析,它相对与Java层面的Crash有什么特点? 上一节我们谈到so库是同通过Native语言开发的,自然在Android中使用so库的时候发生的Crash,就是我们所说的Native Crash。 Native Crash如何分析? 既然要分析就必须找到可以分析的东西,我们在分析Java层Crash的时候是通过logcat日志找到对应的出错代码,然而Native层Crash也是可以logcat日志来进行分析的。
本系列博文主要是想跟大家分享一下在Android平台中如何进行Crash分析并解决问题并告诉大家如何通过bugly进行崩溃捕获快速定位问题。 什么是Crash? 这里我们进行一些概念上的普及: Crash就是由于代码异常而导致App非正常退出现象,也就是我们常说的『崩溃』 Android中有哪些类型Crash 通常情况下会有以下两种类型Crash: Java Crash Native Crash 本篇先探讨Java Crash,Native Crash我们会在下一篇重点讨论。 通过Crash堆栈信息定位问题 上面就是一个很简单的Crash啦,相信很多同学在开发过程中一定遇到过这种情况,万恶的空指针啊,啊,啊。我们来看看logcat给我们输出的堆栈信息: ? 想了解更多内容,敬请关注下一篇『Android Crash之Native Crash分享』。
热卖云产品年终特惠,2核2G轻量应用服务器7.33元/月起,更多上云必备产品助力您轻松上云
1、手动捕捉crash 即使有了bugly,也需要知道奔溃是如何捕捉的。 注意:自定义NSSetUncaughtExceptionHandler之后,会导致bugly失效,需要注意!! //crash奔溃的处理 exception_init(); } void exception_init(void) { // _objc_terminate是一个函数指针 old_terminate = std::set_terminate(&_objc_terminate); } //系统出现crash都会来到这个函数 static void _objc_terminate
欢迎大家关注他的博客——开源实验室(点击原文链接可以直接访问) 在 Android 平台上,Native Crash 一直是比较麻烦的问题,因为捕获麻烦,获取到了内容又不全,内容全了信息又不对,信息对了又不好处理 比 Java Crash 不知道麻烦多少倍。 今天跟大家讲一下,我最近掉了几百根头发写出来的一个 Native Crash 收集的功能(脱发已经越来越严重了)。 一个 Native Crash 的 log 信息如下图: ? 这张图是我在网上找的(由于没有写 demo,项目中的截图不方便直接拿出来,就偷了个懒)。 要实现 Native Crash 的收集,主要有四个重点:知道 Crash 的发生;捕获到 Crash 的位置;获取 Crash 发生位置的函数调用栈;数据能回传到服务器。 知道 Crash 的发生 与 Java 平台不同,C/C++ 没有一个通用的异常处理接口,在 C 层,CPU 通过异常中断的方式,触发异常处理流程。
用户在使用App的过程中,经常遇到闪退的情况,体验不太好,本文尝试探索引发闪退的原因,以及在遇到crash的情况下,尽可能的保持程序运行,并及时上报错误。 一、crash类型 1.OC层面的crash 1.1 普通类型 NSInvalidArgumentException:非法参数异常,传入非法参数导致异常,nil参数比较常见。 2.Signal层面的crash 除了OC层面的异常捕获之外,很多内存错误、访问错误的地址产生的crash则需要利用unix标准的signal机制,注册SIGABRT, SIGBUS, SIGSEGV等信号发生时的处理函数 二、存在问题 程序闪退,用户体验不好 三、监听crash 1.任凭程序闪退并上报 1.1 NSSetUncaughtExceptionHandler 捕获OC层面的crash 参考文章 (1)AppDelegate 自动修复+捕获上报 2.1 针对普通类型Crash的处理机制 hook相关的方法,增加保护机制。
背景 分享一些过去两个月遇到的crash。 根据堆栈信息和日志信息,可以找到用户操作路径,是通过scheme进入分类; 但是直接用真机复现,相同的操作并不会导致crash; 通过分析crash出现的机型和系统特征,发现都是iOS 13以下系统 这段HTML文本在转码的时候会同步对图片资源进行加载,导致线程阻塞,如果阻塞时间过长,还会引发crash。 堆栈如下: ? 堆栈关键信息:dispatch_gate_wait_slow; 注意到上图,crash的是子线程,这时候要习惯性看看主线程在处理什么逻辑: ? 但是使用不当的时候,weak指针也很容易造成crash,如下图: ?
当某个进程发生crash时会出现下面的错误日志,它可能出现在logcat日志或者/data/tombstones目录下的tombstone文件中 --------- beginning of crash Crash dumps 如果当前你没有一个正在研究的crash例子,Android系统源代码中提供了一个用于测试debuggerd的工具,叫做crasher。 一般地,natvie crash日志是以字符串"*** ***"起始。 Build fingerprint:'xxxx' Fingerprint 信息用于辨别发生crash的编译版本。 其中,Linux 专门提供了一类 crash 信号,在程序接收到此类信号时,缺省操作是将 crash 的现场信息记录到 core 文件,然后终止进程。 这部分显示程序发生crash时刻寄存器地址附近的内存信息。通常,检查内存信息能够进一步定位发生crash的原因。
crash>log .... [23680089.192513] NMI watchdog: BUG: soft lockup - CPU#11 stuck for 22s! [filebeat:47277] .... crash> runq .... ... 计算截止重启时刻cpu12 多长时间未发生调度: crash> eval 23680089192515189-23680067820641540 hexadecimal: 4f9dce971 > pd 21371873649/1000000000 $1 = 21 crash> eval 21371873649/1000000000 hexadecimal: 15 decimal: 21 octal: 25 binary: 0000000000000000000000000000000000000000000000000000000000010101 crash>
在工作中经常会遇到一些内核crash的情况,本文就是根据内核出现crash后的打印信息,对其进行了分析,使用的内核版本为:Linux2.6.32。
出现问题是,数据库先是被置为只读,然后过了一段时间,MySQL直接Crash掉了,发生Crash时MySQL的error日志中打印了以下内容: ? 首先数据库变成了只读,最后数据库Crash了,Crash输出的信息如下: ? InnoDB: Error: semaphore wait has lasted > 600 seconds 提示600秒没有响应 数据库选择了Crash 强制重启。 Latch没有释放,update迟迟竞争不到RW-latch 3,Innodb 的Diagnostic线程检查到RW-Latch等待超过了600秒还没有返回,认为系统出现了严重问题,于是触发了MySQL服务的Crash
背景 版本发布后,收集到到异常上报,有部分记录到是native crash。 而上报的native信息,无法直接定位到错误位置。 解决方案: 一,针对可以复现到场景 1,本地debug版本进行复现,crash复现后找到debug版本的so文件(debug版本的so包含调试信息) $ find . arm-linux-androideabi-addr2line 路径 NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin 二,针对发版后的crash 这样在发生crash时候,才能通过归档的so文件来定位到具体的crash位置。
一、准备环境 1)获取crash工具。注意区分版本(arm/arm64/x86_64)。 2)获取对应软件版本的符号表文件(如vmlinux),可以将该文件放置 crash工具同一目录下。 .* > sysdump.core 4)使用crash工具解析之前生成出来的sysdump.core文件: crash_arm -m phys_base=0x80000000 vmlinux sysdump.core 或:crash vmlinux sysdump.core 二、crash常见命令 分析sysdump的入口界面如下(包括panic描述及PID等): XXXX/demo$ . /crash_arm64 vmlinux sysdump.core crash_arm64 7.2.3++ Copyright (C) 2002-2017 Red Hat, Inc. crash_arm64> 其中经常用的有:log,ps,sys,mount,sym,rd/wr,bt等。 1)使用sys命令查看系统概况。
当app发生crash时会产生crash report,这对我们定位crash的原因非常有帮助。该篇重点介绍了如何符号化、看懂并解析一篇crash Report。 所以你应当仔细研读这些crash report,去了解你的app究竟发生的是哪种crash,并尝试修复它们。 Crash Report,尤其是堆栈信息,在被符号化之前是不可读的。 App Store在符号化crash report后会把内部所有的crash reports做汇总并分组,这种聚合(相似crash report)的方法叫做crash聚类。 一个部分符号化的crash report也许包含了可以理解crash的信息,这取决于crash的类型和哪一部分被成功符号化了。一个未符号化的crash report用处有限。 所以你只需要把crash report加到Xcode Organizer就可以了。 Note:Xcode只认.crash后缀的crash report。
First, we do not pretend here that we will cover everything that is important fo...
当app发生crash时会产生crash report,这对我们定位crash的原因非常有帮助。该篇重点介绍了如何符号化、看懂并解析一篇crash Report。 所以你应当仔细研读这些crash report,去了解你的app究竟发生的是哪种crash,并尝试修复它们。 Crash Report,尤其是堆栈信息,在被符号化之前是不可读的。 App Store在符号化crash report后会把内部所有的crash reports做汇总并分组,这种聚合(相似crash report)的方法叫做crash聚类。 9. 一个部分符号化的crash report也许包含了可以理解crash的信息,这取决于crash的类型和哪一部分被成功符号化了。一个未符号化的crash report用处有限。 ? 所以你只需要把crash report加到Xcode Organizer就可以了。 Note:Xcode只认.crash后缀的crash report。
Crash 信息 Last Exception : 0 libobjc.A.dylib 0x00000001bee86f40 _objc_msgSend + 32 1 0x1a9e43fff arm64 <309485b32e2c3803ae988866d303d7fd> libAccessibility.dylib libAccessibility 在发送通知时产生了 Crash 复现场景 在某些路径可以复现 Crash: 这里取出对象 isa 中的 class 对象 PAC 验签后使用,在 _objc_msgSend + 32 寻址时 Crash,是典型的对象内存管理异常问题 有些奇怪,向上分析成本太高,直接开启 Zombie 试图去找到这个 Crash 的对象及其产生时机。 寻找 Crash 对象 开启 Zombie 后果然轻松复现: -[UILabel _accessibilityButtonShapesChangedNotification:]: message sent
crash> struct mutex ffffffffc05f1000 struct mutex { count = { counter = -2 //初始值为1,每增加一个等锁的进程则减 crash> bt 0xffff960574cdd140 PID: 7272 TASK: ffff960574cdd140 CPU: 2 COMMAND: "reader" #0 [ffff96056078bd48 ] kthread at ffffffffb80c1da1 #5 [ffff96056078bf50] ret_from_fork_nospec_begin at ffffffffb8775c24 crash crash> list 0xffff960539f9fe40 -l mutex_waiter.list -s mutex_waiter ffff960539f9fe40 struct mutex_waiter 0xffff960539f9fe40, prev = 0xffff96057483be40 }, task = 0xffff960574cdd140 } 为什么已经获得锁的进程已经不在wait list里了,crash
去年,网易杭州研究院曾经针对 crash 的防护有提出『大白健康系统--iOS APP 运行时 Crash 自动修复系统』方案,使得 crash 防护这个想法真正被落实,但至今该方案的具体实现并没有被开源 Crash 防护可选的方案 Crash 是什么? 在探讨 Crash 防护的方案之前,我们有必要对计算机领域 Crash 这个概念进行重新认识。 对于 Crash 的概念),维基百科中是这么定义的: In computing, a crash (or system crash) occurs when a computer program, such 可选的 Crash 防护方案 上面已经提到了 Crash 实际上我们触发了异常,但又没有去处理这些异常而导致的结果。那么很自然的第一个防护方案便可以想到是去处理这些异常。 这种方案确实是可行的,我也确实有见过一些人使用 try-catch 来做一些常见的 Crash 防护。
扫码关注腾讯云开发者
领取腾讯云代金券