原文作者:
发布时间:2018年3月31日
本文由 简悦SimpRead 转码,原文地址 github.com
Firefox for iOS。通过在GitHu...... 创建一个账户,为mozilla-mobile/firefox-ios的开发做出贡献。
iOS版Firefox使用Sentry进行崩溃和异常报告。这种报告给Mozilla提供了宝贵的洞察力,使其了解Firefox for iOS崩溃或不正确行为的原因。它是我们用来改善产品稳定性的关键方法之一。
本页解释了Sentry是如何工作的,各个部分是如何互动的,以及它向Mozilla发送了什么样的数据。
高水平的总结
Sentry是一个开源的崩溃报告和聚合平台。客户端SDKgithub.com/getsentry/s…和服务器github.com/getsentry/s…都是开源的。
服务器是由Mozilla托管和维护的。没有第三方的参与,所有的崩溃报告都是直接从Firefox for iOS到Mozilla托管的Sentry服务器。
在客户端,Sentry是看不见的。没有任何需要互动的部分。它在后台将崩溃和致命的错误报告给Mozilla。当用户启用_Firefox for iOS_设置中的_Send Anonymous Usage Data_开关时,Sentry将被启用。默认情况下,这个开关是启用的,它是一个_opt-out_机制。
在服务器端,有一个仪表板,Firefox for iOS团队用来查看收到的崩溃报告。仪表盘可以让我们详细检查崩溃报告,例如,看到崩溃发生在应用程序的哪个位置,使用的是什么版本的应用程序,以及哪个版本的iOS处于活动状态。下面是一份崩溃报告中所有属性的概述。
Sentry报告
一个典型的Sentry崩溃报告包含三类数据:设备、应用程序、崩溃。
设备信息
Sentry收集应用程序所运行的设备的基本信息。包括静态(设备类型)和动态(使用中的内存,启动时间)。
model_id: "J82AP",
family: "iOS",
arch: "arm64",
storage_size: 31989477376,
free_memory: 206585856,
memory_size: 2084569088,
boot_time: "2017-07-22T20:24:34Z",
model: "iPad5,4",
usable_memory: 1860943872,
type: "device"
应用程序信息
Sentry收集了关于iOS版Firefox的基本信息。device_app_hash是Sentry生成的一个标识符,它可以将特定客户端的崩溃报告分组。这个标识符对Sentry来说是唯一的,在Sentry之外是无用的。它不能用于将特定的用户与崩溃联系起来。它也与Firefox for iOS内部使用的任何标识符没有关系。
executable_path: "/var/containers/Bundle/Application/07A66DB3-33D8-4C98-ABE6-AE3571A0189C/Client.app/Client",
app_identifier: "org.mozilla.ios.Firefox",
device_app_hash: "971aee19c94f2ec9b35518973bd306020745cabb",
build_type: "app store",
app_start_time: "2017-07-25T13:57:23Z",
app_version: "8.0",
type: "app",
app_build: "4558"
崩溃信息
异常信息
每个崩溃报告都包含一个_reason_ - 为什么会发生这个崩溃。这个字段可以包含两个不同的值。
- 一个由iOS生成的错误信息
- 由Firefox生成的错误信息
苹果和Mozilla都确保这些信息中没有任何个人身份信息。我们让它们保持技术性,直奔主题。
iOS生成的消息的例子。
NSInternalInconsistencyException - fatalApplication threw exception NSInternalInconsistencyException:
attempt to delete item 1 from section 0 which only contains 1 items before the update
Firefox生成的消息的例子。
BEGIN EXCLUSIVE failed. Error code: 0, Error Domain=mozilla Code=0 "Non-open connection;
can't execute change." UserInfo={NSLocalizedDescription=Non-open connection; can't execute change.}
图像
每个崩溃报告都包含一个应用程序所链接的_库和_框架_的列表。这些包括。由Firefox for iOS团队编写的框架,我们所链接的第三方框架,以及最后的_系统框架_。
这些图片描述中的 "UID "字段对每一份Firefox for iOS都是一样的,与特定的安装、设备或用户没有关系。
cpu_subtype: 0,
name: "/var/containers/Bundle/Application/07A66DB3-33D8-4C98-ABE6-AE3571A0189C/Client.app/Client",
revision_version: 0,
major_version: 0,
image_vmaddr: "0x100000000",
image_addr: "0x100060000",
minor_version: 0,
cpu_type: 16777228,
image_size: 3571712,
type: "apple",
uuid: "D16EC59F-2361-3621-A62F-AB41F5F0F869"
cpu_subtype: 0,
name: "/System/Library/Frameworks/Accelerate.framework/Frameworks/vImage.framework/vImage",
revision_version: 0,
major_version: 331,
image_vmaddr: "0x1826db000",
image_addr: "0x18f347000",
minor_version: 5,
cpu_type: 16777228,
image_size: 2732032,
type: "apple",
uuid: "1F670947-59DE-3818-9883-0A3692EDFF0F"
堆栈跟踪
每个崩溃报告都包含一个_stack trace_,它显示了Firefox for iOS代码中哪些函数导致了这次崩溃。它包括iOS系统函数和Firefox for iOS函数的名称。
0 CoreFoundation 0x30f7ccfe0 __exceptionPreprocess
1 libobjc.A.dylib 0x30cdb4538 objc_exception_throw
2 CoreFoundation 0x30f7cceb4 +[NSException raise:format:arguments:]
3 Foundation 0x310d7a720 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
4 UIKit 0x31c446d24 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:]
5 UIKit 0x31bd09f1c -[UICollectionView _updateRowsAtIndexPaths:updateAction:]
6 Client 0x2000c9e9c specialized TopTabsViewController.((reloadData in _3434E9307FC2B0225EF0EAC66FE81010)() -> ()).(closure #1) (TopTabsViewController.swift:454)
7 Client 0x2000c5304 [inlined] TopTabsViewController.((reloadData in _3434E9307FC2B0225EF0EAC66FE81010)() -> ()).(closure #1)
8 Client 0x2000c5304 partial apply for TopTabsViewController.((reloadData in _3434E9307FC2B0225EF0EAC66FE81010)() -> ()).(closure #1)
9 UIKit 0x31bb733dc +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:]
10 UIKit 0x31bcb7a24 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:animations:completion:]
11 Client 0x2000c0150 TopTabsViewController.(reloadData in _3434E9307FC2B0225EF0EAC66FE81010)() -> () (TopTabsViewController.swift:463)
12 Client 0x2000c2e60 [inlined] TopTabsViewController.tabManager(TabManager, didSelectedTabChange : Tab?, previous : Tab?) -> ()
13 Client 0x2000c2e60 @objc TopTabsViewController.tabManager(TabManager, didSelectedTabChange : Tab?, previous : Tab?) -> ()
14 Client 0x2000c3084 [inlined] dynamic TopTabsViewController.tabManager(TabManager, didSelectedTabChange : Tab?, previous : Tab?) -> ()
15 Client 0x2000c3084 protocol witness for TabManagerDelegate.tabManager(TabManager, didSelectedTabChange : Tab?, previous : Tab?) -> () in conformance TopTabsViewController (TopTabsViewController.swift:497)
16 Client 0x20025945c [inlined] specialized TabManager.(selectTab(Tab?, previous : Tab?) -> ()).(closure #1) (TabManager.swift:192)
17 Client 0x20025945c [inlined] TabManager.(selectTab(Tab?, previous : Tab?) -> ()).(closure #1) (TabManager.swift:192)
18 Client 0x20025945c [inlined] thunk
19 Client 0x20025945c [inlined] specialized Sequence.forEach((A.Iterator.Element) throws -> ()) throws -> ()
20 Client 0x20025945c specialized TabManager.selectTab(Tab?, previous : Tab?) -> () (TabManager.swift:192)
21 Client 0x2000c1970 [inlined] TabManager.selectTab(Tab?, previous : Tab?) -> ()
22 Client 0x2000c1970 TopTabsViewController.togglePrivateModeTapped() -> () (TopTabsViewController.swift:215)
23 Client 0x2000c1a40 @objc TopTabsViewController.togglePrivateModeTapped() -> ()
24 UIKit 0x31bb73010 -[UIApplication sendAction:to:from:forEvent:]
25 UIKit 0x31bb72f90 -[UIControl sendAction:to:forEvent:]
26 UIKit 0x31bb5d504 -[UIControl _sendActionsForEvents:withEvent:]
27 UIKit 0x31bb72874 -[UIControl touchesEnded:withEvent:]
28 UIKit 0x31bb72390 -[UIWindow _sendTouchesForEvent:]
29 UIKit 0x31bb6d728 -[UIWindow sendEvent:]
30 UIKit 0x31bb3e33c -[UIApplication sendEvent:]
31 UIKit 0x31c338014 __dispatchPreprocessedEventFromEventQueue
32 UIKit 0x31c332770 __handleEventQueue
33 UIKit 0x31c332b9c __handleHIDEventFetcherDrain
34 CoreFoundation 0x30f77b42c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
35 CoreFoundation 0x30f77ad04 __CFRunLoopDoSources0
36 CoreFoundation 0x30f7789a8 __CFRunLoopRun
37 CoreFoundation 0x30f6a8da4 CFRunLoopRunSpecific
38 GraphicsServices 0x312b78074 GSEventRunModal
39 UIKit 0x31bba3058 UIApplicationMain
40 Client 0x2000695dc main (main.swift:16)
41 libdyld.dylib 0x30d6ca59c start