我昨天在 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
进一步阅读: