Установка моей библиотеки для LD_PRELOAD приводит к тому, что некоторые процессы вызывают ошибки загрузчика

Я получаю следующую ошибку, когда пытаюсь запустить скрипт, для которого у меня есть доступ только к исполнению:

uname: symbol lookup error: /home/dumindara/random/sotest/a.out: undefined symbol: dlsym

Это произошло после того, как я установил для переменной среды LD_PRELOAD значение /home/dumindara/random/sotest/a.out.

a.out имеет тестовую функцию malloc и вызывает dlsym внутри.

У меня нет этой проблемы при запуске ls. Большинство процессов выдают эту ошибку. Почему это происходит и что я могу сделать, чтобы это сработало?


person nakiya    schedule 08.12.2010    source источник
comment
Обычно рекомендуется устанавливать LD_PRELOAD только для a.out, а не изменять среду оболочки. В большинстве оболочек UNIX вы можете ввести: LD_PRELOAD=xyz ./a.out. В противном случае попробуйте ( LD_PRELOAD=xyz; ./a.out ).   -  person Tony Delroy    schedule 08.12.2010
comment
@Tony: я думаю, что в данном случае a.out является общим объектом, несмотря на неудачно выбранное имя. ОП, по-видимому, пытается переопределить malloc() своей собственной версией, а затем перейти к настоящему malloc.   -  person thkala    schedule 08.12.2010
comment
@tkhala: ах, хороший улов... тогда было бы больше похоже на LD_PRELOAD=`pwd`/a.out program_to_test....   -  person Tony Delroy    schedule 08.12.2010


Ответы (2)


Я предполагаю, что ваш файл a.out является общим объектом, а не исполняемым файлом, и идем дальше...

dlsym() — это функция из библиотеки libdl, которая обычно находится в общем объекте libdl.so.2 в современных системах Linux.

Я рискну предположить, что ваш общий объект a.out не связан с libdl. Это означает, что когда вы предварительно загружаете простой двоичный файл, такой как uname, который не использует множество других библиотек, libdl.so.2 может не загружаться, и вы получаете ошибку неопределенного символа.

Если, с другой стороны, вы предварительно загрузите его в двоичный файл, который связан с libdl.so.2 и, наконец, загрузит его, ваш общий объект будет работать нормально.

Я бы проверил с помощью ldd, связан ли ваш собственный общий объект с libdl должным образом, а также какие библиотеки прямо или косвенно подключаются при запуске uname и ls.

РЕДАКТИРОВАТЬ:

Я только что подтвердил это. Способ исправить эту ошибку — связать ваш общий объект с libdl. Добавление -ldl к его LDFLAGS должно помочь.

person thkala    schedule 08.12.2010
comment
Обратите внимание, что -ldl может потребоваться перед другими файлами .o, например. gcc -ldl -shared foo.o bar.o -o baz.so. - person Mr Fooz; 08.05.2012
comment
Как упоминалось в ответе ниже, -ldl на самом деле должно идти в конце строки gcc, если компоновка и компиляция выполняются вместе. Я читал объяснение, что gcc строит список символов из файлов, а затем ищет их в библиотеках, которые почему-то указаны после их имен. - person Marisha; 01.10.2019

Я не могу прокомментировать принятый ответ, однако здесь стоит упомянуть, что можно столкнуться с проблемой неправильной компоновки libdl.so.2, когда -ldl используется перед командой компиляции (при условии, что компоновка и компиляция выполняются командой ту же команду; это возможно, поскольку библиотеки LD_PRELOAD обычно основаны на одном исходном файле).

Итак, вызовите gcc с -ldl в конце:

gcc -shared -fPIC fakeuname.c -o libfakeuname.so -ldl

В моем случае наличие -ldl впереди привело к ошибке, такой же, как в вопросе:

uname: symbol lookup error: ./libfakehostname.so: undefined symbol: dlsym

person kraju    schedule 24.10.2012
comment
да палец вверх!!! Ответ thkala все еще выдавал мне ошибку, но ваш -ldl в конце все решил. - person Peter Teoh; 16.10.2015