dSYM是什么?如何使用?(iOS SDK)

158
有时编译器会生成 .dSYM 文件。我猜这是一个与调试相关的文件,但我不知道它是什么,以及如何使用它。
.dSYM 是什么?我该如何使用它?

在这个惊人的 WWDC 2021 视频中,可以找到一份细致而优秀的解释 ⟹ https://developer.apple.com/videos/play/wwdc2021/10211/ - XLE_22
2个回答

204

dSYM文件存储应用程序的调试符号

像 Crashlytics 这样的服务使用它来将崩溃日志中的符号替换为适当的方法名称,使其易读且有意义。

使用 dSYM 的好处是,您不需要将应用程序与其符号一起发布,这使得反向工程更加困难,并减小了二进制文件的大小。

为了使用符号解析崩溃日志,您需要将崩溃日志拖放到编译应用程序二进制文件的机器(存储 dSYM 的机器)的设备日志中。

如果您有dSYM但没有编译应用程序二进制文件的机器,请按照此链接中的说明将dSYM安装到该机器上。

如果需要自行进行符号化崩溃日志,则可以使用Mac应用程序

有关更多信息,请参见苹果技术说明TN2151


1
不将dSYMs与应用商店二进制文件一起包含,会导致Crashlytics无法记录崩溃吗? - genaks
那么取消勾选“包括应用程序符号...”框是安全的吗? - genaks
2
如果您想要在Apple Connect中查看崩溃日志,可以在上传应用到应用商店时包含应用符号。如果您正在使用Crashlytics,则不必这样做,但包含应用符号(即dsym文件)并通过在上传到App Store向导中选中“包含应用符号...”将其发送给Apple是无害的。 - Tomer Even
1
我在考虑如果可能的话,能否为用户节省几个MB。 - genaks
据我所知,生成报告的实体需要dSYM。它可以从应用程序中获取,或者应上传到Crashlytics、AppDynamics(或其他您正在使用的分析工具)服务器... - mfaani
显示剩余2条评论

32

Xcode调试符号(dSYM)

dSYM是一个包含映射信息的Bundle(例如F49088168M.app.dSYM),通过它,您可以将堆栈跟踪解码为可读格式。

结构:

例如,崩溃日志如下:

//before
0   libswiftCore.dylib              0x000000018f3c9380 0x18f394000 + 217984
1   libswiftCore.dylib              0x000000018f3c9380 0x18f394000 + 217984
2   libswiftCore.dylib              0x000000018f3c8844 0x18f394000 + 215108
3   libswiftCore.dylib              0x000000018f3a74e0 0x18f394000 + 79072
4   libswiftCore.dylib              0x000000018f3ab0d8 0x18f394000 + 94424
5   F49088168M                      0x00000001045ac750 0x104590000 + 116560
6   F49088168M                      0x00000001045b7904 0x104590000 + 162052
7   F49088168M                      0x00000001045b897c 0x104590000 + 166268
8   F49088168M                      0x000000010459d914 0x104590000 + 55572
9   F49088168M                      0x00000001045a0e70 0x104590000 + 69232
10  F49088168M                      0x00000001045a0f4c 0x104590000 + 69452

dSYM 的作用

//after Symbolicating(dSYM is used)
0   libswiftCore.dylib              0x000000018f3c9380 closure #1 in closure #1 in closure #1 in _assertionFailure+ 217984 (_:_:file:line:flags:) + 452
1   libswiftCore.dylib              0x000000018f3c9380 closure #1 in closure #1 in closure #1 in _assertionFailure+ 217984 (_:_:file:line:flags:) + 452
2   libswiftCore.dylib              0x000000018f3c8844 _assertionFailure+ 215108 (_:_:file:line:flags:) + 468
3   libswiftCore.dylib              0x000000018f3a74e0 _ArrayBuffer._checkInoutAndNativeTypeCheckedBounds+ 79072 (_:wasNativeTypeChecked:) + 208
4   libswiftCore.dylib              0x000000018f3ab0d8 Array.subscript.getter + 84
5   F49088168M                      0x00000001045ac750 static ELM327ResponseManager.getResponse(responseStr:obd2Protocol:) + 116560 (ELM327ResponseManager.swift:27)
6   F49088168M                      0x00000001045b7904 ELM327Client.dataInput(_:characteristicUuidStr:) + 162052 (ELM327Client.swift:56)
7   F49088168M                      0x00000001045b897c protocol witness for BLEClientInputPort.dataInput(_:characteristicUuidStr:) in conformance ELM327Client + 166268 (<compiler-generated>:0)
8   F49088168M                      0x000000010459d914 BLEConnection.peripheralDataReceived(data:characteristicUuidStr:) + 55572 (BLEConnection.swift:124)
9   F49088168M                      0x00000001045a0e70 BLEConnection.peripheral(_:didUpdateValueFor:error:) + 69232 (BLEConnection.swift:293)
10  F49088168M                      0x00000001045a0f4c @objc BLEConnection.peripheral(_:didUpdateValueFor:error:) + 69452 (<compiler-generated>:0)

默认情况下,为发布版本默认生成dSYM。 您可以检查它:

Build Settings -> Generate Debug Symbols(GCC_GENERATE_DEBUGGING_SYMBOLS) -> Yes
Build Settings -> Debug Information Format(DEBUG_INFORMATION_FORMAT) -> DWARF with dSYM File

你可以在 Products 文件夹中找到结果位置

使用 dsymutil.app 手动生成 dSYM 文件

dsymutil F49088168M.app/F49088168M -o F49088168M.app.dSYM

使用symbolicatecrash符号化崩溃日志

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer" 
/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/Current/Resources/symbolicatecrash "<path>/F49088168M-2020-06-04-212904.crash" "<path>/F49088168M.app.dSYM" > symbolicated.crash

使用 dwarfdump 手动打开 dSYM

dwarfdump --arch arm64 --debug-pubtypes F49088168M.app.dSYM

结果看起来像:

0x00000065 "PeripheralLogView"
0x000005cc "BLEConnection"
0x000005da "BLEPeripheral"
0x000005e9 "ELM327Client"

*您的.app的dSYM应包括所有包含的(框架)dSYMs

[dSYM位置]

[.bcsymbolmap]

[词汇表]


那么这就像dsym知道每个地址的相关符号一样?这个地址是在哪个容器内部的地址? - mfaani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接