问题描述
我正在为FFmpeg制作补丁程序,需要调试我的代码.我正在加载一个外部库,并且为了测试不同的库版本,我将它们放在不同的文件夹中.要选择我要使用的那个,我一直在使用DYLD_LIBRARY_PATH=/path/to/lib/dir ./ffmpeg
,它可以正常工作.但是,当我在lldb
中尝试它时,它会崩溃,提示dyld: Library not loaded
和Reason: image not found
.以前可以在Xcode 7.1之前运行,但是我最近才进行了升级,因此它停止了工作.
I'm working on a patch for FFmpeg and need to debug my code. I'm loading an external library, and in order to test different library versions, I have them in different folders. To select which one I want to use, I've been using DYLD_LIBRARY_PATH=/path/to/lib/dir ./ffmpeg
and that works okay. But when I try it within lldb
, it crashes saying dyld: Library not loaded
and Reason: image not found
. This used to work pre-Xcode 7.1, but I just recently upgraded and it stopped working.
这是我的MVCE:
#include <stdio.h>
#include <stdlib.h>
int main() {
char* str = getenv("DYLD_LIBRARY_PATH");
if (str) puts(str);
else puts("(null)");
return 0;
}
按以下方式运行该程序会产生输出:
Running this program as follows produces the output:
$ ./a.out
(null)
$ DYLD_LIBRARY_PATH=/tmp ./a.out
/tmp
这看起来还不错.但是当我尝试使用lldb时,它会失败:
That looks okay. But when I try to use lldb it fails:
$ 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中设置环境变量的工作原理:
Trying to set the environment variable inside lldb works:
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 (it's from Xcode 7.1):
$ lldb --version
lldb-340.4.110
问题:这是否是预期的新功能",或者这是lldb中的新错误(或者我完全疯了,而且从未使用过)?我非常肯定lldb用来转发DYLD_LIBRARY_PATH
环境变量,所以它怎么了?
Question: Is this an intended new "feature," or is this a new bug in lldb (or am I totally crazy and this never used to work)? I'm quite positive lldb used to forward the DYLD_LIBRARY_PATH
environment variable, so how come it isn't anymore?
这是在OS X 10.11.1.上
This is on OS X 10.11.1.
推荐答案
如果在El Capitan(OS X 10.11)上使用,则几乎可以肯定是系统完整性保护的副作用.来自系统完整性保护指南:运行时保护文章:
If this is on El Capitan (OS X 10.11), then it's almost certainly a side effect of System Integrity Protection. From the System Integrity Protection Guide: Runtime Protections article:
…任何动态链接器(dyld
) 在以下情况下清除环境变量,例如DYLD_LIBRARY_PATH
启动受保护的进程.
… Any dynamic linker (dyld
) environment variables, such as DYLD_LIBRARY_PATH
, are purged when launching protected processes.
/usr/bin中的所有内容都以这种方式受到保护.因此,当您调用/usr/bin/lldb时,将清除所有DYLD_ *环境变量.
Everything in /usr/bin is protected in this fashion. Therefore, when you invoke /usr/bin/lldb, all DYLD_* environment variables are purged.
应该可以从Xcode.app或命令行工具中运行lldb,如下所示:
It should work to run lldb from within Xcode.app or the Command Line Tools, like so:
DYLD_LIBRARY_PATH=whatever /Applications/Xcode.app/Contents/Developer/usr/bin/lldb <whatever else>
我认为lldb的副本不受保护. /usr/bin/lldb实际上只是一个蹦床,可以在Xcode或命令行工具中执行该版本,因此最终您将运行相同的东西.但是/usr/bin/lldb受保护,因此在运行时会清除DYLD_ *环境变量.
I don't believe that copy of lldb is protected. /usr/bin/lldb is actually just a trampoline that executes the version in Xcode or the Command Line Tools, so you're ultimately running the same thing. But /usr/bin/lldb is protected so the DYLD_* environment variables are purged when running that.
否则,您将必须在lldb中设置环境变量,如在该线程中:
Otherwise, you will have to set the environment variable inside lldb as shown in this thread:
(lldb) process launch --environment DYLD_LIBRARY_PATH=<mydylibpath> -- arg1 arg2 arg3
或使用简短的-v选项:
or using the short -v option:
(lldb) process launch -v DYLD_LIBRARY_PATH=<mydylibpath> -- arg1 arg2 arg3
或者,您可以禁用系统完整性保护,尽管它有很好的用途.
Or, you can disable System Integrity Protection, although it serves a good purpose.
这篇关于为什么lldb不再转发我的环境变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!