我试图获取并保存一个堆栈跟踪到一个文件后,我的共享库中的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]
- __cxa_finalize和__attribute__
- 有没有在网上的任何交互式工具来了解通用的代码库?
- 如何知道编译器正在编译的函数的位置
- 我如何模拟一个内存I / O设备在Linux上进行unit testing?
- 从C ++的posix信号处理程序获取对象属性
/ opt / ecelerity / sbin / ecelerity(validate_data + 0xa5)[/ opt / ecelerity / sbin / ecelerity(sieve_seng_execute + 0x82)[0x506d32] / opt / ecelerity / ecelerity / sbin / ecelerity(esmtp_message_factory + 0x154e)[0x46eace] / opt / ecelerity / sbin / ecelerity(schedule_event_and_dispatch + 0x6a)[0x49c59a]
问题是,我不能拥有共享库中的函数名称和偏移量。 据我所知,我可以在/proc/$PID/maps
find库偏移后,使用addr2line实用程序查找给定地址的函数名称/文件名。
之后,我正在执行这样的事情:
addr2line -e /opt/ecelerity/libexec/site/ec_attachextensions.so (LIBRARY_OFFSET_FROM_MAPS_FILE - 0x2aecc2019f11)
其中0x2aecc2019f11
是来自上面堆栈跟踪的地址。 我想知道有没有什么办法,我可以不使用地图文件的堆栈跟踪获取函数名称? 换句话说,我该如何编程呢? dladdr
会在这里帮助(在我的情况下, dladdr
无法从backtrace
函数提供的地址获取函数名称)?
回溯代码使用与dladdr大致相同的机制来确定函数名称。
如果您的库是使用链接器映射文件(定义正在导出的内容,并且可以用来限制所有其他项目的可见性)构建的,或者使用显式可见符号-fvisibility=hidden
了-fvisibility=hidden
,则它会遮蔽这些符号它们不会出现在回溯输出中。
解决方法是在不使用限制库中所有符号可见性的映射文件的情况下编译,或者使用-fvisibility=default
编译。 这将回到工作,没有任何代表你的努力。
为了在不这样做的情况下工作,你需要从.so中加载本地符号表,并使用类似于addr2line的机制来确定符号位置。 这样做的机制是利用libelf1
。 读取本地符号表。
这当然要求表格没有被从文件中剥离。 如果是这样的话,那么这些技巧都不重要,因为.so根本就没有提供这些信息。
您可以让信号处理程序为您读取/ proc / self / maps。
或者你可以输出一些函数的绝对地址,然后你可以用它作为比较点来查找库偏移量。
但是如果有一个动态链接器函数会给你基地址,我不会感到惊讶 – 你可以查看文档。