在我的共享库中获取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实用程序。
之后我正在执行类似的事情:
addr2line -e /opt/ecelerity/libexec/site/ec_attachextensions.so (LIBRARY_OFFSET_FROM_MAPS_FILE - 0x2aecc2019f11)
其中0x2aecc2019f11
是上面堆栈跟踪的地址。我想知道有没有办法在不触及地图文件的情况下在堆栈跟踪中获取函数名称?换句话说,我该如何编程呢? dladdr
会在这里提供帮助(dladdr
无法从我的案例中的backtrace
函数提供的地址中获取函数名称吗?
答案 0 :(得分:1)
回溯代码使用与dladdr大致相同的机制来确定函数名称。
如果您的库是使用链接器映射文件(定义正在导出的内容,可用于限制所有其他项的可见性)或带有显式可见符号的-fvisibility=hidden
构建的,那么它模糊符号,使它们不会出现在回溯输出中。
变通方法是在不使用限制库中所有符号可见性的映射文件的情况下进行编译,或使用-fvisibility=default
进行构建。这将使您无需代表您进行任何努力即可恢复工作。
要在不执行此操作的情况下使其工作,您需要从.so加载本地符号表,并使用类似于addr2line的机制确定符号位置。执行此操作的机制是使用libelf1
。阅读本地符号表。
...这当然要求表格尚未从文件中删除。如果是这种情况,那么这些技巧都不重要,因为.so根本没有提供信息。
答案 1 :(得分:1)
你可以让信号处理程序读取/ proc / self / maps。
或者您可以输出某些函数的绝对地址,然后您可以将其用作比较点以查找库偏移量。
但是如果有一个动态链接器函数可以为你提供基地址,我不会感到惊讶 - 你可以检查文档。