2016-05-08 77 views
3

我正在使用dlsym在程序中查找符号,但它始终返回NULL,这并不是我期待的。根据手册页,如果出现错误,dlsym可能会返回NULL,或者符号确实为NULL。在我的情况下,我收到一个错误。我会告诉你我今晚做的MCVE。即使符号存在,dlsym也会返回NULL

这里是instr.c的内容:

#include <stdio.h> 

void * testing(int i) { 
    printf("You called testing(%d)\n", i); 
    return 0; 
} 

仅含有一个不起眼示例功能的非常简单的事情。

这里是test.c的内容:

#include <dlfcn.h> 
#include <stdlib.h> 
#include <stdio.h> 

typedef void * (*dltest)(int); 

int main(int argc, char ** argv) { 

    /* Declare and set a pointer to a function in the executable */ 
    void * handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); 
    dlerror(); 
    dltest fn = dlsym(handle, "testing"); 

    if(fn == NULL) { 
     printf("%s\n", dlerror()); 
     dlclose(handle); 
     return 1; 
    } 
    dlclose(handle); 
    return 0; 
} 

正如我通过与调试器的代码步骤,我看到的dlopen返回一个句柄。根据手册页,If filename is NULL, then the returned handle is for the main program.因此,如果我将一个名为testing的符号链接到主程序中,dlsym应该找到它,对不对?

这里是我编译和链接程序的方式:

all: test 

instr.o: instr.c 
    gcc -ggdb -Wall -c instr.c 

test.o: test.c 
    gcc -ggdb -Wall -c test.c 

test: test.o instr.o 
    gcc -ldl -o test test.o instr.o 

clean: 
    rm -f *.o test 

当我建立这个程序,然后做objdump -t test | grep testing,我看到符号testing确实存在:

08048632 g  F .text 00000020    testing 

然而,我的程序的输出是错误:

./test: undefined symbol: testing 

我不知道我做错了什么。如果有人能够解决这个问题,我将不胜感激。

+2

http://coliru.stacked-crooked.com/a/3048847bea8edb97添加:'-Wl, - export-dynamic'使您的程序可以正常工作。没有它,你会得到错误'未定义的符号:'testing''。 – Brandon

回答

4

我不认为你可以那样做,dlsym适用于导出的符号。因为你在做dlsymNULL(当前图像),即使符号存在于可执行的ELF图像中,它们也不会被导出(因为它不是共享库)。

为什么不直接调用它并让链接器照顾它呢?使用dlsym从与您的dlsym呼叫相同的图像中获取符号没有意义。如果您的testing符号位于您使用dlopen链接或加载的共享库中,那么您将能够检索它。

我相信当构建可执行文件时(-Wl,--export-dynamic,在Brandon的评论中提到),也有一种导出符号的方法,但我不确定为什么要这么做。

+0

ELF程序和ELF共享库几乎没有区别。实际上,一些共享库包含'main()'函数,可以作为程序运行。 ELF“程序”无法作为共享库加载的原因没有特别的理由。尽管如此,我相信你是对的,问题是这个符号不会被导出。 –

相关问题