为什么 lldb 不再转发我的环境变量?

Why doesn't lldb forward my environment variable anymore?

我正在为 FFmpeg 打补丁,需要调试我的代码。我正在加载一个外部库,为了测试不同的库版本,我将它们放在不同的文件夹中。 select 我想用哪个,我一直在用 DYLD_LIBRARY_PATH=/path/to/lib/dir ./ffmpeg 没问题。但是当我在 lldb 内尝试时,它会崩溃并显示 dyld: Library not loadedReason: 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

问题:这是一个新的 "feature," 还是 lldb 中的一个新错误(或者我完全疯了,这从来没有用过)?我非常肯定 lldb 曾经转发 DYLD_LIBRARY_PATH 环境变量,那怎么现在不再了?


编辑:这是在 OS X 10.11.1.

如果这是在 El Capitan (OS X 10.11) 上,那么几乎可以肯定这是系统完整性保护的副作用。来自 System Integrity Protection Guide: Runtime Protections 文章:

When a process is started, the kernel checks to see whether the main executable is protected on disk or is signed with an special system entitlement. If either is true, then a flag is set to denote that it is protected against modification. …

… Any dynamic linker (dyld) environment variables, such as DYLD_LIBRARY_PATH, are purged when launching protected processes.

/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 是受保护的,因此当 运行ning 时 DYLD_* 环境变量被清除。

否则,您将不得不在 lldb 中设置环境变量,如图所示 in this thread:

(lldb) process launch --environment DYLD_LIBRARY_PATH=<mydylibpath> -- arg1 arg2 arg3

或使用简短的 -v 选项:

(lldb) process launch -v DYLD_LIBRARY_PATH=<mydylibpath> -- arg1 arg2 arg3

或者,您可以禁用系统完整性保护,尽管它有很好的用途。