如何在Xcode中对崩溃日志进行符号化?

219

Xcode 5的组织者(Organizer)有一个视图,可以列出所有崩溃日志,并且我们可以将崩溃日志拖放到此处。但是自从Xcode 6以后,我知道他们已经将设备移出组织者并为其创建了一个新窗口。但是我找不到在升级到Xcode 6后查看我在Xcode 5中拖放的崩溃日志的地方。有人知道答案吗?


3
几个月前我在Apple开发者论坛上提出了这个问题,但没有得到答案。这导致了一些有用功能的缺失。向苹果提交一个错误报告,要求恢复这个功能。 - rmaddy
1
我在一个周末内匆忙编写了这个程序,以解决iOS和OSX崩溃转储的符号化问题。它仍然很粗糙,但应该可以工作。https://github.com/agentsim/Symbolicator - Tim
12
Xcode,请你能不能按照规定好好地解析苹果审核员的崩溃日志,而不是假设我们有一整天的时间来弄清楚如何做这件事?请不要使用粗俗的语言。 - William Entriken
13个回答

285

我写这篇答案不仅是为了社区,也是为了自己。

如果在符号定位崩溃报告时遇到问题,可以按以下步骤解决:

  1. 创建一个单独的文件夹,将相应的.xcarchive中的Foo.appFoo.app.dSYM复制到该文件夹中。还要将.crash报告复制到该文件夹中。

  2. 在TextEdit或其他文本编辑器中打开崩溃报告,转到Binary Images:部分,并复制那里的第一个地址(例如0xd7000)。

  3. cd进入该文件夹。现在可以运行以下命令:

    xcrun atos -o Foo.app/Foo -arch arm64 -l 0xd7000 0x0033f9bb

这将对地址0x0033f9bb处的符号进行定位。请确保选择正确的-arch选项值(可以从Binary Images:部分的第一行获取,或者从崩溃报告中的Hardware Model:和应用程序支持的体系结构中找出)。

您还可以直接从崩溃报告中复制必要的地址(例如线程调用堆栈)到文本文件中(在TextEdit中,按住Option键并选择所需的文本块,或者复制和剪切),以获得以下结果:

0x000f12fb
0x002726b7
0x0026d415
0x001f933b
0x001f86d3

现在你可以将这个内容保存到一个文本文件中,例如 addr.txt,然后运行以下命令:
xcrun atos -o Foo.app/Foo -arch arm64 -l 0xd7000 -f addr.txt

这将同时为所有地址提供良好的符号化。

P.S.

在执行上述操作之前,值得检查一切是否设置正确(因为atos会为基本上任何提供的地址报告某些内容)。

要进行检查,请打开崩溃报告,并转到Thread 0的调用堆栈末尾。从末尾开始列出您的应用程序(通常是第二个),例如:

34  Foo                    0x0033f9bb 0xd7000 + 2525627

应该是main()函数调用。对于此处的地址(0x0033f9bb),按照上述方法将其符号化,应该能确定这确实是main()函数而不是某个随机方法或函数。

如果地址不是main()函数的地址,请检查您的加载地址(-l选项)和体系结构(-arch选项)。

P.S.

如果由于比特代码而无法使用上述方法,则从iTunes Connect下载您构建的dSYM,从中提取可执行二进制文件(Finder > Show Package Contents),将其复制到目录中,并使用它(即Foo)作为参数传递给atos,而不是Foo.app/Foo


2
感谢您编写迷你xcrun教程并更新其中的健全性检查部分。在经历了大量咒骂和找不到符号化的情况下,我的理智得以保留。 - Anton Tropashko
12
别忘了验证崩溃报告是否与可执行文件和dSYM相匹配。你可以通过在“Binary Image”部分的<>标识符与运行命令“xcrun dwarfdump --uuid <path to executable>”返回的可执行文件中匹配来进行检查。 - Ryan C. Payne
2
需要注意的是,只有来自您的应用程序(Foo)的符号才会显示出来。它不会显示来自外部库/框架(如Foundation或libsystem_kernel.dylib)的符号。 - jlukanta
1
这很有帮助,但对我仍然没有用。我遇到麻烦的部分是我没有0xd7000的信息。我的代码行看起来像这样0x100038328 __mh_execute_header + 99112。我已经阅读了__mh_execute_header的内容,但我如何获取关于0x100038328的信息???我已经拥有其他所有信息。 - skinsfan00atg
7
我编写了一个简单的Bash脚本,可以为您完成大部分工作。使用方法:./symbolicate.sh mycrash.crash MyApp.app arch64 output.crash它将符号化完整的崩溃报告,并给您提供符号化版本的内容。https://gist.github.com/nathan-fiscaletti/b58b642f78a4f60274e3be703e230140 - Nathan F.
显示剩余4条评论

