iOS 崩溃解析

获取崩溃 crash.log

  1. 真机 Crash 文件目录:var/mobile/Library/Logs/CrashReporter。
  2. 通过 Xcode:Xcode->Window->Devices,选取设备,View Device Logs。
  3. 通过 Xcode 直接查看:Xcode -> Window -> Organizer -> Crashes。
  4. 通过 手机查找:设置->隐私->分析->分析数据,报告命名为 appname-time.ips。

将 XCode 加入环境变量

1
2
3
4
5
# 查找 XCode 环境
xcode-select -print-path

# 将其加入环境变量
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer

获取符号化工具

1
2
3
4
5
6
7
# iOS 15 以下:查找 symbolicatecrash (选对应平台的工具)
# Contents/SharedFrameworks/DVTFoundation.framework/Resources/symbolicatecrash。
find /Applications/Xcode.app -name symbolicatecrash -type f

# iOS 15 及以上:查找 CrashSymbolicator (选对应平台的工具)
# Contents/SharedFrameworks/CoreSymbolicationDT.framework/Resources/CrashSymbolicator.py
find /Applications/Xcode.app -name CrashSymbolicator -type f
  • 错误提示:Error: “DEVELOPER_DIR” is not defined at ./symbolicatecrash line 69。(未配置XCode环境变量)
  • 错误提示:No crash report version in file。(iOS 15 crash log 格式做了更新, 需要用到 CrashSymbolicator.py)

确认 crash.log 和 dSYM 的一致性

1
2
3
4
5
6
7
8
9
10
# 获取 app 的 UUID
xcrun dwarfdump --uuid appName.app/appName

# 获取 dSYM 的 UUID
xcrun dwarfdump --uuid appName.dSYM

# 查找 crash.log 集成二进制的id (crash.log 里搜索app同名二进制的 uuid")
# iOS 15 以下:查找关键字 "Binary Images:",之后第一行即可找到
# iOS 15 及以上:查找关键字 "usedImages",在其子数组中可找到app的二进制段信息
grep --after-context=2 "Binary Images:" crash.log

还原 crash.log 堆栈信息

方法1:通过符号工具手动还原 crash.log

使用 symbolicatecrash:将 crash 文件、DSYM 文件、symbolicatecrash 工具拷贝到一个目录下,执行:

1
./symbolicatecrash ./crash.log ./xxxx.dSYM > yyy.log

使用 CrashSymbolicator:切换到 CrashSymbolicator.py目录下,执行:

1
python3 CrashSymbolicator.py -d xxxx.dSYM -o yyy.log -p /xxxCrash.ips

方法2:通过 Xcode 还原 crash.log

需要3个文件,放在同一目录下

  • crash报告(.crash文件)
  • Debug Symbol 符号文件 (.dsym文件)
  • 解压 ipa 包后的 .app 文件

操作过程:Xcode -> Devices and Simulators -> 选中设备 -> View Device Logs,
然后把 .crash文件 拖到 Device Logs 或者选择下面的import导入.crash文件。这样你就可以看到crash的详细log了。

方法3:通过 atos 还原单个堆栈信息

1
xcrun atos -o {executable} -arch {architecture} -l {loadAddress} {stackAddress}

使用 atos 还原堆栈,需要两个信息:符号的栈地址(stack address)和二进制加载地址(load address)。

iOS 15以下系统的崩溃堆栈,通常包含栈地址(stack address)和符号偏移地址(offset),二进制加载地址(load address)则可能不直接显示,可以通过下面两种方式获得:

  1. 计算:loadAddress = stackAddress - offset
  2. 从崩溃日志的 binary Image 部分,找到对应的二进制,获得 loadAddress。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# iOS 15以下系统堆栈格式一: [imageName]  [stack address] [load address] + [offset]
* 3 appName 0x000f462a 0x4000 + 984618
* 4 appName 0x00352aee 0x4000 + 3468014

# 0. 获取 load address = 0x4000
# 1. 获取 stack address = 0x000f462a
xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -arch armv7 -l 0x4000 0x000f462a


# iOS 15以下系统堆栈格式二: [imageName] [stack address] [imageName] + [offset]
* 0 appName 0x001b27d7 appName + 1394647
* 1 appName 0x001b2f05 appName + 1396485

