【问题标题】:Getting Thread.callStackSymbols from release version give me weird stack trace从发布版本获取 Thread.callStackSymbols 给我奇怪的堆栈跟踪
【发布时间】:2023-02-04 03:28:59
【问题描述】:

在我的项目中,当发生错误(不是崩溃,只是错误)时,我将日志发送到我的服务器。这些日志是错误描述和堆栈跟踪,应该为我提供有关错误发生的地点和时间的信息。我正在使用获取堆栈跟踪

Thread.callStackSymbols

当我通过 Xcode 在我的设备上使用它时它工作得很好,但是我在我的服务器上收到来自我的应用程序发布版本的堆栈跟踪,这些跟踪没有意义。

我测试了它在名为 X 的类中强制出错并将此错误的堆栈跟踪发送到我的服务器。直接从 Xcode 在本地运行,堆栈跟踪按预期显示类 X。但是当我构建我的发布版本以用作我的用户时,我在服务器中收到的堆栈跟踪没有提到类 X(发生错误的地方)。

我正在使用生成的 dSYM 文件和所有必要的东西来表示我的堆栈跟踪,但它仍然不起作用。我还看到了我的DEBUG_INFORMATION_FORMAT,它是DWARF with dSYM file,这对我来说似乎是正确的。

我错过了什么?我在某个地方读到,Thread.callStackSymbols 在发布版本的设备端可能不可靠。还有另一种方法可以将堆栈跟踪发送到我的服务器吗?

【问题讨论】:

    标签: ios swift debugging


    【解决方案1】:

    我想我明白了这个问题:

    Thread.callStackSymbols 自动在设备上符号化地址,但它可能不起作用,因为符号已从发布版本中删除。为了解决这个问题,我的代码基于NSProgrammer's answer

    现在,我发送Thread.callStackReturnAddresses(您需要将这些地址转换为十六进制值)和加载地址到我的服务器。我使用_dyld_get_image_header 获得了加载地址。需要注意的是,如果你想获取特定框架的加载地址,你需要这样检查

        for i in 0..<_dyld_image_count() {
          guard let address = _dyld_get_image_header(i),
                let name = String(validatingUTF8: _dyld_get_image_name(i)) else {
            continue
          }
          
          if name.contains(FRAMEWORK_NAME) {
            // send address to the server
          }
        }
    

    使用服务器中的堆栈地址和加载地址,您可以获取 dSYM 文件并使用 atos 之类的

    atos -arch arm64 -o <PathToDSYMFile>/Contents/Resources/DWARF/<BinaryName>  -l <LoadAddress> <AddressesToSymbolicate>
    

    有些地址可能不会被符号化,因为它们引用其他库,如系统库,但正确的地址可以正常工作!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-15
      • 2010-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多