233

你也可以参考这个链接,我写了一步一步的手动崩溃重新符号化过程。

崩溃重新符号化

第一步

将上述所有文件(MyApp.app、MyApp-dSYM.dSYM和MyApp-Crash-log.crash)移动到一个方便使用终端的文件夹中。

对我来说,桌面是最容易到达的地方;) 因此,我已将这三个文件移动到桌面上的名为MyApp的文件夹中。

第二步

现在轮到Finder了,根据您的XCODE版本选择以下路径之一。

使用此命令查找symbolicatecrash脚本文件,
find /Applications/Xcode.app -name symbolicatecrash

Xcode 7.3及更高版本(Xcode 8、...、Xcode 14、...):/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

第三步

像这样将找到的symbolicatecrash脚本文件目录添加到$PATH env变量中:sudo vim /etc/paths.d/Xcode-symbolicatecrash,并粘贴脚本文件目录并保存该文件。在打开新终端时,您可以在任何文件夹中调用symbolicatecrash作为位于/usr/bin中的命令。

或者

从这个位置复制symbolicatecrash文件,并将其粘贴到Desktop/MyApp。 (等一下...不要盲目跟随我,在步骤一中创建的文件夹MyApp中粘贴sybolicatecrash文件,这是您喜欢的位置,包含三个文件。)

第四步

打开终端,并CD到MyApp文件夹。

cd Desktop/MyApp — Press Enter
export DEVELOPER_DIR=$(xcode-select --print-path)

 — 按下回车键

./symbolicatecrash -v MyApp-Crash-log.crash MyApp.dSYM

完成了!符号化的日志已经在你的终端上了… 现在只需找到错误并解决它 ;)


3
请使用以下命令进行翻译,并确保内容准确无误、通顺易懂且意思不变:将开发者目录设置为 Xcode 的路径。命令如下:export DEVELOPER_DIR=`xcode-select --print-path` - Parag Bafna
10
非常有效 - 谢谢。只有一件事,我需要使用export DEVELOPER_DIR=/Applications/XCode.app/Contents/Developer(无引号)。 - goelectric
2
更新;在这里;对于Xcode7,在这里找到symbolicatecrash;/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash,参考https://dev59.com/MFwY5IYBdhLWcg3wRGBS。 - AnneTheAgile
2
嗯,它只是将除了我提供的app目标符号外的一切进行符号化... - fabb
2
这个可行! 你可以将符号化日志写入文件以记录和更好地处理,而不是在控制台上搜寻;只需将符号化命令更改为: ./symbolicatecrash -v MyApp-Crash-log.crash MyApp.dSYM | xargs >> symbolicated_crash_log 这将把符号化的日志写入指定的文件中。 - geekay
显示剩余6条评论

133

我意识到你可以这样做:

  1. 在中,选择连接的iPhone / iPad /等设备左上角。
  2. 查看设备日志
  3. 所有日志

您可能有很多日志,在后面找到导入的日志更容易一些,您可以立即删除所有日志…除非它们对您意味着钱。或者,除非您知道崩溃发生的确切时间点-它应该在文件中写好了...我很懒,所以我只删除所有旧日志(这实际上花了一些时间)。