# 0. 计算 load address = 0x001b27d7 - 1394647 (0x5E000)
# 1. 获取 stack address = 0x000f462a
xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -arch armv7 -l 0x5E000 0x001b27d7

iOS 15及以上系统的崩溃堆栈,仅包含 offset,loadAddress 需要根据 imageIndex 从崩溃日志的 usedImages 区域获得,stackAddress 则需要手动计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 线程堆栈格式: [imageOffset]  [imageIndex]
{"imageOffset":32436488,"imageIndex":4}

# 二进制信息
{
"source":"P",
"arch":"arm64",
"base":4342956032,
"size":57344000,
"uuid":"df7fde00-c67e-3903-a933-a0c30af58a18",
"path":"\/private\/var\/containers\/Bundle\/Application\/02179C2E-D831-42B5-879F-F97EC59E29F0\/example.app\/example",
"name":"example"
}

# 0. 获取 load address = 4342956032 (0x102DC4000)
# 1. 计算 stack address = 4342956032 + 32436488 (0x104CB3108)
xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -arch arm64 -l 0x102DC4000 0x104CB3108

方法4:通过 dwarfdump 还原单个堆栈信息

1
dwarfdump --arch {architecture} {executable} --lookup {dSYM symbol address}

使用 dwarfdump 还原堆栈,仅需要符号的地址(symbol address),其计算公式:symbol address = start address + offset。start address 为代码段的起始地址,是指 _TEXT 段的内存加载地址,可以通过 otool 命令获得。(也可以通过 MachOView 工具查看)。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 日志格式: [appName]  [stack address] [appName] + offset
* 0 appName 0x001b27d7 appName + 1394647
* 1 appName 0x001b2f05 appName + 1396485

# 0. 计算符号地址
# start address = 代码段的起始地址 vmaddr(需要从 app 或 dSYM 中获取)
# symbol address = 1394647(偏移) + start address
# 1. 执行
dwarfdump --arch armv7 appName.app.dSYM/Contents/Resources/DWARF/appName --lookup {dSYM symbol address}
# 2. 获得符号化结果:
AT_name( "[UncaughtExceptionHandler backtrace]" )
AT_decl_file( "UncaughtExceptionHandler.m" )
AT_decl_line( 29 )

通过 otool 命令获得 app 或者 dSYM 的代码段起始地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 指令
otool -arch arm64 -l appName.app/appName

# 结果(截取 __TEXT 部分)
Load command 1
cmd LC_SEGMENT_64
cmdsize 1032
segname __TEXT
vmaddr 0x0000000100000000
vmsize 0x0000000002d48000
fileoff 0
filesize 47480832
maxprot 0x00000005
initprot 0x00000005
nsects 12
flags 0x0

# vmaddr 即为代码段的起始地址

iOS 崩溃分析

旧格式堆栈还原信息(iOS 15 以下)

还原后的 crash 文件信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
Incident Identifier: 668316AC-6AFA-4459-B4BE-6EB53ACDD79B
CrashReporter Key: 57df449638bdba0ef5911096b54d13cb0faf8e84
Hardware Model: iPhone13,4
Process: smoba [23245]
Path: /private/var/containers/Bundle/Application/577A1753-544D-47BE-BB3F-4AD59932544B/smoba.app/smoba
Identifier: com.tencent.smoba
Version: 00003 (3.65.10503)
AppStoreTools: 12E262
AppVariant: 1:iPhone13,4:14
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.tencent.smoba [582]


