3

SEGSEGV进入共享库后,我正在尝试获取堆栈跟踪并将其保存到文件中。共享库是闭源产品的插件。所有这些都适用于生产,我无法直接访问它。

我的代码捕获SIGSEGV信号,打印堆栈跟踪并退出。我有这样的事情:

/opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc2019f11] /opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc2019f11] /opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc2019fee] /opt/ecelerity/ libexec/site/ec_attachextensions.so [0x2aecc201a587]

/opt/ecelerity/sbin/ecelerity [0x501235]

/opt/ecelerity/sbin/ecelerity(sieve_seng_execute+0x82) [0x506d32] /opt/ecelerity/libexec/validate/sieve.so [0x2aecc2862c9e] /opt/ecelerity/sbin/ecelerity(validate_data+0xa5) [0x4a90d5] /opt/ ecelerity/sbin/ecelerity(esmtp_message_factory+0x154e) [0x46eace] /opt/ecelerity/sbin/ecelerity(schedule_event_and_dispatch+0x6a) [0x49c59a]

问题是我不能在其中包含共享库的函数名称和偏移量。据我了解,在找到/proc/$PID/maps.

之后,我正在执行类似的操作:

addr2line -e /opt/ecelerity/libexec/site/ec_attachextensions.so (LIBRARY_OFFSET_FROM_MAPS_FILE - 0x2aecc2019f11)

0x2aecc2019f11上面堆栈跟踪的地址在哪里。我想知道有什么方法可以在不接触地图文件的情况下在堆栈跟踪中获取函数名称?换句话说,我该如何编程?在这里会dladdr有所帮助(在我的情况下dladdr,无法从函数提供的地址获取函数名称backtrace)?

4

2 回答 2

1

回溯代码使用与 dladdr 大致相同的机制来确定函数名称。

如果您的库是使用链接器映射文件(定义要导出的内容,并可用于限制所有其他项目的可见性)或-fvisibility=hidden具有显式可见符号的 构建的,那么它会隐藏符号,以便它们不会出现在回溯输出中。

解决方法是在不使用限制库中所有符号可见性的映射文件的情况下进行编译,或者使用-fvisibility=default. 这将使您无需任何努力就可以进行回溯。

要让它在不这样做的情况下工作,您需要从 .so 加载本地符号表,并使用类似于 addr2line 的机制确定符号位置。这样做的机制是利用libelf1. 读取本地符号表。

...这当然要求该表尚未从文件中删除。如果是这种情况,那么这些技巧都不重要,因为 .so 根本不附带信息。

于 2012-05-04T17:11:02.310 回答
1

您可以让信号处理程序为您读取 /proc/self/maps。

或者您可以输出某个函数的绝对地址,然后您可以将其用作比较点来查找库偏移量。

但是,如果有一个动态链接器函数可以为您提供基地址,我不会感到惊讶 - 您可以查看文档。

于 2012-05-04T17:22:40.817 回答