2017-10-21 176 views
1

我有一个android应用程序崩溃在本地代码在某些情况下,我不能再现。 我在使用visual studio构建的可执行文件的崩溃调查方面拥有丰富的经验,并且包含适当的PDB文件。不幸的是,我在gcc中没有这样的经验,但我理解所需的概念。崩溃调查,从.so文件恢复符号

我没有崩溃转储,只有调用堆栈(由谷歌播放控制台报告)。它从java代码开始,然后转到.so库的公共符号,然后在本地代码中也有一个调用堆栈。当然,符号是不可见的,因为它是一个发布版本,其中剥离了私有符号。

我使用标准的NDK构建脚本。在输出发布版本,我有以下:

  • 的发行版本.so文件,700KB〜
  • 在中间(临时)文件目录:
    • 。所以使用相同的文件名,8.4MB
    • OBJ文件目录,各种的.o和.od文件

所以,我需要指导如何找出符号。位于中间目录中的.so文件比释放目录中具有相同名称的文件大得多。这些文件在小文件的末尾几乎是相同的。 看来,较大的文件实际上是相同的,并且在最后附加了调试信息。用HEX查看器打开它并搜索一些符号名称(C++ - 装饰函数名称) - 它肯定包含它们。

我试图在较大的文件上使用nm -gC工具。它确实显示了一些符号,但这是不够的:它只包含公共符号(即模块故意导出的JNI方法),以及构建过程中使用的std库中的大量内容(标准C/C++函数,pthread stuff,一些东西与例外和RTTI有关)。但是没有内部函数名称,这些名称肯定存在于文件中。

所以,我错过了什么?是否有应该指定到nm的选项?或者应该使用其他工具? 在此先感谢。

+0

最常与GCC一起使用的“标准”GNU调试器是一个调用GDB。我建议你简单地搜索'gdb从文件读取符号',你应该能够快速得到你的答案。您可以通过简单地从可用的调试版本加载符号来调试版本构建。 –

回答

1

通常,addr2line是此工作的工具。它将查看调试信息并报告行号和功能行。有一些选项可以提高输出(处理内联函数,解除符号)。

但是你需要补偿ASLR(地址空间布局随机化)。我从来没有见过谷歌崩溃报告,所以我不知道它是否提供了相对于共享对象的加载地址的地址,或者是否有其他方法来恢复相对地址。绝对地址在这种情况下非常难以使用。

+0

谢谢,伙计。这有帮助。 – valdo