Date/Time: 2021-08-03 00:46:07.6607 +0800
Launch Time: 2021-08-02 23:19:26.9540 +0800
OS Version: iPhone OS 14.4.2 (18D70)
Release Type: User
Baseband Version: 1.42.03
Report Version: 104

Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d
Termination Description: SPRINGBOARD, <RBSTerminateContext| domain:10 code:0x8BADF00D explanation:scene-update watchdog transgression: application<com.tencent.smoba>:23245 exhausted real (wall clock) time allowance of 10.00 seconds | ProcessVisibility: Foreground | ProcessState: Running | WatchdogEvent: scene-update | WatchdogVisibility: Foreground | WatchdogCPUStatistics: ( | "Elapsed total CPU time (seconds): 7.960 (user 5.280, system 2.680), 13% CPU", | "Elapsed application CPU time (seconds): 0.857, 1% CPU" | ) reportType:CrashLog maxTerminationResistance:Interactive>
Triggered by Thread: 0

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x00000001cbf43230 0x1cbf19000 + 172592
1 libsystem_info.dylib 0x00000001a738e9ac 0x1a7383000 + 47532
2 libsystem_info.dylib 0x00000001a738dccc 0x1a7383000 + 44236
3 libsystem_info.dylib 0x00000001a7390b44 0x1a7383000 + 56132
4 libsystem_info.dylib 0x00000001a7393650 0x1a7383000 + 67152
5 libsystem_info.dylib 0x00000001a738c40c 0x1a7383000 + 37900
6 smoba 0x00000001078cd2bc tgcpapi_net_str2inet(char const*, sockaddr_storage*, char*, int, int*) tgcpapi_net.cpp:315 0x100f74000 + 110465724
7 smoba 0x00000001078cdf10 tgcpapi_net_connect_nonblock(char const*, char*, int, int*) tgcpapi_net.cpp:693 0x100f74000 + 110468880
8 smoba 0x000000010789fc9c tgcpapi_tcp_connection::tgcpapi_net_connect_nonblock(char const*) tgcpapi_tcp_connection.h:78 0x100f74000 + 110279836
9 smoba 0x0000000107893448 tgcpapi_connect_url(tagTGCPApiHandle*, char const*, int) tgcpapi_internal.cpp:463 0x100f74000 + 110228552
10 smoba 0x000000010789e850 tgcpapi_start(tagTGCPApiHandle*, char const*) tgcpapi_advanced.cpp:40 0x100f74000 + 110274640
11 smoba 0x00000001077ab3bc NApollo::CTdir::StartSession() Tdir.cpp:241 0x100f74000 + 109278140
12 smoba 0x00000001077b078c NApollo::CTdir::UpdateSession(int) Tdir.cpp:622 0x100f74000 + 109299596
13 smoba 0x00000001077b4b74 NApollo::CTdir::Query(int) Tdir.cpp:1005 0x100f74000 + 109316980
14 smoba 0x00000001077a9b68 tcls_query TdirAdapter.cpp:79 0x100f74000 + 109271912
...
47 smoba 0x000000010102bc3c -[UnityAppController(Rendering) repaintDisplayLink] UnityAppController+Rendering.mm:86 0x100f74000 + 752700
48 QuartzCore 0x00000001a12c36fc 0x1a12af000 + 83708
49 QuartzCore 0x00000001a139ca80 0x1a12af000 + 973440
50 CoreFoundation 0x000000019df48dd0 0x19decc000 + 511440
51 CoreFoundation 0x000000019df6dfe8 0x19decc000 + 663528
52 CoreFoundation 0x000000019df6d378 0x19decc000 + 660344
53 CoreFoundation 0x000000019df6708c 0x19decc000 + 635020
54 CoreFoundation 0x000000019df6621c 0x19decc000 + 631324
55 GraphicsServices 0x00000001b5b30784 0x1b5b2d000 + 14212
56 UIKitCore 0x00000001a09a6ee8 0x19fdde000 + 12357352
57 UIKitCore 0x00000001a09ac75c 0x19fdde000 + 12379996
58 smoba 0x0000000101023c24 main main.mm:54 0x100f74000 + 719908
59 libdyld.dylib 0x000000019dc266b0 0x19dc25000 + 5808

Thread 1 name: Dispatch queue: com.unity3d.WebOperationQueue (QOS: UNSPECIFIED)
...
...
Thread 84 name: AURemoteIO::IOThread

Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x0000000000000004 x1: 0x0000000000000000 x2: 0x0000000000000000 x3: 0x000000016ee7b480
x4: 0x0000000000000001 x5: 0x000000016ee7b450 x6: 0x0000000000000001 x7: 0x0000000000000000
x8: 0x00000001103db96c x9: 0x0000000200ed1110 x10: 0x000000016ee7b508 x11: 0x000000016ee7b4b0
x12: 0x00000000016e3600 x13: 0x0000000000002519 x14: 0x000000000000c500 x15: 0x0000c40000000000
x16: 0x000000000000016b x17: 0x0000000000000001 x18: 0x00000001543bd6ec x19: 0x0000000200ed9118
x20: 0x0000000000000035 x21: 0x0000000000000000 x22: 0x000000016ee7b9b8 x23: 0x0000000000000001
x24: 0x0000000000000002 x25: 0x0000000000000000 x26: 0x00000001f6f96000 x27: 0x0000000000008000
x28: 0x000000016ee7b5f0 fp: 0x000000016ee7b5c0 lr: 0x00000001a738e9ac
sp: 0x000000016ee7b370 pc: 0x00000001cbf43230 cpsr: 0x20000000
esr: 0x56000080 Address size fault

Binary Images:
0x100f74000 - 0x10a44ffff smoba arm64 <f5c7f02ecdbf32cab58577ce6a852e85> /var/containers/Bundle/Application/577A1753-544D-47BE-BB3F-4AD59932544B/smoba.app/smoba
0x110330000 - 0x11039ffff dyld arm64e <1f4d7499ee603c5d9d542cd29e4e537c> /usr/lib/dyld
...

注意 Binary Images 下的第一行,包含了 app 主框架的 load address(示例:0x100f74000),CPU 架构(示例:arm64),UUID (示例:f5c7f02ecdbf32cab58577ce6a852e85)。

新格式堆栈还原信息(iOS 15及以上)

