于是,我有了一个不成熟的想法。。。 让我的APP永不崩溃 既然我们可以拦截崩溃,那我们直接把APP中所有的异常拦截了,不杀死程序。这样一个不会崩溃的APP用户体验不是杠杠的? 运行,点击按钮2,触发子线程异常崩溃: “咦,还真没啥影响,程序能继续正常运行” 然后点击按钮1,触发主线程异常崩溃: “嘿嘿,卡住了,再点几下,直接ANR了” [主线程崩溃] “果然有问题,但是为啥主线程会出问题呢 而子线程崩溃了并不会影响主线程也就是UI线程的操作,所以用户还能正常使用。 这样好像就说的通了。 来张崩溃日志图给大家对对看: [崩溃日志图] 好了,回到正轨,所以我们通过setDefaultUncaughtExceptionHandler方法设置了我们自己的崩溃处理器,就把之前应用设置的这个崩溃处理器给顶掉了 [崩溃调用图] 小光又来找我对峙了 搞清楚这一切的小光又来找我了: “老铁,你瞅瞅,这是我写的Demo和总结的资料,你那套根本行不通,主线程崩溃就GG了,我就说有问题吧” 我继续故作镇定: “老哥,我上次忘记说了
它的主要功能: 实时监控SDK业务异常 汇总包体崩溃排重与聚合后的数据 统计影响设备数 上报崩溃日志 收集iOS系统向上兼容性问题 监控客户端请求的网络问题 <! 开发者可以通过设置 Thread、Task、Host 的异常端口来捕获 Mach 异常。Mach 异常会被转换成相应的 Unix 信号,并传递给出错的线程。 SIGFPE:程序浮点异常信号,通常在浮点运算错误、溢出及除数为等算术错误时都会产生该信号。 SIGKILL:程序结東接收中止信号,用来立即结東程序运行,不能被处理、阻塞和忽略。 聚合先过滤掉崩溃线程的内存地址、偏移量,再将文本做hash标签,按标签进行聚合,再按设备标示进行排重。以此种方法聚合堆栈由于iOS系统版本的不同堆栈md5值会有出入。 7.2、结束语 本次对Bugless项目的技术关键点的设计、开发和上线,可以看出该项目能持续有效的对苹果平台发行业务问题排查提供数据支撑。当然该项目仍有一个自身不断完善的过程。
Vite学习指南,基于腾讯云Webify部署项目。
UI 更新可能会发生崩溃 多个线程进行数据的读取操作,因为处理时机不一致,比如有一个线程在置空数据的同时另一个线程在读取这个数据,可能会出现崩溃情况 ▐ 2.4 主线程无响应 如果主线程超过系统规定的时间无响应 一般,在退后台时你都会把关键业务数据保存在内存中,如果保存过程中出现了崩溃就会丢失或损坏关键数据,进而数据损坏又会导致应用不可用。这种关键数据的损坏会给用户带来巨大的损失。 App崩溃在不通过的系统版本、设备、版本的占比.png 有了全局大盘信息,一旦出现大量崩溃,你就需要明白是哪些方法调用出现了问题,需要根据影响的用户数量按照从大到小的顺序排列出来,优先解决影响面大的问题 有了崩溃的方法调用堆栈后,大部分问题都能够通过方法调用堆栈,来快速地定位到具体是哪个方法调用出现了问题。 有些问题仅仅通过这些堆栈还无法分析出来,这时就需要借助崩溃前用户相关行为和系统环境状况的日志来进行进一步分析。 5.
于是,我有了一个不成熟的想法。。。 让我的APP永不崩溃 既然我们可以拦截崩溃,那我们直接把APP中所有的异常拦截了,不杀死程序。这样一个不会崩溃的APP用户体验不是杠杠的? 而子线程崩溃了并不会影响主线程也就是UI线程的操作,所以用户还能正常使用。 这样好像就说的通了。 崩溃日志图 好了,回到正轨,所以我们通过setDefaultUncaughtExceptionHandler方法设置了我们自己的崩溃处理器,就把之前应用设置的这个崩溃处理器给顶掉了,然后我们又没有做任何处理 ,自然程序就不会崩溃了,来张总结图。 崩溃调用图 小光又来找我对峙了 搞清楚这一切的小光又来找我了: “老铁,你瞅瞅,这是我写的Demo和总结的资料,你那套根本行不通,主线程崩溃就GG了,我就说有问题吧” 我继续故作镇定: “老哥,我上次忘记说了
于是,我有了一个不成熟的想法。。。 让我的APP永不崩溃 既然我们可以拦截崩溃,那我们直接把APP中所有的异常拦截了,不杀死程序。这样一个不会崩溃的APP用户体验不是杠杠的? 而子线程崩溃了并不会影响主线程也就是UI线程的操作,所以用户还能正常使用。 这样好像就说的通了。 所以程序就崩溃了。 关于我们平时在手机上看到的崩溃提示弹窗,就是在这个handleApplicationCrash方法中弹出来的。 方法设置了我们自己的崩溃处理器,就把之前应用设置的这个崩溃处理器给顶掉了,然后我们又没有做任何处理,自然程序就不会崩溃了,来张总结图。 “这就要通过反射了,借用Cockroach开源库中的思想,由于Activity的生命周期都是通过主线程的Handler进行消息处理,所以我们可以通过反射替换掉主线程的Handler中的Callback回调
于是,我有了一个不成熟的想法。。。 让我的APP永不崩溃 既然我们可以拦截崩溃,那我们直接把APP中所有的异常拦截了,不杀死程序。这样一个不会崩溃的APP用户体验不是杠杠的? 运行,点击按钮2,触发子线程异常崩溃: “咦,还真没啥影响,程序能继续正常运行” 然后点击按钮1,触发主线程异常崩溃: “嘿嘿,卡住了,再点几下,直接ANR了 image.png “果然有问题,但是为啥主线程会出问题呢 而子线程崩溃了并不会影响主线程也就是UI线程的操作,所以用户还能正常使用。 这样好像就说的通了。 所以程序就崩溃了。 关于我们平时在手机上看到的崩溃提示弹窗,就是在这个handleApplicationCrash方法中弹出来的。 来张崩溃日志图给大家对对看: image.png 好了,回到正轨,所以我们通过setDefaultUncaughtExceptionHandler方法设置了我们自己的崩溃处理器,就把之前应用设置的这个崩溃处理器给顶掉了
手机上显示闪退崩溃信息,并且崩溃详情信息可以保存,分享给开发 主要是测试同学在测试中发现了崩溃,然后跑过去跟开发说,由于不容易复现导致开发童鞋不承认……有时候用的bug统计不是那么准! (AppManager.getAppManager().currentActivity()); 关于app启动方式详细介绍 App启动介绍 06.后续的需求说明 可能不兼容 该库尚未通过多进程应用程序进行测试 如果您使用这种配置进行测试,请提供反馈! 如果您的应用程序初始化监听或错误活动崩溃,则有可能进入无限重启循环(在大多数情况下,库会对此进行检查,但在极少数情况下可能会发生)。 (得出应用本身内存的占用大小和分布) 线程数 收集崩溃时的应用信息 崩溃场景(崩溃发生在哪个 Activity 或 Fragment,发生在哪个业务中) 关键操作路径(记录关键的用户操作路径,这对我们复现崩溃会有比较大的帮助 looper拦截崩溃或者anr,存在一个巨大的问题,就是按钮点不动或者无反应。
进入正题,大家应该都听过这样一句话——“UI更新要在主线程,子线程更新UI会崩溃”。久而久之就感觉这是个真理,甚至被认为是“官方结论”。 但是如果问你,官方什么时候在哪里说过这句话,你会不会有点懵。 就好比之前的Android11更新文档,我也是看了好久,通过一个个实践才写出了适配指南,然后就发现其中一个比较明显的BUG,Google官方有说过这样一句: 下面是首先需要关注的行为变更 (无论您应用的 如果设置为固定值,是不会崩溃的,见案例2,所以是不是跟布局改变的逻辑有关呢? 延时3秒。如果不延时的话,即使是wrap_content也不会崩溃,见案例1,所以是不是跟某些类的加载进度有关呢? 加载布局 加载布局其实就是我们常用的setContentView(int layoutResID)方法,这个方法主要做的就是新建了一个DecorView,然后根据activity设置的主题(theme) 但是,Button的宽度设置为固定值咋又不崩溃了?难道就不会执行checkThread方法了?奇怪。
而在应用发布后,监视应用程序中这些不断增加的崩溃是一种极其不愉快的体验。 不管应用程序的业务逻辑如何,都可能会因为运行的系统或平台问题而导致出现某些奇怪的崩溃现象。 在 Android 中,从后台状态恢复应用程序时可能会产生崩溃 —— 此类崩溃是意外发生的,而且仅通过查看崩溃日志,我们很难理解崩溃的具体原因以及解决问题,而本文讨论了此类问题及其解决方法。 导航到任意一个页面,然后按下“主页”按钮。 打开终端,键入以下命令,我们就可以获取应用程序的进程 ID(PID)。 虽然此解决方案可以防止崩溃,但是这种方法其实就是重新启动应用程序,而不是从中断的位置恢复应用程序。如果你在发布应用后遇到此问题,并且急切地希望快速解决这个问题,则此解决方案应该能帮你大忙。 解决方案 1 可以快速解决你现有的应用崩溃问题。 但是,如果你正在从头开始开发应用程序,我建议使用解决方案 2,因为它可以确保系统会从先前关闭的位置恢复该应用程序,因此带来更好的用户体验。
按月去重统计,则每月有高达 1.8 亿 的设备遭遇应用崩溃。 ? 3.每天有大量用户会遇到多次应用崩溃 应用程序发生崩溃,通常表现在你打开,或者试运行它的时候立即退出。 有时候一个应用程序的崩溃可能在你开启它的一瞬间就会发生,或者在你不希望停下的时候发生,每次崩溃都会导致大量用户卸载应用。 ? 可见巨头们在解决应用崩溃方面还是下了不少功夫的。 注:崩溃率 = 当天发生崩溃的设备数 /当天联网设备数,本报告后续所有崩溃率均按此标准计算 ? 12.在 Root 设备上应用更容易发生崩溃 手机 Root 不仅会带来更高的崩溃率,同时,也存在很多的安全性问题。 ? 移动互联网的竞争已经到了白热化的阶段,产品创意再好,如果品质不过关也会给整体的口碑大打折扣。希望这篇基于腾讯Bugly大数据的移动应用崩溃分析,能给每个开发者一些收获。崩溃不可怕,我们一起来解决它。
这就导致大多服务还没起来,应用就已经崩溃了。只要出现了这种情况,每次打开 App, 都会因为一样的问题,而连续闪退。 2. 连续崩溃的后果 那么像这样的连续崩溃,会造成什么后果呢? 也就是说,保得了一时,保不了一世。 ▐ 3.1 进行连续崩溃检测 在前面有提到过,连续崩溃的一大问题是--开发无感知。 也就是说,我们连问题发生了都不知道,所以首要做到的是发现问题。 我们可以将流程中要 hook 的对象和方法,都想办法存储起来,如使用 NSMapTable 等。 在结束修复后,再按顺序遍历出来对象和方法一个个调用,走完一套启动的流程。 >= maxCrash, 进入修复引导 修复的流程设计为: 设置根控制器为新的控制器,并弹出修复框,提示“检测到应用可能已损坏,是否尝试修复?” 所以作为技术人员,需要做好兜底的策略,尽量来消除此类问题,保证好用户体验,通过技术保护手段多留住一个用户就是一个用户。 何况事实证明,未雨绸缪是应该的,这次连续崩溃问题不就发生在了自己身上了吗?
NSException掌控着程序的生命,程序的崩溃就是NSException来控制的。其实主要的出发点是让开发者认识到哪里的代码有问题。 ** NSException** ? 就像上面NSException的基本用法中的代码一样。 2、可以用来捕获异常,防止程序的崩溃。当你意识到某段代码可能存在崩溃的危险,那么你就可以通过捕获异常来防止程序的崩溃。 } 崩溃日志 关于修复崩溃的Bug,如果你凭借自己的经验,有时候可能会遇到问题卡住,我想最快的方式就是通过分析崩溃日志来解决崩溃。 什么时候不会产生崩溃日志 以下情况不会有崩溃信息产生: 内存访问错误(不是野指针错误) 低内存,当程序内存使用过多会造成系统低内存的问题,系统会将程序内存回收 因为某种原因触发看门狗机制 一般Xcode 在iOS中, 收集Crash主要通过两种方式, 一种是信号量机制,因为crash通常会发出信号量,标明某某应用崩溃了, 另一种方式是每一个应用都有一个crash handle, 即崩溃钩子, 每当程序崩溃时
前言 作为开发者,程序崩溃是很经常的事,我们可以自己利用崩溃日志和自己找出Crash的原因,但是当团队人数众多,多版本控制的情况下,以及线上版本崩溃追踪都迫切需要一个工具来把崩溃的原因反馈给我们,最好是定位到崩溃的具体位置和在代码的具体行数 pod install 安装执行 集成SDK到项目中 为了更加方便开发者设置相应的工程,Crashlytics提供了mac端的应用程序,帮助你检测相关工程是否正确设置并且提供相应的帮助信息。 image.png 由于崩溃都是在下次打开应用时上传的,所以在程序出现崩溃时,你需要再次打开一下APP才行。 使用真机时,需要拔掉连接线;使用模拟器时,需要先通过点击Xcode的停止键,然后在模拟器中通过点击应用图标后打开,Xcode运行模拟器的时候会阻止dSYM文件的上传。 小结 这算是一篇工具使用介绍,集体的安装工程配置工作,按照官网上的操作就可顺利完成,这里不作详细说明。
此时,用户可以开始使用该应用程序。 [70] 因为App应用进程的创建过程是由手机的软硬件决定的,所以我们只能在这个创建过程中视觉优化。 启动主题优化 冷启动阶段 : 加载并启动应用程序。 启动后立即显示应用程序空白的启动窗口。 创建应用程序进程。 所谓的主题优化,就是应用程序在冷启动的时候(1~2阶段),设置启动窗口的主题。 默认情况 如果我们对App没有做处理(设置了默认主题),并且在 Application 初始化了其它第三方的服务(假设需要加载2000ms),那么冷启动过程就会如下图 : [70] 系统默认会在启动应用程序的时候启动空白窗口 其实这种方式并没有真正的加速应用进程的启动速度,而只是通过用户视觉效果带来的优化体验。 代码优化 当然上面使用设置主题的方式优化用户体验效果治标不治本,关键还在于对代码的优化。 如果当前 Activity 是透明主题或者是浮动窗口等,那么就不需要启动窗口来过渡启动过程,所以在上面视觉优化中的设置透明主题就没有显示白色的启动窗口。
同时,带来了另一个问题,在系统crash时能否正确地恢复数据的读写呢? 许多应用程序都依赖于特定的文件系统实现,因此当在不同的文件系统或不同的配置上运行时,在系统崩溃后很容易出现意外的行为。 关于文件系统的崩溃行为存在着两个误区: 误区1 :POSIX 定义了崩溃行为 POSIX 定义了类 unix 操作系统导出的标准文件系统接口(打开、关闭、读取和写入) ,并且对于构建可移植应用程序至关重要 开发人员的应对 开发人员可以通过以下方法法来缓解应用崩溃后的数据一致性问题: 使用一个库 只要有可能,一个明智的策略是使用一个库,比如 SQLite,在应用程序的底层实现崩溃后的数据一致性。 文档承诺 应用程序提供的崩溃后数据一致性承诺可能令人困惑, 一些开发人员可能不清楚应用程序可以提供的承诺,因为通常都不清楚文件系统的那些行为。最好的文档承诺是提供所支持的文件系统配置列表。 用一个抽象的持久性模型来完全表达文件系统的崩溃行为是否可行呢? 除了文件系统之外,应用程序崩溃后的数据一致性是一个有趣的问题,整个存储堆栈都面对着这个问题.......
简单地添加更多 CPU 并不是一个好主意,因为它不能解决应用程序中可能存在的潜在瓶颈。 但是,这不是生产工作负载,也不是生产应用程序,所以让我们看看通过让几个实例在少数节点上运行来扩展模糊应用程序的可能最糟糕的*方法。这就是 Kubernetes 发挥作用的地方。 通过在 gdb 中逐步执行应用程序的最终验证显示 strdup 存在相同的问题并且无法访问内存。 最后,我们对崩溃是如何发生的有了一个很好的了解,但是为什么? 这个函数调用在一个迭代程序段的存根中。在某些情况下 name不会设置为任何值,因此 strdup 没有字符串可以复制。这显示在下面的代码片段中。幸运的是,这是一个简单的解决方法,并且PR 已入站! 这可以通过 获得minikbue ssh-key -n NODE_NAME。然而,更“Kubernetes 方式”将是有一个边车应用程序,用于将崩溃推送到特定的中心位置。
但是Native崩溃会比较麻烦,Native崩溃一般是在c/c++代码中访问了非法地址,也可能是地址对齐出现了问题,或者发生了程序主动abort,这些都会产生signal信号,导致程序异常退出。 通过dump_sysm工具可以生成发生崩溃so文件的符号表,通过mindump_stackwalk工具可以生成上报native崩溃日志的调用栈,结合符号表就能定位到发生崩溃的位置。 Facebook 开发的检测手机主流配置工具device-year-class,我们可以对低端手机关闭复杂的动画效果,使用565格式图片,使用更小的缓存策略来提升应用在低端机上的体验。 ? 对于普通的应用程序,系统时间一般不会超过30%,如果超过这个值,就需要进一步检查是不是I/O过多,或者是其他系统调用问题。 进行监控,而且性能开销非常低,但是它不支持应用程序代码耗时分析,使用起来有一定的局限性。
数据如果过大,可能要压缩或者解压。这块我将介绍两种库的使用: zip 7z 日志打点。日志打点的作用不可小视。对于开发同学,日志可以标识程序执行的脉络,从而方便我们定位问题。 对于产品交互设计同学,打点可以帮助统计一个按钮被按下多少次,是经过什么顺序被按下的,从而我们可以依据这些数据设计出更合理的交互。有时候,我们安装一款软件后,往往会有个勾选——帮助我们改进。 相关技术参阅: 《python3编写简易统计服务器》 《WMI技术介绍和应用——查询硬件信息》 崩溃。可能除了著名的Hello World,没有哪款著名的程序可以保证自己不崩溃。 对于折腾过破电脑或者安装过很多杀软的同学来说,应该见过蓝屏是什么样子——操作系统崩溃了。连操作系统都会崩溃,更何况我们写的程序呢?所以崩溃并不可怕,可怕的是我们不能收集崩溃日志和不会分析崩溃日志。 这是一个非常有意思的主题。通过指令可配置化,我们可以像控制网页一样方便的控制客户端的行为——一般情况下,如果我们要改变客户端逻辑可能需要修改代码并发布新的版本。
要学会看crash崩溃和报告 一个应用程序并不总会一直运行的很好,它总会有出现crash崩溃的情况。 如果在应用程序中接入了一些第三方的crash收集工具或者自建crash收集报告平台的话将会很好的帮助开发者去分析和解决应用程序在线上运行的问题,当出现的崩溃问题能得到及时的解决和快速的修复时必将会大大的提升应用程序的用户体验 设置符号断点的目的是为了在崩溃函数调用堆栈重现时,能在运行时的断点处进行动态分析。当你设置了符号断点后,如果程序逻辑运行到这个函数或者方法时,系统就会在设置的方法或者函数的第一条指令处停止下来。 符号断点的设置 当程序停在了设置符号断点的函数或者方法的开始地址后,接下来就需要在这个方法内进行第二个断点的设置,设置的地方就是崩溃函数调用栈中函数调用上层函数的偏移处,这个可以在崩溃的报告中看到: 0 其实这个问题如果进一步观察就可以看出:崩溃的线程并不是出现在主线程,而是在一个工作线程中。
扫码关注云+社区
领取腾讯云代金券