Solaris进程如何读取自己的符号表? [英] How can a Solaris process read its own symbol table?

查看:64
本文介绍了Solaris进程如何读取自己的符号表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Solaris进程,它是一个由 ld 加载并带有一些 .so 库的C ++应用程序.此应用程序具有一个函数,该函数在调用函数中获取返回地址,然后尝试确定所述调用函数的名称.

I have a Solaris process, which is a C++ application that is loaded by ld with a few .so libraries. This application has a function that gets a return address in the calling function and then tries to determine the name of the said calling function.

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

If I use dladdr(3) for that, it does not always put what I expect to see in Dl_info::dli_sname. It looks like it returns a name of a function that is not nearest below or at the pointer value. If I take the pointer value and look at the output of nm, I can match the value to the exact function I expect it to be.

我想知道是否有一种方法可以检索进程的符号映射,并使其无需使用 dladdr(3)即可搜索函数名称.我特别想获得一个符号映射,它不仅针对可执行文件本身,而且还针对其已加载的所有 .so 库.

I am wondering if there is a way to retrieve a symbol map for a process and let it search for the function name without using dladdr(3). I am especially interested to get a symbol map not just for the executable itself but also for all .so libraries that it has loaded.

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

I'm running on Solaris10/SPARC and I'm using gcc 4.2.x.

谢谢!

推荐答案

我已经在Solaris 10/SPARC上使用 dladdr()尝试了一个简单的测试(但要注意的是:GCC 3.4,C语言),这对我来说很好:

I have tried a simple test using dladdr() on Solaris 10/SPARC (but caveats: GCC 3.4, straight C), and this works fine for me:

#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_

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

This also works correctly if I write (for example)

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

您说您可以针对 nm 的输出正确解析,因此可能性似乎很有限...您确定返回地址已正确派生或正确传递给解析器函数吗?我猜您正在为此使用 GCC内置程序吗?我已经测试了 __ builtin_return_address(0),这对我也很好.如果您使用的是GCC内置函数,是否调用了 __ builtin_extract_return_address()(有关详细信息,请参见上一页,其中明确提到了SPARC)?您可以发布代码吗?

You say you can resolve correctly against the output of nm so possibilities seem limited... are you certain that the return address is being derived or passed correctly to your resolver function? I guess you are using the GCC builtins for this? I have tested __builtin_return_address(0) and this also works fine for me. If you are using the GCC builtins, did you call __builtin_extract_return_address() (see above page for details, mentions SPARC explicitly)? Can you post your code?

您可以稍微拉伸一下以重新读取它自己的二进制/共享目标文件的过程"吗?如果是这样,那么 libelf 可能是前进的方法.这正是您提到的某些实用程序正在使用的,例如 nm :

Can you stretch slightly to "process re-reading it's own binary/shared object files"? If so then libelf may be a way forwards. This is exactly what some of those utilities you mention are using, eg nm: http://cr.opensolaris.org/~devnull/6515400/usr/src/cmd/sgs/nm/common/nm.c.html

sun.com上的介绍性文章可能有用(警告:文章已经10岁了.

This introductory article from sun.com might be of use (warning: article is 10 years old).

这不像进行内部自省, dladdr(3C)不起作用很奇怪:(

This isn't as nice as doing native introspection and it's odd that dladdr(3C) doesn't work :(

替代中间体:您是否尝试过将 RTLD_DL_SYMENT 标志标记为 dladdr1(3C)(然后像上面那样从 nm.c 借用返回的ELF符号)?

Alternative intermediate: have you tried the RTLD_DL_SYMENT flag to dladdr1(3C) (and then perhaps borrow from nm.c as above on the returned ELF sym)?

这篇关于Solaris进程如何读取自己的符号表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