Вызов скрипта с помощью ld-linux.so?

Вызов скрипта с помощью ld-linux.so?

Я только что скачал tarфайл, который должен включать все необходимое для запуска программы, которую мы можем назвать some_binary. Я извлек его содержимое и вижу следующее:

  • Двоичный файл (назовем его так some_binary)
  • Папка libс различными динамическими библиотеками (файлы .so), такими как/lib/ld-linux-x86-64.so
  • и скрипт оболочки под названиемsome_binary.sh

Скрипт имеет следующее содержание:

#!/bin/bash
`dirname "$0"`/lib/ld-linux-x86-64.so.2   `dirname "$0"`/some_binary "$@"

и запуск его как ./some_binary.sh some argumentsкажется работает ./some_binaryправильно. Как ни странно, запуск следующего скрипта:

#!/bin/bash
LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
./some_binary "$@"

as ./my_script.sh some argumentsне работает. Это приводит к ошибкам перемещения (неопределенные символы), предположительно из-за неправильной загрузки библиотек под./lib

Более того, выполнение следующих двух операторов из командной строки приводит к следующему segmentation fault:

> LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
> ./some_binary some arguments

В связи с этим у меня возникли вопросы:

  1. Что делает первый скрипт?
  2. Почему я получаю разные результаты в этих трех попытках? И почему я не могу просто добавить $pwd/libданные LD_LIBRARY_PATHи затем запустить их some_binaryнапрямую?

решение1

Программа поставляется со своим собственнымдинамический загрузчик. Довольно редко программам требуется собственный динамический загрузчик: обычно тот, что есть в вашей системе, тоже подойдет. Это может быть необходимо, если программа была скомпонована со стандартной библиотекой, отличной от GNU libc, или если она была скомпонована с GNU libc, скомпилированной со странными настройками.

Может быть достаточно указать загрузчику, где найти предпочтительные библиотеки программы. Ваша попытка почти делает это, но не совсем. Если LD_LIBRARY_PATHуже нет в среде, то назначение LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATHопределяет только переменную оболочки, а не переменную среды, поэтому программа ничего не видит. Более того, $CWDобычно расширяется до пустой строки, вы, вероятно, имели в виду $PWDили лучше $(dirname "$0")(т. е. каталог, содержащий скрипт). Также будьте осторожны, что вы использовали libи LIBнепоследовательно в своем вопросе. Попробуйте

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
exec "$(dirname "$0")/some_binary" "$@"

или лучше, чтобы избежать пустой записи в конце, LD_LIBRARY_PATHесли она не была определена ранее (это может быть плохо, поскольку пустая запись обозначает текущий каталог, хотя в конце пути она вредна только в том случае, если библиотека не найдена там, где ей положено быть):

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
case "$LD_LIBRARY_PATH" in *:) LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:};; esac
exec "$(dirname "$0")/some_binary" "$@"

Связанный контент