提供dladdr犯规返回函数名 [英] dladdr doesnt return the function name

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

问题描述

我试图使用提供dladdr。它正确地定位在库中,但它没有找到的函数名。我可以打电话给objdump的,做一些数学,并得到了我通过提供dladdr函数的地址。如果objdump的可以看出来,为什么不能提供dladdr?

下面是我的功能:

 为const char * funcname的(常量无效* pFunc)
{
Dl_info DlInfo;
INT NRET;    //查找给定函数指针的函数的名称
    如果((NRET =提供dladdr(pFunc,&放大器;!DlInfo))= 0)
        返回DlInfo.dli_sname;
    返回NULL;
}

下面是GDB成绩单显示我所得到的。

 程序接收到的信号SIGINT,中断。
[切换主题0xf7f4c6c0(LWP 28365)]
0xffffe410在__kernel_vsyscall()
(GDB)p MatchRec8Cmp
$ 2 = {无效(TCMP *,* TWork,*的TThread)} 0xf1b62e73< MatchRec8Cmp>
(GDB)调用FUNCNAME(MatchRec8Cmp)
$ 3 =为0x0
(GDB)调用FUNCNAME(0xf1b62e73)
$ 4 =为0x0
(GDB)b FUNCNAME
在0xf44bdddb断点1:文件threads.c,线3420。
(GDB)调用FUNCNAME(MatchRec8Cmp)断点1,FUNCNAME(pFunc = 0xf1b62e73)在threads.c:3420
3420 {
正在调试的程序停止,而在从GDB调用的函数。
当函数(FUNCNAME)执行完毕,GDB会默默地
停止(而不是继续评估包含前pression
函数调用)。
(GDB)■
3426如果((NRET =提供dladdr(pFunc,&放大器;!DlInfo))= 0)
(GDB)
3427回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
$数据:=(无效(*)(TCMP *,* TWork,* TThread类))0x11fe73
(GDB)问
该程序正在运行。退出呢? (是或否)Y

下面是我从objdmp

获得

  $ objdump的--syms /xxx/libdata.so | grep的MatchRec8Cmp
0011fe73升˚F.text区段00000a98 MatchRec8Cmp

果然,0011fe73 = MatchRec8Cmp - 0xf1a43000。任何人都知道为什么提供dladdr不能返回dli_sname =MatchRec8Cmp???

我运行的红帽企业Linux服务器版本5.4(Tikanga)。我以前看过这部作品。也许这是我的编译开关:

  CFLAGS = -m32 -march = i686的-msse3 -ggdb3哌-fno常见-fomit帧指针\\
        -Ispio -fms的扩展-Wmissing-声明-Wstrict的原型-Wunused -Wall \\
        -Wno-multichar -Wdisabled优化-Wmissing的原型-Wnested,实习医生\\
        -Wpointer-ARITH -Wextra -Wno-sign-compare的-Wno序列点\\
        -I ../../../包括-I在/ usr /本地/包括-fPIC \\
        -D $(UNAME)-D_REENTRANT -D_GNU_SOURCE

我与-g而不是-ggdb3试了一下,虽然我不认为调试符号有什么用小精灵。

谢谢!


解决方案

  

如果objdump的可以看出来,为什么不能提供dladdr


提供dladdr 只能看到函数的出口的动态符号表中。最有可能的

 纳米-D /xxx/libdata.so | grep的MatchRec8Cmp

显示什么。事实上,你objdump显示该符号是的本地的,这证明这是原因。

符号是本地或者是因为它有一个隐藏的知名度,是静态的,或者是因为你把它藏在一些其他的方式(例如,用链接脚本)。

更新:


  

标有与提供dladdr的U的工作。他们得到出口自动弄好了。


他们的工作,因为他们是从出口的一些其他的共享库的。在 U 表示尚未解决,即其他地方定义。

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?

Here is my function:

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;
}

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

Here is what I get from objdmp

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

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

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 

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

Thanks!

解决方案

If objdump can see it, why can't dladdr

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

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

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).

Update:

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

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

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

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