
昨日、この C++ プログラムを Ubuntu Linux 16.04 でテストしました。気になるのは、次のプログラムが、Ubuntu 16.04 の /var/log/syslog ファイルで確認したように、プログラムでモノサービスを開始するものの、システム コールLD_LIBRARY_PATH
に envp ポインターを渡しても、C# 実行可能ファイルのランタイム環境に渡されない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
そして「オープン」コールを探します。
原則として、Linux上の任意の共有実行ファイルで実行できますldd
。例:
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
参考文献: