dladdr不返回函数名称 [英] dladdr doesn't return the function name

查看:98
本文介绍了dladdr不返回函数名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用dladdr.它可以正确找到该库,但是找不到函数名称.我可以调用objdump,做一些数学运算,然后获取传递dladdr的函数的地址.如果objdump可以看到它,为什么不能dladdr?

I'm trying to use dladdr. It correctly locates the library, but it does not find the function name. I can call objdump, do a little math, and get the address of the function that I pass dladdr. If objdump can see it, why can't dladdr?

这是我的功能:

const char *FuncName(const void *pFunc)
{
Dl_info  DlInfo;
int  nRet;

    // Lookup the name of the function given the function pointer
    if ((nRet = dladdr(pFunc, &DlInfo)) != 0)
        return DlInfo.dli_sname;
    return NULL;
}

这是显示我所得到的gdb成绩单.

Here is a gdb transcript showing what I get.

Program received signal SIGINT, Interrupt.
[Switching to Thread 0xf7f4c6c0 (LWP 28365)]
0xffffe410 in __kernel_vsyscall ()
(gdb) p MatchRec8Cmp
$2 = {void (TCmp *, TWork *, TThread *)} 0xf1b62e73 <MatchRec8Cmp>
(gdb) call FuncName(MatchRec8Cmp)
$3 = 0x0
(gdb) call FuncName(0xf1b62e73)
$4 = 0x0
(gdb) b FuncName
Breakpoint 1 at 0xf44bdddb: file threads.c, line 3420.
(gdb) call FuncName(MatchRec8Cmp)

Breakpoint 1, FuncName (pFunc=0xf1b62e73) at threads.c:3420
3420    {
The program being debugged stopped while in a function called from GDB.
When the function (FuncName) is done executing, GDB will silently
stop (instead of continuing to evaluate the expression containing
the function call).
(gdb) s
3426            if ((nRet = dladdr(pFunc, &DlInfo)) != 0)
(gdb) 
3427                    return DlInfo.dli_sname;
(gdb) p DlInfo 
$5 = {dli_fname = 0x8302e08 "/xxx/libdata.so", dli_fbase = 0xf1a43000, dli_sname = 0x0, dli_saddr = 0x0}
(gdb) p nRet
$6 = 1
(gdb) p MatchRec8Cmp - 0xf1a43000
$7 = (void (*)(TCmp *, TWork *, TThread *)) 0x11fe73
(gdb) q
The program is running.  Exit anyway? (y or n) y

这是我从objdmp得到的

Here is what I get from objdmp

$ objdump --syms /xxx/libdata.so | grep MatchRec8Cmp
0011fe73 l     F .text  00000a98              MatchRec8Cmp

果然,0011fe73 = MatchRec8Cmp-0xf1a43000.任何人都知道为什么dladdr无法返回dli_sname ="MatchRec8Cmp";???

Sure enough, 0011fe73 = MatchRec8Cmp - 0xf1a43000. Anyone know why dladdr can't return dli_sname = "MatchRec8Cmp" ???

我正在运行Red Hat Enterprise Linux Server 5.4版(Tikanga).我以前看过这项工作.也许是我的编译开关:

I'm running Red Hat Enterprise Linux Server release 5.4 (Tikanga). I have seen this work before. Maybe it's my compile switches:

CFLAGS = -m32 -march=i686 -msse3 -ggdb3 -pipe -fno-common -fomit-frame-pointer \
        -Ispio -fms-extensions  -Wmissing-declarations -Wstrict-prototypes -Wunused  -Wall \
        -Wno-multichar -Wdisabled-optimization -Wmissing-prototypes -Wnested-externs \
        -Wpointer-arith -Wextra -Wno-sign-compare -Wno-sequence-point \
        -I../../../include -I/usr/local/include -fPIC \
        -D$(Uname) -D_REENTRANT -D_GNU_SOURCE 

尽管我认为调试符号与elf没有任何关系,但我已经使用-g而不是-ggdb3进行了尝试.

I have tried it with -g instead of -ggdb3 although I don't think debugging symbols have anything to do with elf.

推荐答案

如果objdump可以看到它,为什么不能dladdr

If objdump can see it, why can't dladdr

dladdr 在动态符号表中只能看到 exported 函数.最可能

dladdr can only see functions exported in the dynamic symbol table. Most likely

 nm -D /xxx/libdata.so | grep MatchRec8Cmp

什么也不显示.确实,您的objdump显示该符号是 local ,这证明了这是原因.

shows nothing. Indeed your objdump shows that the symbol is local, which proves that this is the cause.

该符号是局部符号,或者是因为它具有隐藏的可见性,是静态的,还是因为您以其他某种方式(例如,使用链接脚本)将其隐藏.

The symbol is local either because it has a hidden visibility, is static, or because you hide it in some other way (e.g. with a linker script).

更新:

那些标有"U"的字母与dladdr一起使用.他们以某种方式自动导出".

Those marked with the 'U' work with dladdr. They get "exported" automatically somehow.

它们之所以起作用,是因为它们是从其他共享库中导出的. U 代表未解决,即在其他地方定义.

They work because they are exported from some other shared library. The U stands for unresolved, i.e. defined elsewhere.

这篇关于dladdr不返回函数名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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