崩溃调查,从.so文件中恢复符号

时间:2017-10-21 21:35:23

标签: c++ gcc symbols

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

我没有崩溃转储,只有callstack(由google play console报告)。它从java代码开始,然后转到.so库的公共符号,然后在本机代码中也有一个callstack。当然,符号是不可见的,因为它是一个发布版本,它剥离了私有符号。

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

  • 发布版本.so文件,~700KB
  • 在中间(临时)文件目录中:
    • .so文件同名,8.4MB
    • objs目录,包含各种.o和.o.d文件

所以,我需要一个如何找出符号的指导。中间目录中的.so文件比发布目录中具有相同名称的文件大得多。这些文件几乎完全相同,直到较小的文件结束。 似乎较大的文件实际上是相同的,加上调试信息最后附加。用HEX查看器打开它并搜索一些符号名称(C ++ - 修饰的函数名称) - 它肯定包含它们。

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

那么,我错过了什么吗?是否应该为nm指定选项?或者也许应该使用其他工具? 提前谢谢。

1 个答案:

答案 0 :(得分:1)

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

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