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

时间:2022-04-02 23:29:46

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.

我正在为FFmpeg编写补丁,需要调试我的代码。我正在加载一个外部库,为了测试不同的库版本,我将它们放在不同的文件夹中。要选择我想要使用的那个,我一直在使用DYLD_LIBRARY_PATH = / path / to / lib / dir ./ffmpeg,这样可以正常工作。但是当我在lldb中尝试它时,崩溃说dyld:库未加载而原因:图像未找到。这曾经用于Xcode 7.1之前,但我刚刚升级,它停止工作。


Here's my MVCE:

这是我的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

That looks okay. But when I try to use lldb it fails:

那看起来还不错。但是当我尝试使用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)

Trying to set the environment variable inside lldb works:

尝试在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 version (it's from Xcode 7.1):

lldb版本(它来自Xcode 7.1):

$ lldb --version
lldb-340.4.110

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?

问题:这是一个新的“功能”,还是lldb中的一个新bug(或者我完全疯了,这从未使用过)?我很乐意lldb用来转发DYLD_LIBRARY_PATH环境变量,那怎么回事呢?


Edit: This is on OS X 10.11.1.

编辑:这是在OS X 10.11.1上。

1 个解决方案

#1


23  

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:

如果这是在El Capitan(OS X 10.11)上,那么它几乎肯定是系统完整性保护的副作用。从“系统完整性保护指南:运行时保护”一文中:

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.

...启动受保护的进程时,将清除任何动态链接器(dyld)环境变量,例如DYLD_LIBRARY_PATH。

Everything in /usr/bin is protected in this fashion. Therefore, when you invoke /usr/bin/lldb, all DYLD_* environment variables are purged.

/ usr / bin中的所有内容都以这种方式受到保护。因此,当您调用/ usr / bin / lldb时,将清除所有DYLD_ *环境变量。

It should work to run lldb from within Xcode.app or the Command Line Tools, like so:

它应该可以在Xcode.app或命令行工具中运行lldb,如下所示:

DYLD_LIBRARY_PATH=whatever /Applications/Xcode.app/Contents/Developer/usr/bin/lldb <whatever else>

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的副本受到保护。 / usr / bin / lldb实际上只是一个在Xcode或命令行工具中执行版本的蹦床,所以你最终运行同样的东西。但是/ usr / bin / lldb受到保护,因此运行时会清除DYLD_ *环境变量。

Otherwise, you will have to set the environment variable inside lldb as shown by Greg Clayton in that thread you linked. Or, you can disable System Integrity Protection, although it serves a good purpose.

否则,您必须在Lldb中设置环境变量,如Greg Clayton在您链接的那个线程中所示。或者,您可以禁用系统完整性保护,尽管它有很好的用途。

#1


23  

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:

如果这是在El Capitan(OS X 10.11)上,那么它几乎肯定是系统完整性保护的副作用。从“系统完整性保护指南:运行时保护”一文中:

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.

...启动受保护的进程时,将清除任何动态链接器(dyld)环境变量,例如DYLD_LIBRARY_PATH。

Everything in /usr/bin is protected in this fashion. Therefore, when you invoke /usr/bin/lldb, all DYLD_* environment variables are purged.

/ usr / bin中的所有内容都以这种方式受到保护。因此,当您调用/ usr / bin / lldb时,将清除所有DYLD_ *环境变量。

It should work to run lldb from within Xcode.app or the Command Line Tools, like so:

它应该可以在Xcode.app或命令行工具中运行lldb,如下所示:

DYLD_LIBRARY_PATH=whatever /Applications/Xcode.app/Contents/Developer/usr/bin/lldb <whatever else>

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的副本受到保护。 / usr / bin / lldb实际上只是一个在Xcode或命令行工具中执行版本的蹦床,所以你最终运行同样的东西。但是/ usr / bin / lldb受到保护,因此运行时会清除DYLD_ *环境变量。

Otherwise, you will have to set the environment variable inside lldb as shown by Greg Clayton in that thread you linked. Or, you can disable System Integrity Protection, although it serves a good purpose.

否则,您必须在Lldb中设置环境变量,如Greg Clayton在您链接的那个线程中所示。或者,您可以禁用系统完整性保护,尽管它有很好的用途。