Почему lldb больше не перенаправляет переменную окружения?

Я работаю над патчем для FFmpeg и должен отлаживать свой код. Я загружаю внешнюю библиотеку, и для того, чтобы протестировать разные версии библиотеки, я имею их в разных папках. Чтобы выбрать тот, который я хочу использовать, я использовал DYLD_LIBRARY_PATH=/path/to/lib/dir ./ffmpeg, и это работает нормально. Но когда я пробую его в lldb, он выдает сообщение dyld: Library not loaded и Reason: image not found. Это использовалось для работы с pre-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 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
lldb-340.4.110

Вопрос: Является ли это намеченной новой "функцией", или это новая ошибка в lldb (или я абсолютно сумасшедший, и это никогда не работало)? Я вполне уверен, что lldb используется для перенаправления переменной среды DYLD_LIBRARY_PATH, так как это уже не так?


Изменить: это на OS X 10.11.1.

Ответы

Ответ 1

Если это на El Capitan (OS X 10.11), то это почти наверняка побочный эффект защиты целостности системы. Из Руководства по защите целостности системы: статья по защите времени выполнения:

Когда процесс запускается, ядро проверяет, защищен ли основной исполняемый файл на диске или подписан специальным системным правом. Если любой из них имеет значение true, тогда устанавливается флаг, обозначающий, что он защищен от модификации....

… Любые переменные среды динамического компоновщика (dyld), такие как DYLD_LIBRARY_PATH, очищаются при запуске защищенных процессов.

Все в /usr/bin защищено таким образом. Поэтому, когда вы вызываете /usr/bin/lldb, все переменные окружения DYLD_ * очищаются.

Он должен работать для запуска lldb из Xcode.app или из инструментов командной строки, например:

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

Я не верю, что копия lldb защищена. /usr/bin/lldb - это на самом деле просто батут, который выполняет версию в XCode или в инструментах командной строки, так что в конечном итоге вы выполняете то же самое. Но /usr/bin/lldb защищен, поэтому переменные окружения DYLD_ * очищаются при его запуске.

В противном случае вам придется установить переменную окружения внутри lldb, как показано в этом потоке:

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

или используя короткую опцию -v:

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

Или вы можете отключить защиту целостности системы, хотя она служит хорошей цели.