2017-05-12 24 views
0

对于我的应用程序,我使用DYLD_INSERT_LIBRARIES来切换库。我正在运行Mac OS X,El Capitan。当通过bash调用应用程序时,dyld_insert_libraries被忽略

如果我设置在我的壳这些环境变量:

export PYTHONHOME=${HOME}/anaconda 
export DYLD_INSERT_LIBRARIES=${HOME}/anaconda/lib/libpython2.7.dylib:${HOME}/anaconda/lib/libmkl_rt.dylib 

如果我直接启动我的应用程序,它工作正常。但是,如果我通过我写的bash脚本调用它,DYLD_INSERT_LIBRARIES将被忽略。

如果我将相同的2行添加到我的bash脚本,我的应用程序再次工作。

看起来DYLD_INSERT_LIBRARIES在调用bash脚本时未被设置,正如本测试脚本所证明的。

#!/bin/bash 
set -e 
echo ${DYLD_INSERT_LIBRARIES} 

有什么办法让bash脚本继承并传递下去DYLD_INSERT_LIBRARIES

+0

为什么不将导出添加到您的配置文件或脚本中? –

+0

这个脚本应该是跨平台的。 ''DYLD_INSERT_LIBRARIES''应该可以在启动脚本中用我的应用程序的命令调用。现在我更加好奇如何让bash兑现DYLD_INSERT_LIBRARIES和DYLD_LIBRARY_PATH。 – Juan

+0

'DYLD_INSERT_LIBRARIES'不适用于Linux,它是'LD_PRELOAD'。 –

回答

1

这是最近的macOS版本的安全特性。

系统bash可执行文件已被标记为“restricted”,禁用DYLD_ *功能。要解决此问题,您可以制作bash的副本,然后使用它。

通过在dyld的实现中查找以下详细信息,我发现此限制至少回到10.6。

在MacOS的10.13 dyldimplementation这个逻辑是pruneEnvironmentVariables,与注释:

// For security, setuid programs ignore DYLD_* environment variables. 
// Additionally, the DYLD_* enviroment variables are removed 
// from the environment, so that any child processes don't see them. 

但是设置限制的实际逻辑是configureProcessRestrictions

// any processes with setuid or setgid bit set or with __RESTRICT segment is restricted 
if (issetugid() || hasRestrictedSegment(mainExecutableMH)) { 
    gLinkContext.processIsRestricted = true; 
} 
... 
if (csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1) { 
    // On OS X CS_RESTRICT means the program was signed with entitlements 
    if (((flags & CS_RESTRICT) == CS_RESTRICT) && usingSIP) { 
     gLinkContext.processIsRestricted = true; 
    } 
    // Library Validation loosens searching but requires everything to be code signed 
    if (flags & CS_REQUIRE_LV) { 
     gLinkContext.processIsRestricted = false; 
... 

正如你所看到的它取决于issetugid,hasRestrictedSegmentCS_RESTRICT/SIP权利。您可以直接测试受限状态,或者您可以根据这些信息构建一个函数来自己测试这些条件。

相关问题