
我昨天在 Ubuntu Linux 16.04 上測試了這個 C++ 程式。令我困擾的是,以下程式以程式設計方式啟動單一服務,我在 Ubuntu 16.04 /var/log/syslog 檔案中看到該服務,但無法將其傳遞LD_LIBRARY_PATH
到C# 執行檔的執行時間環境,即使我將envp 指標傳遞給execve
系統呼叫。我可以判斷LD_LIBRARY_PATH
目標可執行檔的運行時環境無法識別環境變數的方法是,目標可執行檔案行為不當並跳過所有LD_LIBRARY_PATH
告訴在何處查找運行時庫依賴項的函數。
#include <unistd.h> // execv(), fork()
#include <sys/types.h> // pid_t
#include <sys/wait.h> // waitpid()
#include <stdio.h>
int main(int argc, char* argvp)
{
char *argv[] = { "/usr/lib/mono/4.5/mono-service.exe",
"Audio_Video_Recorder.exe", 0};
char *envp[] =
{
"LD_LIBRARY_PATH=.",
0
};
execve(argv[0], &argv[0], envp);
fprintf(stderr, "Oops!\n");
return -1;
}
是否可以使用 C++ 和 Linux API 以程式方式修復此疏忽?
答案1
由於基於 Debian/Ubuntu,問題不太可能是由於 rpath 造成的(仍然有可能)。您更有可能遇到麻煩
"LD_LIBRARY_PATH=."
它不提供絕對路徑名。
您可以用來strace
顯示可執行檔嘗試開啟哪些路徑,例如,
strace -f -o strace.log mono myprogram
並尋找“開放”的電話。
原則上,您可以ldd
在 Linux 上的任何共享可執行檔上運行,例如
ldd myprogram
或(可能)
ldd /usr/lib/mono/4.5/mono-service.exe
同樣,objdump 提供有用的信息,例如,
objdump -ax /usr/lib/mono/4.5/mono-service.exe
查看是否有任何共享庫是透過絕對路徑名解析的。 obdump 應該在(其輸出的)「動態庫」部分。
然而,評論中.NET/Mono 應用程式的 ldd 的等效項表明您可能需要更高級別(和不同的工具)來獲取有用的信息,例如透過設定環境變數;
$ MONO_LOG_LEVEL=debug mono myprogram
延伸閱讀: