使用 ld-linux.so 呼叫腳本?

使用 ld-linux.so 呼叫腳本?

我剛剛下載了一個tar文件,該文件應該包含運行我們可以調用的程式所需的所有內容some_binary。我提取了它的內容,我看到以下內容:

  • 一個二進位(我們稱之為some_binary
  • 包含各種動態庫(.so 檔案)的資料夾lib,例如/lib/ld-linux-x86-64.so
  • 和一個名為的 shell 腳本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 "$@"

因為./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僅定義 shell 變量,而不是環境變量,因此程式看不到任何東西。此外,$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" "$@"

相關內容