dlsym возвращает NULL, даже если символ существует
Я использую dlsym для поиска символов в моей программе, но он всегда возвращает NULL, которого я не ожидаю. Согласно manpage, dlsym может возвращать NULL, если произошла ошибка или если символ действительно равен NULL. В моем случае я получаю ошибку. Я покажу вам MCVE, который я сделал сегодня вечером.
вот содержание instr.c:
#include <stdio.h>
void * testing(int i) {
printf("You called testing(%d)n", i);
return 0;
}
очень простая вещь, содержащая только ничем не примечательную функцию примера.
здесь содержание теста.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("%sn", dlerror());
dlclose(handle);
return 1;
}
dlclose(handle);
return 0;
}
когда я прохожу через код с отладчиком, я вижу, что dlopen возвращает дескриптор. По словам manpage,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
Я не уверен, что я делаю неправильно. Я был бы признателен, если бы кто-то мог пролить свет на эту проблему.
1 ответов
Я не думаю, что вы можете делать, что dlsym
работает на экспортируемые символы. Потому что ты делаешь dlsym
on NULL
(текущее изображение), даже если символы присутствуют в исполняемом образе ELF, они не экспортируются (поскольку это не общая библиотека).
почему бы не позвонить ему напрямую и позволить компоновщику позаботиться об этом? Нет смысла использовать dlsym
чтобы получить символы из того же изображения, что и ваш dlsym
звонок. Если testing
символ был в общей библиотеке, что вы либо связано против или загружено с помощью dlopen
тогда вы сможете получить его.
Я считаю, что есть также способ экспорта символов при создании исполняемых файлов (-Wl,--export-dynamic
как упоминалось в комментарии Брэндона), но я не уверен, почему вы хотите это сделать.