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 как упоминалось в комментарии Брэндона), но я не уверен, почему вы хотите это сделать.