【问题标题】:dladdr doesn't return the function namedladdr 不返回函数名
【发布时间】:2012-07-30 23:41:34
【问题描述】:

我正在尝试使用 dladdr。它正确定位了库,但找不到函数名。我可以调用 objdump,做一些数学运算,然后得到我传递给 dladdr 的函数的地址。如果objdump可以看到,为什么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 成绩单,显示了我得到的结果。

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 得到的

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

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

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

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。

【问题讨论】:

  • 只是一个猜测 - 尝试extern "C"你的 MatchRec8Cmp()?
  • 值得一试,除了我认为当我执行 objdump 并且函数位于 .c 文件中时名称看起来不正确。
  • 您是否在链接可执行文件时传递了-rdynamic
  • @BasileStarynkevitch -rdynamic 不太可能有帮助:无论如何,它是链接共享库时的默认设置。
  • 我说的是-rdynamic 用于程序可执行文件(在这种情况下它不是默认值)- 不是用于共享库。

标签: c linux elf


【解决方案1】:

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

dladdr 只能看到动态符号表中exported 的函数。很有可能

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

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

符号是本地的,或者因为它具有隐藏的可见性,是静态的,或者因为您以其他方式隐藏它(例如使用链接器脚本)。

更新:

标有“U”的人使用 dladdr。它们以某种方式自动“导出”。

它们之所以有效,是因为它们是从其他一些共享库导出的。 U 代表未解决,即在别处定义。

【讨论】:

  • 你是对的,当我执行 nm -D 时,所讨论的函数没有出现。事实上,当我调用 nm.当我传递确实显示的函数的地址时, dladdr 工作。我不知道如何导出函数。我不使用 -fvisibility,所以默认情况下应该导出所有函数。我尝试使用 attribute ((visibility("default"))),但这也不起作用。
  • 我搜寻了很长时间,发现在构建中执行了一个 bash 脚本,该脚本设置了一个 make 变量,导致 --version-script 被添加到构建中。但是由于某种原因,nm -D 结果中显示了许多未在 --version-script 中列出的函数。它们都看起来像这样:“U MemInfoTransCreate”,而 --version-script 中标记为“全局”的项目看起来像这样:“00000000001202ff T MatchRec8Cmp_th”。那些标有“U”的人与 dladdr 一起工作。它们以某种方式自动“导出”。
【解决方案2】:

我将-rdynamic 添加到我的 LDFLAGS 中。

man gcc 说:

-rdynamic
    Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the
    dynamic symbol table. This option is needed for some uses of "dlopen" or to allow obtaining backtraces from within a program.

【讨论】:

    【解决方案3】:

    添加 gcc 选项“-export-dynamic”为我解决了这个问题。

    【讨论】:

      【解决方案4】:

      hinesmr 解决方案对我有用。我通过 gcc 的确切选项是“-Wl,--export-dynamic”,所有函数都对 dladdr 可见

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多