質問

質問

乾いた男

私はPHPをApacheモジュール(libphp56.so)として構築し、それをMacPortsのlibcurlに接続しました。ただし、libphp56.soがロードされると、httpdは起動時に(launchdを介して)失敗し、ライブラリバージョンの不一致エラーを出力します。

脂肪

PHPの設定スクリプトを実行し、--with-curl=/opt/localそれを/opt/local/lib/libcurl.4.dylib(MacPortsから提供)に関連付けました。 libcurlのコピーはバージョン9.0.0ですが、dyldはバージョン7.0.0(/usr/lib/libcurl.4.dylibのバージョン)をロードすると主張します。現在、後者がロードされていると仮定します。

apachectlhttpdを実行するには呼び出しますlaunchctl。直接実行すると、httpdはlibphp56.soをロードし、エラーなしで実行されます。

以下はコマンドラインの関連情報です(読みやすくするためにスペースが追加されています)。

$ sudo -s
#apachectl設定テスト
httpd:/private/etc/apache2/httpd.conf 行 174 に構文エラーがあります:
libexec/apache2/libphp56.so をサーバーにロードできません:
dlopen(/Library/WebServer/libexec/apache2/libphp56.so, 10):
ロードされていないライブラリ:/opt/local/lib/libcurl.4.dylib

引用:/Library/WebServer/libexec/apache2/libphp56.so
理由:ライブラリバージョンの非互換性:libphp56.soにはバージョン9.0.0以降が必要ですが、libcurl.4.dylibはバージョン7.0.0を提供しています。

# /usr/sbin/httpd
# ps -ax -O gid | grep /usr/sbin/httpd |
 6878 0 ?? SS 0:00.22 /usr/sbin/httpd
 6901 70 ?? S 0:00.00 /usr/sbin/httpd
 6907 0 s008 S+ 0:00.00 grep --color=auto /usr/sbin/httpd
#終了期間6878

# otool -L /opt/local/lib/libcurl.4.dylib grep libcurl関数|
/opt/local/lib/libcurl.4.dylib:
    /opt/local/lib/libcurl.4.dylib (互換バージョン 9.0.0、現在のバージョン 9.0.0)

# otool -L /usr/lib/libcurl.4.dylib grep libcurl関数|
/usr/lib/libcurl.4.dylib:
    /usr/lib/libcurl.4.dylib (バージョン7.0.0、現在のバージョン8.0.0と互換性があります)

#otool -L /Library/WebServer/libexec/apache2/libphp56.so grep libcurl関数|
    /opt/local/lib/libcurl.4.dylib (互換バージョン 9.0.0、現在のバージョン 9.0.0)

# エコー "x${DYLD_LIBRARY_PATH}x"
ダブルX
# grep -r 'DYLD_.*_PATH' /etc
#launchctl getenv DYLD_LIBRARY_PATH

httpdのlaunchd.plistは非常に基本的です。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Disabled</key>
    <false/>
    <key>EnvironmentVariables</key>
    <dict>
      <key>XPC_SERVICES_UNAVAILABLE</key>
      <string>1</string>
    </dict>
    <key>KeepAlive</key>
    <dict>
      <key>SuccessfulExit</key>
      <false/>
    </dict>
    <key>Label</key>
    <string>org.apache.httpd</string>
    <key>ProgramArguments</key>
    <array>
      <string>/usr/sbin/httpd</string>
      <string>-D</string>
      <string>FOREGROUND</string>
    </array>
  </dict>
</plist>

設定ディアド環境変数を報告DYLD_PRINT_TO_FILEし、launchd 設定 DYLD_LIBRARY_PATHDYLD_PRINT_ENVおよびDYLD_PRINT_LIBRARIES/usr/lib/libcurl.4.dylib ロードを表示します。

#DYLD_PRINT_TO_FILE=~/httpd.log DYLD_PRINT_ENV=1 DYLD_PRINT_LIBRARIES=1 apachectl configtest
# grep -P 'curl|DYLD_' ~/httpd.log
DYLD_PRINT_TO_FILE=/Users/Capra/httpd.log
DYLD_PRINT_LIBRARIES=1
DYLD_PRINT_ENV=1
DYLD_PRINT_LIBRARIES=1
DYLD_PRINT_TO_FILE=/Users/Capra/httpd.log
DYLD_LIBRARY_PATH=/usr/lib
DYLD_PRINT_ENV=1
dyld: ロード済み: /usr/lib/libcurl.4.dylib
# エコ > ~/http.log
#DYLD_PRINT_TO_FILE=~/httpd.log DYLD_PRINT_ENV=1 DYLD_PRINT_LIBRARIES=1 /usr/sbin/httpd -D FOREGROUND
^C
# grep -P 'curl|DYLD_' ~/httpd.log
DYLD_PRINT_TO_FILE=/Users/Capra/httpd.log
DYLD_PRINT_LIBRARIES=1
DYLD_PRINT_ENV=1
dyld: ロード済み: /opt/local/lib/libcurl.4.dylib
dyld: 削除済み: /opt/local/lib/libcurl.4.dylib
dyld: ロード済み: /opt/local/lib/libcurl.4.dylib

libcurlがこの問題を経験する唯一のライブラリではないことに注意してください。問題の解決中に、ビルドプロセスでPHPのカール拡張が欠落しており、libxmlに関連する同様のメッセージを受け取りました。

質問

DYLD_LIBRARY_PATHlaunchdで実行するときにhttpdをオフにする方法は?安全の結果は何ですか?

試してみるソリューション

  • launchctl unsetenv DYLD_LIBRARY_PATH
  • DYLD_LIBRARY_PATHorg.apache.httpd.plistに設定します。
  • org.apache.httpd.plistがhttpdのラッパーを実行して設定するようにします。DYLD_LIBRARY_PATH

解決策ではありません

システムlibcurlにリンクできますが、PHPが最新のコンポーネントで実行されるようにする方法を探しています。 /usr/lib/libcurl.4.dylibへのリンクは最後の手段です。 launchdを完全に回避し、影響を受けるPHP拡張/ライブラリをビルドに含めず、システムlibcurlを置き換えることもソリューションではないと考えられます。私は取り外し可能な包装紙を持つことをほとんど考えます。

システムメッセージ

  • オペレーティングシステム:Mac OS X 10.10.5ヨセミテ。
  • Webサーバー:Apache 2.4.16
  • PHP 5.6.31

関連情報