debugging 从发布版本中获取Thread.callStackSymbols给予奇怪的堆栈跟踪

iqxoj9l9  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(228)

在我的项目中,当发生错误(不是崩溃,只是错误)时,我会向服务器发送日志,这些日志是错误描述和堆栈跟踪,它们会给予有关错误发生的位置和时间的信息。

Thread.callStackSymbols

当我从Xcode在我的设备上使用它时,它工作得很好,但是我在服务器上从我的应用程序的发布版本接收到堆栈跟踪,这是没有意义的。
我测试了它在一个名为X的类中强制一个错误,并将这个错误的堆栈跟踪发送到我的服务器。直接从Xcode本地运行,堆栈跟踪显示了类X。但是当我构建我的发布版本作为我的用户使用时,我在服务器中收到的堆栈跟踪没有提到类X(错误发生的地方)。
我使用生成的dSYM文件和所有必要的东西来符号化我的堆栈跟踪,但它仍然不起作用。我还看到了我的DEBUG_INFORMATION_FORMAT,它是DWARF with dSYM file,这似乎是正确的。
我错过了什么?我在哪里读到,在发布版本中,Thread.callStackSymbols在设备端可能不可靠。是否有其他方法可以获取堆栈跟踪并发送到我的服务器?

z5btuh9x

z5btuh9x1#

我想我明白问题所在了:
Thread.callStackSymbols在设备上自动符号化地址,但它可能不起作用,因为符号从发布版本中删除了。
现在,我将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>

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

相关问题