gpt4 book ai didi

ios - 从 swift 获取人类可读的堆栈跟踪

转载 作者:行者123 更新时间:2023-12-03 11:16:06 25 4
gpt4 key购买 nike

我第一次在 Apple iOS 项目上工作,我需要检索人类可读的堆栈跟踪,包括类名称和行号等,我可以将其存储为字符串以供记录和/或将来存储在某处。
我有各种各样的堆栈跟踪,但它似乎是符号,所以它不太容易看清实际发生了什么。
以下是我目前拥有的代码:

Thread.callStackSymbols.forEach({print($0)})
堆栈跟踪的示例如下
0   TestCrash                           0x0000000104056e1c $s9TestCrash14ViewControllerC03btnaB0yyypF + 1480
1 TestCrash 0x0000000104057320 $s9TestCrash14ViewControllerC03btnaB0yyypFTo + 76
2 UIKitCore 0x00000001843d2fc4 -[UIApplication sendAction:to:from:forEvent:] + 96
3 UIKitCore 0x0000000183d70c80 -[UIControl sendAction:to:forEvent:] + 220
4 UIKitCore 0x0000000183d70fc4 -[UIControl _sendActionsForEvents:withEvent:] + 352
5 UIKitCore 0x0000000183d6f924 -[UIControl touchesEnded:withEvent:] + 532
6 UIKitCore 0x000000018440d034 -[UIWindow _sendTouchesForEvent:] + 1112
7 UIKitCore 0x000000018440e920 -[UIWindow sendEvent:] + 3824
8 UIKitCore 0x00000001843ea2ac -[UIApplication sendEvent:] + 608
9 UIKitCore 0x000000018446f8bc __processEventQueue + 13600
10 UIKitCore 0x0000000184467434 __eventFetcherSourceCallback + 108
11 CoreFoundation 0x00000001803654f4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
12 CoreFoundation 0x00000001803653f4 __CFRunLoopDoSource0 + 204
13 CoreFoundation 0x000000018036474c __CFRunLoopDoSources0 + 256
14 CoreFoundation 0x000000018035ed94 __CFRunLoopRun + 760
15 CoreFoundation 0x000000018035e58c CFRunLoopRunSpecific + 572
16 GraphicsServices 0x000000018b9c2740 GSEventRunModal + 160
17 UIKitCore 0x00000001843ccbf0 -[UIApplication _run] + 964
18 UIKitCore 0x00000001843d19d0 UIApplicationMain + 112
19 libswiftUIKit.dylib 0x00000001b220f328 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 100
20 TestCrash 0x0000000104058308 $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 120
21 TestCrash 0x0000000104058280 $s9TestCrash11AppDelegateC5$mainyyFZ + 48
22 TestCrash 0x000000010405834c main + 32
23 libdyld.dylib 0x0000000180223cbc start + 4
这样做的原因是我希望能够将堆栈上传到服务器进行日志记录(是的,我了解崩溃报告服务,我正在创建自己的版本)。
在我设置的 xcode build设置中 Deployment Postprocessing , Strip Debug Symbols During CopyStrip Linked Product但这似乎没有太大区别。
我还查看了 Linux 的 dwarfdump 和 atos 项目(这是将发送日志的服务器类型),但这些似乎都不起作用,因为它要么只是再次给我十六进制值,要么 dwarfdump 只是抛出了一些错误,但两者都在我发现的这些项目中,我发现似乎不受支持并且现在已经很老了,所以我猜在编译代码的情况下发生了一些变化,这意味着这不再有效,因此为什么要避免构建过程剥离调试信息,所以它以编程方式可用。

最佳答案

所以我认为首先重新实现像 Firebase Crashlytics 这样的崩溃报告解决方案是 非平凡不可取 鉴于 Crashlytics 提供的服务质量 免费 .崩溃报告很难,因为 您需要避免框架崩溃 本身是因为与内存地址、函数指针、操作系统信号和多线程的低级接口(interface) 没有类型安全和垃圾收集(在 C++ 中) .也是出了名的难以测试 给出各种可能的崩溃、应用程序状态、不同的设备(对于旧设备需要轻量级)以及具有死锁/线程/内存泄漏的边缘情况。如果您 还是想继续 ,我将在下面概述主要考虑因素。
运行时符号化的问题是实现 API 以读取调试符号、上传符号和拦截异常处理程序。 callStackSymbols不是机器可读的 所以你必须使用类似 callStackReturnAddresses 的函数重新实现调用堆栈解析器。 .
这很重要,因为不仅崩溃必须被符号化,而且需要在应用程序之前上传到服务器/缓存(通常由 忙于等待 同时检查应用程序是否仍处于事件状态)完成)因崩溃而终止。这意味着代码需要运行 高效生成堆栈帧带有文件和行号元数据(C++ 最适合)。
执行异步上传具有挑战性 没有高级 C++ 库 ,并在不使用 native Foundation API 的情况下进行持久本地缓存(事件也需要在专用线程上排队,使用锁来确保同步)。除了语言障碍外,名称还需要用线程信息进行符号化和解调(每个堆栈帧还需要包括当时其他每个线程的状态)。默认情况下,崩溃堆栈跟踪确实包含方法名称(已损坏),但还有其他信息,例如 应用运行时需要上传文件名和行号 . 您看到的十六进制数字是内存地址 ,因此这些需要在运行时转换为适当的对象元数据并发送。 C中拦截异常的方法是使用信号处理程序 - 拦截 iOS 内核信号:

{SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS, SIGTRAP};
如果信号不是其中之一,您仍然可以发送请求但使用 拦截崩溃的“未知”信号处理程序 .
话虽如此,使用调试符号将崩溃报告器拼接在一起可能是可行的。你可以这样做 就一次当您归档应用程序时(您 不需要 需要物理设备)。您可以在将应用程序发送到 App Store 时执行一次此操作。 FaSTLane 可以通过输出目录简化此操作(另一种方法是在 xcodebuild 中使用环境变量 DWARF 目标文件夹)。 然后您可以解析服务器上的调试符号。
找到 .xcarchive并执行此操作以将主要目标和任何链接框架的 dsym 压缩在一起:
ditto -c -k --keepParent -rsrc <AppName>.xcarchive/dSYMs/*.dSYM <AppName>-${PRODUCT_VERSION}-dSYM.zip
你提到你不知道在哪里可以找到调试符号。如果您想知道文件所在的位置,可以转到 Xcode Organizer,Archives,然后右键单击 Show in Finder。然后右键点击 显示包装内容 查看 dSYM。
即使你对一个相当简陋的崩溃记者感到满意,你也 需要加密服务器上传因为在发送原始崩溃日志时可以对代码库进行逆向工程!您还需要手动检查 构建 UUID 以确保崩溃的相同应用程序版本被符号化(否则符号化将失败)。
另一种方法是使用 App Store 提供的崩溃日志(可在 Xcode 中下载)。这样做的优势主要是易于设置、与 Xcode 的集成以及报告的质量。如果您坚持使用 Apple,您还可以获得 Jetsam 内存日志警告。然后,服务器本身就可以使用 dSYM 和脚本轻松地自动构建崩溃报告:
//Put dsyms and crash log in one folder and navigate to that folder
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
cp -i /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash ./
./symbolicatecrash unsymbolicated.crash > symbolicated.crash
我希望这为您指明了正确的方向;不幸的是,无法为您提供功能齐全的崩溃报告解决方案的完整代码(它太宽泛、太复杂,更不用说超出了 SO 问题的范围)。 :-)

关于ios - 从 swift 获取人类可读的堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58293598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com