我正在研究FFmpeg的补丁,需要调试我的代码。我正在加载一个外部库,为了测试不同的库版本,我将它们放在不同的文件夹中。要选择我想要使用的那个,我一直在使用DYLD_LIBRARY_PATH=/path/to/lib/dir ./ffmpeg
,这样就行了。但是当我在lldb
内尝试时,它会崩溃说dyld: Library not loaded
和Reason: image not found
。这曾经用于Xcode 7.1之前的版本,但我刚刚升级并停止工作。
这是我的MVCE:
#include <stdio.h>
#include <stdlib.h>
int main() {
char* str = getenv("DYLD_LIBRARY_PATH");
if (str) puts(str);
else puts("(null)");
return 0;
}
按如下方式运行此程序会产生输出:
$ ./a.out
(null)
$ DYLD_LIBRARY_PATH=/tmp ./a.out
/tmp
看起来没问题。但是当我尝试使用lldb时,它失败了:
$ DYLD_LIBRARY_PATH=/tmp lldb ./a.out
(lldb) target create "./a.out"
Current executable set to './a.out' (x86_64).
(lldb) run
Process 54255 launched: './a.out' (x86_64)
(null)
Process 54255 exited with status = 0 (0x00000000)
尝试在lldb中设置环境变量:
lldb ./a.out
(lldb) target create "./a.out"
Current executable set to './a.out' (x86_64).
(lldb) env DYLD_LIBRARY_PATH=/tmp
(lldb) run
Process 54331 launched: './a.out' (x86_64)
/tmp
Process 54331 exited with status = 0 (0x00000000)
lldb版本(它来自Xcode 7.1):
$ lldb --version
lldb-340.4.110
问题:这是一个新的“功能”,还是lldb中的一个新错误(或者我完全疯了,这从未使用过)?我很乐意lldb用来转发DYLD_LIBRARY_PATH
环境变量,那怎么回事呢?
编辑:这是在OS X 10.11.1上。
答案 0 :(得分:26)
如果这是在El Capitan(OS X 10.11)上,那么它几乎肯定是系统完整性保护的副作用。来自ECMA-262文章:
当一个进程启动时,内核会检查是否为main 可执行文件在磁盘上受保护或使用特殊系统进行签名 权利。如果其中任何一个为真,则设置一个标志来表示它 保护免受修改。 ...
......任何动态链接器(
dyld
) 环境变量(例如DYLD_LIBRARY_PATH
)在清除时被清除 启动受保护的流程。
/ usr / bin中的所有内容都以这种方式受到保护。因此,当您调用/ usr / bin / lldb时,将清除所有DYLD_ *环境变量。
它应该可以在Xcode.app或命令行工具中运行lldb,如下所示:
DYLD_LIBRARY_PATH=whatever /Applications/Xcode.app/Contents/Developer/usr/bin/lldb <whatever else>
我不相信lldb的副本受到保护。 / usr / bin / lldb实际上只是一个在Xcode或命令行工具中执行版本的蹦床,所以你最终会运行相同的东西。但是/ usr / bin / lldb受到保护,因此在运行时会清除DYLD_ *环境变量。
否则,您必须在lldb中设置环境变量,如System Integrity Protection Guide: Runtime Protections所示:
(lldb) process launch --environment DYLD_LIBRARY_PATH=<mydylibpath> -- arg1 arg2 arg3
或使用短-v选项:
(lldb) process launch -v DYLD_LIBRARY_PATH=<mydylibpath> -- arg1 arg2 arg3
或者,您可以禁用系统完整性保护,尽管它有用。