还原后的 crash 文件包含两段 json 信息,第一段包含 app 相关信息,第二段包含异常堆栈信息,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"app_name":"example",
"timestamp":"2022-05-13 17:12:50.00 +0800",
"app_version":"18.1.11",
"slice_uuid":"df7fde00-c67e-3903-a933-a0c30af58a18",
"build_version":"1",
"platform":2,
"bundleID":"com.tencent.itop.example",
"share_with_app_devs":1,
"is_first_party":0,
"bug_type":"309",
"os_version":"iPhone OS 15.4.1 (19E258)",
"incident_id":"0C6A9E99-8A92-4AF8-BE28-E21D5BD86D9D",
"name":"example"
}
  • slice_uuid, app 的 Build ID,可以通过此 ID 与对应的 dSYM 符号表进行匹配。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
{
"uptime":430000,
"procLaunch":"2022-05-13 17:12:08.5753 +0800",
"procRole":"Foreground",
"version":2,
"userID":501,
"deployVersion":210,
"modelCode":"iPhone14,3",
"procStartAbsTime":10329684742490,
"coalitionID":2601,
"osVersion":{
"isEmbedded":true,
"train":"iPhone OS 15.4.1",
"releaseType":"User",
"build":"19E258"
},
"captureTime":"2022-05-13 17:12:50.0648 +0800",
"incident":"0C6A9E99-8A92-4AF8-BE28-E21D5BD86D9D",
"bug_type":"309",
"pid":57663,
"procExitAbsTime":10330680129839,
"cpuType":"ARM-64",
"procName":"example",
"procPath":"/private/var/containers/Bundle/Application/02179C2E-D831-42B5-879F-F97EC59E29F0/example.app/example",
"bundleInfo":{
"CFBundleShortVersionString":"18.1.11",
"CFBundleVersion":"1",
"CFBundleIdentifier":"com.tencent.itop.example"
},
"storeInfo":{
"deviceIdentifierForVendor":"8841BFE9-35BD-4BC7-A6A1-95EC17810BB2",
"thirdParty":true
},
"parentProc":"launchd",
"parentPid":1,
"coalitionName":"com.tencent.itop.example",
"crashReporterKey":"62ff04c2694085de9d0807197e5c7a0e6d3fe149",
"basebandVersion":"1.59.03",
"vmRegionInfo":"...略...",
"isCorpse":1,
"exception":{
"codes":"0x0000000000000001, 0x40422a1f42b88000",
"rawCodes":[
1,
4630309680642032000
],
"type":"EXC_BAD_ACCESS",
"signal":"SIGSEGV",
"subtype":"KERN_INVALID_ADDRESS at 0x40422a1f42b88000 -> 0x0000001f42b88000 (possible pointer authentication failure)"
},
"vmregioninfo":"...略...",
"faultingThread":51,
"threads":[
{
"triggered":true,
"id":4564176,
"name":"GThreadProcess",
"threadState":"...略...",
"frames":[
{
"imageOffset":32436488,
"imageIndex":4,
"symbol":"GCloud::GCloudDNS::doLocalDNS(GCloud::ObjectOperation*, void*)",
"symbolLocation":3380
},
{
"imageOffset":32436420,
"imageIndex":4,
"symbol":"GCloud::GCloudDNS::doLocalDNS(GCloud::ObjectOperation*, void*)",
"symbolLocation":3311
},
{
"imageOffset":28498480,
"imageIndex":4,
"symbol":"GCloud::ObjectOperation::Run()",
"symbolLocation":195
},
{
"imageOffset":28551536,
"imageIndex":4,
"symbol":"GCloud::OperationQueueImp::onThreadProc(void*)",
"symbolLocation":1863
},
{
"imageOffset":6572,
"symbol":"_pthread_start",
"symbolLocation":148,
"imageIndex":6
},
{
"imageOffset":3688,
"symbol":"thread_start",
"symbolLocation":8,
"imageIndex":6
}
]
}
],
"usedImages":Array[16],
"sharedCache":{
"base":6450200576,
"size":2566684672,
"uuid":"dbcbede8-6a7a-33d4-a982-44d98dd7258b"
},
"vmSummary":"...略...",
"legacyInfo":{
"threadTriggered":{
"name":"GThreadProcess"
}
},
"trialInfo":{
"rollouts":[
{
"rolloutId":"61030413bfe6dc472e1c980c",
"factorPackIds":{
"SIRI_UNDERSTANDING_NL_OVERRIDES":"624b713e16a70b047e45b7b9"
},
"deploymentId":240000277
},
{
"rolloutId":"5fb4245a1bbfe8005e33a1e1",
"factorPackIds":{

},
"deploymentId":240000015
}
],
"experiments":[
{
"treatmentId":"64a94ae0-f732-4cdb-bb33-75152aff2179",
"experimentId":"6192fb082171a2330e561df0",
"deploymentId":400000022
},
{
"treatmentId":"dc6188db-da76-4777-9ee0-4bd129ce1e4a",
"experimentId":"61ae5b540a12026a0805a31f",
"deploymentId":400000018
}
]
}
}
  • exception, 崩溃信息。可以获取到崩溃类型等信息。
  • faultingThread,崩溃线程序号。从0开始计数。
  • threads,线程堆栈信息。其中崩溃线程会带有 “triggered”:true 标识。
  • usedImages,二进制信息。可以获取到崩溃二进制段的偏移信息。

常见的 Exception

Mach Exception Type Signal 说明
EXC_BAD_ACCESS SIGSEGV、SIGBUS 非法访问,通常由于访问了不该访问的内存导致
EXC_BAD_INSTRUCTION SIGILL 非法指令,通常与特定非法或未定义指令或操作数相关
EXC_BREAKPOINT SIGTRAP 跟踪陷阱中断进程
EXC_ARITHMETIC SIGFPE 崩溃的线程执行了无效的算术运算(如除0)
EXC_CRASH SIGABRT、SIGKILL、SIGQUIT 进程收到中止信号

SIGSEGV

访问了无效地址。一般是由于内存地址不合法导致,例如访问未申请的虚拟内存地址(空指针,未初始化指针,栈溢出),或者写入没有写权限的内存。子码可能有以下几种:

  • KERN_INVALID_FAILURE:试图访问未映射的内存导致的,包括访问数据和取指令。
  • KERN_PROTECTION_FAILURE:试图使用受保护的有效内存地址导致的,包括只读内存区域或不可执行内存区域。

SIGBUS

访问了有效地址,但总线访问异常。一般是由于地址未对齐导致的,例如内存地址对齐出错,或者试图执行没有权限的代码地址。子码有以下几种情况:

  • KERN_MEMORY_ERROR:试图访问当时无法返回数据的内存,如内存映射文件不可用。
  • EXC_ARM_DA_ALIGN:试图访问没有正确对齐的内存。此异常代码很少见,因为64位ARM CPU可处理未对齐的数据。但是,如果内存地址既未对齐又位于未映射的内存区域中,则可能会看到此异常子类型。

SIGABRT

进程调用了abort函数,例如,当应用遇到未捕获的Objective-C或C++异常。SIGABRT等价于”kill -6”,它是用来杀死正在运行的进程,可以被捕获,但不能阻塞。

SIGKILL

此信号表示系统中止进程,通常是调用函数exit()或kill(9)产生。SIGKILL等价于”kill -9”,它是用来杀死僵尸进程;不能被捕获或忽略,接受进程也不能在收到此信号后做任何清理操作。

SIGKILL 时,崩溃报告会包含代表中止原因的编码:

Exception Code 说明
0x8badf00d ate bad food,系统监视程序 watch dog 中止无响应应用。(如主线程进行网络请求)
0xbaaaaaad bad,表示这个crash文件是系统的stackshot,并不是crash report,可以通过按住home+voice按键生成
0xc00010ff cool off,系统由于过热保护中止应用,通常与特定的手机和环境有关。
0xdead10cc dead lock,系统中止在后台期间一直保持占用系统资源的应用(进程在suspend期间保持在文件锁或SQLite数据库锁)。
0xbaadca11 bad all,系统由于应用在响应PushKit通知时无法报告CallKit呼叫而中止它。
0xbad22222 系统由于VoIP应用恢复太频繁而中止程序。(后台调用网络TCP连接被唤醒太多次,例如 300 秒内 15 次,就会导致此崩溃)
0xbada5e47 系统可能由于你启动了过多了后台任务而中止你的应用。
0xdeadfa11 dead fall,程序无响应用户强制关闭(在程序bug造成系统无响应时长按电源键,出现关机确认画面时按下Home键关闭当前程序)

ILL_ILLTRP:ILL_ILLTRP at 0xxxxx通常是二进制出错,典型比如app升级前后二进制缓存出错。

看门狗 Watchdog

“看门狗”(watchdog)的机制是为了防止一个应用占用过多的系统资源。在不同的场景下,“看门狗”会监测应用的性能。如果超出了该场景所规定的运行时间,“看门狗”就会强制终结这个应用的进程。

在生命周期的不同阶段,触发看门狗机制的超时时间是不一样的。

生命周期 超时时间
启动 Launch 20s
恢复 Resume 10s
悬挂 Suspend 10s
退出 Quit 6s
后台 Background 10min

在连接 Xcode 调试时为了便于调试,系统会暂时禁用掉 Watchdog,所以此类问题的发现需要使用正常的启动模式。

扩展:LC_SEGMENT

Mach-O文件的主要功能在于加载命令(load command),加载命令紧跟在文件头之后。

LC_SEGMENT(或LC_SEGMENT_64)命令是最主要的加载命令, 用于将segment直接从Mach-O二进制文件加载到内存中。对于每一个段,将文件中相对应的内容加载到内存中:从偏移量为fileoff处加载 filesize 字节到虚拟内存地址 vmaddr 处的 vmsize 字节。

一条LC_SEGMENT命令都提供了段布局的所有必要细节信息,如下表:
LC_SEGMENT

_PAGEZERO段(空指针陷阱)、_TEXT段(程序代码)、_DATA段(程序数据)和_LINKEDIT(链接器使用的符号和其他表)段提供了 LC_SEGMENT 命令。段也可以进一步分解为区(section)。

Mach-O可执行文件中常见的段和区:
MACHO_SEGMENT

常用工具

https://github.com/answer-huang/dSYMTools
https://github.com/Zuikyo/iOS-System-Symbols

参考资料

https://ctinusdev.github.io/2017/08/27/Mach-OBasis_Loadcommand/
https://developer.apple.com/library/archive/qa/qa1592/_index.html
https://developer.apple.com/documentation/xcode/diagnosing-issues-using-crash-reports-and-device-logs
https://developer.apple.com/documentation/xcode/understanding-the-exception-types-in-a-crash-report
https://developer.apple.com/documentation/xcode/adding-identifiable-symbol-names-to-a-crash-report#Symbolicate-the-Crash-Report-in-Xcode