3a. 确保日志文件具有扩展名.crash(而不是.txt.ips

  1. 只需将文件拖放到该列表中。 对我很有效。

17
我遇到了同样的问题,但这并没有解决我的问题——我将日志拖放到窗口中,但无法进行符号化。 - Arkaaito
9
诀窍在于您必须连接设备并从列表中选择该设备。我认为如果没有设备是不可能实现的。 - Jonny
67
为了使您的崩溃文件可以被拖放到该列表中,它应该具有扩展名为 .crash - pjay_
9
对我来说缺失的一步是将文件拖放后,需要右键单击文件并重新符号化日志。 - RobCroll
13
在组织器(Organizer)中下载dSYM文件以获取该存档。 - 123FLO321
显示剩余20条评论

40

对我来说,.crash文件就足够了,不需要.dSYM文件和.app文件。

我在构建存档的Mac上运行了这两个命令,它可以工作:

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer" 

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash  /yourPath/crash1.crash > /yourPath/crash1_symbolicated.crash

哇,我不知道没有.dsym文件它是如何工作的,但它确实可以工作! - rustyMagnet
5
它的工作方式是使用计算机上已存档版本构建中的dsyms。 - Andrey Tarantsov
3
是的,这只适用于你已经通过Xcode存档的构建版本,而不是其他你可能为特定目的生成的构建版本,如果你希望对它们进行符号化崩溃日志处理,则需要采取其他措施。 - CMash

24

有一个更简单的方法使用Xcode来做(不用使用命令行工具和一个接着一个查找地址)

  1. 选取任何一个.xcarchive文件。如果之前有一个,可以直接使用。如果没有,可以通过在Xcode中运行“Product > Archive”来创建一个。

  2. 右键点击.xcarchive文件,然后选择“显示包内容”。

  3. 将崩溃版本的dsym文件复制到dSYMs文件夹中。

  4. 将崩溃版本的.app文件复制到Products > Applications文件夹中。

  5. 编辑Info.plist文件,编辑ApplicationProperties字典下的CFBundleShortVersionString和CFBundleVersion。这将帮助您后来识别档案。

  6. 双击.xcarchive文件将其导入到Xcode中。它会打开Organizer。

  7. 返回到崩溃日志(在Xcode的设备窗口中)中。

  8. 将.crash文件拖到那里(如果还没有出现)。

  9. 整个崩溃日志现在应该已经被符号化了。如果没有,请右键点击并选择“重新符号化崩溃日志”。


2
你的答案正确并简单。无需使用终端应用程序。重新创建.xcarchive文件夹非常重要,因为在某些持续集成系统中没有.xcarchive文件,而是使用.app.dSYM文件夹的压缩包。巧合的是,昨天我所做的正是你所说的。 - DawnSong
完整的输出应该是什么样子? - noobsmcgoobs
这部分符号化了我的崩溃日志,尽管我跳过了步骤3-5,因为我的xcarchive是针对崩溃的应用程序版本的。 - Declan McKenna
1
当然,它只会对您自己的代码进行符号化处理 - 而不是您可能使用的外部库代码。 - RPM
2
如果拖动不起作用怎么办?该文件确实具有.crash扩展名,但窗口会拒绝它(它会执行移回的动画)。无论我将其拖到哪里或是否选择了所有日志,都是如此。 - CristianMoisei
这应该是被接受的答案。实际上,我所要做的就是双击保存的.xcarchive文件,然后Xcode就会加载它。不需要步骤2-6,但是这个答案已经有六年了,所以可能会有改进。一旦我加载了存档,Xcode就开始无问题地对我的崩溃日志进行符号化处理。 - Bill

18

Xcode 11.2.1,2019年12月

苹果以 .txt 格式提供了崩溃日志,但该格式是未进行符号化处理的

**

连接设备后:

**

  • 下载 ".txt" 文件,将扩展名更改为 ".crash" enter image description here
    • 从 Xcode 的窗口标签中打开 "设备和模拟器"
    • 选择设备并选择设备日志
    • 将 .crash 文件拖放到设备日志窗口中

enter image description here

我们将能够在那里看到符号化的崩溃日志

请参阅链接以获取有关符号化崩溃日志的详细信息Crash logs


哇,将文件扩展名从.txt更改为.crash就可以了。他们给了我一个.txt文件。谢谢,伙计。真不敢相信你的答案这么简单。 - datWooWoo

14

你需要获取包含DWARF文件的.dSYM文件夹,并使用编辑器打开.crash文件。

查看回溯(backtrace)部分,你应该会看到类似下面的内容:

...
13  TheElements                         0x0000000100f62ca0 0x100f5c000 + 27808
14  UIKitCore                       0x00000001843e3044 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 356 (UIApplication.m:2328)
...

Binary Images:
0x100f5c000 - 0x101673fff TheElements arm64 ...
...
  1. 请注意堆栈跟踪部分的长地址,第3列 (0x0000000100f62ca0)
  2. 请注意第4列中的短地址 (0x100f5c000)
  3. 请注意Binary Images部分中的架构 (arm64)
  4. 执行以下操作:
$ atos -arch <arch> -o TheElements.app.dSYM/Contents/Resources/DWARF/TheElements -l <short_address> <long_address>

你应该得到这样的结果:

-[AtomicElementViewController myTransitionDidStop:finished:context:]

权威来源:https://developer.apple.com/library/content/technotes/tn2151/_index.html#//apple_ref/doc/uid/DTS40008184-CH1-SYMBOLICATE_WITH_ATOS

注意:如果由于任何原因您无法访问.dSYM文件,则可以使用Xcode>Product>Archive重新创建.xcarchive,但请确保构建的是完全相同的代码。然后,您可以从.xcarchive包中提取符号。


这对我有用。请注意,倒数第二个数字(在上面的示例中为0x1000e4000)可以在“二进制图像”部分的第一列或堆栈跟踪的第四列中找到。此外,没有必要将.dSYM文件和.crash文件放在同一个子文件夹中。 - arlomedia
更新了答案以简化它。还添加了一些额外的信息。 - Victor Bogdan

13

按照以下步骤在Xcode 10中对来自同一台机器构建的应用程序崩溃日志进行符号化:

  1. 组织者内,找到基于该应用程序的存档。
  2. 单击下载调试符号按钮。您的下载文件夹中不会出现任何内容,但这很正常。
  3. 将构建机连接到iOS设备。
  4. 选择设备和模拟器中的设备。
  5. 单击查看设备日志按钮。
  6. 将崩溃文件拖放到左侧面板。该文件必须以.crash扩展名结尾,否则拖动失败。
  7. 切换到所有日志选项卡。
  8. 选择添加的崩溃文件。
  9. 文件应自动符号化,否则使用右键上下文菜单项重新符号化日志

3
起初我认为这并没有增加其他帖子的任何内容,但前两个步骤,特别是“下载调试符号”,似乎是我所缺少的。谢谢。 - Christopher King

4
请确保你的Xcode应用程序名称中不包含任何空格。这就是它不能正常工作的原因。因此,/Applications/Xcode.app 是可以工作的,而 /Applications/Xcode 6.1.1.app 不行。

1
这不是我所讨论的同一个问题。Xcode可以在安装后但首次使用前更名。然而,符号化脚本无法处理应用程序名称中的空格并将失败。 - Bouke
1
@ChuckKrutsinger 你真的试过吗?因为转义空格可以让脚本运行,但脚本本身可能会失败。脚本可能没有使用转义空格调用其他脚本。 - Bouke
@ChuckKrutsinger,我回答了几个星期了,但我相信这个脚本无法处理空格:/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash - Bouke
1
@ChuckKrutsinger 那很不错,但如果要让 Xcode 自动符号化崩溃日志,最终需要我的答案。 - Bouke
1
我想再强调一遍,bouke是正确的,如果您在Xcode应用程序路径中存在空格,则Xcode用于重新符号化崩溃日志的脚本将无法工作。这与手动重新符号化无关。 - Gary Makin
显示剩余5条评论

3

根据苹果的文档:

使用Xcode对崩溃报告进行符号化 Xcode将自动尝试对遇到的所有崩溃报告进行符号化。您只需要将崩溃报告添加到Xcode组织者中即可进行符号化。

  • 将iOS设备连接到Mac上
  • 从“窗口”菜单中选择“设备”
  • 在左侧列的“设备”部分下,选择一个设备
  • 在右侧面板的“设备信息”部分下点击“查看设备日志”按钮
  • 将您的崩溃报告拖到呈现面板的左侧列上
  • Xcode将自动对崩溃报告进行符号化并显示结果 要对崩溃报告进行符号化,Xcode需要能够定位以下内容:

    1. 崩溃应用程序的二进制文件和dSYM文件。

    2. 应用程序链接的所有自定义框架的二进制文件和dSYM文件。对于与应用程序一起构建的框架,它们的dSYM文件将复制到归档中,与应用程序的dSYM文件一起。对于由第三方构建的框架,您需要向作者请求dSYM文件。

    3. 应用程序在崩溃时运行的操作系统的符号。这些符号包含特定OS版本(例如iOS 9.3.3)中包含的框架的调试信息。OS符号是体系结构特定的-64位设备上的iOS版本不会包括armv7符号。Xcode将自动从连接到Mac的每个设备复制OS符号。

如果缺少其中任何一个,Xcode可能无法对崩溃报告进行符号化,或者可能只能部分符号化崩溃报告。


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