本文介绍了提供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试了一下,虽然我不认为调试符号有什么用小精灵。

谢谢!


解决方案

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:

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

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

09-11 01:56