c – Solaris进程如何读取自己的符号表?

前端之家收集整理的这篇文章主要介绍了c – Solaris进程如何读取自己的符号表?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个Solaris进程,它是一个由带有几个.so库的ld加载的C应用程序.该应用程序有一个函数,它在调用函数获取返回地址,然后尝试确定所述调用函数名称.

如果我使用dladdr(3),它并不总是把我期望在Dl_info :: dli_sname中看到.看起来它返回的函数名称不是最接近下方或指针值.如果我取指针值并查看nm的输出,我可以将该值与我期望的确切函数匹配.

我想知道是否有办法检索进程的符号映射,并让它搜索函数名称而不使用dladdr(3).我特别感兴趣的是获得一个符号映射,不仅可以用于可执行文件本身,还可以用于已加载的所有.so库.

我在Solaris10 / SPARC上运行,我正在使用gcc 4.2.x.

谢谢!

解决方法

我在Solaris 10 / SPARC上尝试过使用dladdr()的简单测试(但需要注意的是:GCC 3.4,直接C),这对我来说很好用:
#include <dlfcn.h>
#include <stdio.h>

void print_name(char *name,void *addr);
void print_name_by_dladdr(void *addr);

int main(int argc,const char *argv[])
{
    print_name("main",(void *)&main);
    print_name("print_name",(void *)&print_name);
    print_name("printf",(void *)&printf);
    return 0;
}

void print_name(char *name,void *addr)
{
    (void)printf("Getting name of function %s() at 0x%x\n",name,addr);
    print_name_by_dladdr(addr);
}

void print_name_by_dladdr(void *addr)
{
    Dl_info dli;
    if(!dladdr(addr,&dli)) {
        perror("dladdr()");
        exit(1);
    }
    (void)printf("  %s\n",dli.dli_sname);
}

输出

Getting name of function main() at 0x10714
  main
Getting name of function print_name() at 0x10778
  print_name
Getting name of function printf() at 0x209b8
  _PROCEDURE_LINKAGE_TABLE_

如果我写(例如)这也可以正常工作

print_name("main",(void *)&main + 4);

你说你可以正确地解决nm的输出,所以可能性似乎有限……你确定返回地址是正确地导出或传递给你的解析器函数吗?我猜你用的是GCC builtins吗?我测试了__builtin_return_address(0),这对我来说也很好.如果你使用的是GCC内置函数,你是否调用__builtin_extract_return_address()(有关详细信息,请参见上页,明确提及SPARC)?你能发布你的代码吗?

你能稍微伸展一下“处理重新读取它自己的二进制/共享对象文件”吗?如果是这样,那么libelf可能是一种前进的方式.这正是您提到的一些实用程序正在使用的内容,例如nm:http://cr.opensolaris.org/~devnull/6515400/usr/src/cmd/sgs/nm/common/nm.c.html

来自sun.com的introductory article可能是有用的(警告:文章是10岁).

这不像做本机内省那么好,而且dladdr(3C)不起作用很奇怪:(

替代中间:您是否已尝试将RTLD_DL_SYMENT标志发送到dladdr1(3C)(然后可能在返回的ELF sym上从nm.c借用)?

猜你在找的C&C++相关文章