VSCodeによるPHPのリモートデバッグ

はじめに

今回のネタはCactiですが、筆者はCactiを使うのは始めてなので、Cactiの中身についてはまだ何も知りません。導入作業のどこかでミスをしたのだろうと思いますが、当初デフォルトの admin / admin でログインできなかったので、単にログインできない原因を追求したいがために PHP の実行トレースを行います。

Cacti は Vagrant で建てた CentOS7 ホスト cacti1(192.168.57.74) にインストールされているものとします。なお VSCode は 1.5.4.3 で、Windows10 上で動いています。

PHP

PHP は remi から php-7.3 を入れました。当初 php-7.4 で動かしてみたのですが、ログに【Laravel5.8】PHP7.4でTrying to access array offset on valueが山盛り出るようになった の警告が出て気持ち悪かったので 7.3 に下げました。まぁいずれ直るとは思いますが。

XDebug

まず、PHP のトレースに必要となる xdebug を入れておきます。

$ sudo yum --enablerepo=remi,remi-php73 install php-xdebug
$ sudo vi /etc/php.d/15-xdebug.ini # 以下を追加
$ grep '^[^;]' /etc/php.d/15-xdebug.ini
zend_extension=xdebug.so
xdebug.log = /tmp/xdebug.log
xdebug.mode = debug
xdebug.start_with_request = yes

Xdebug の設定の中に xdebug.client_host という項目があり、デフォルトでは localhost になっているのですが、Windows の VSCode から接続するんだからここは Windows の IP アドレスを入れるべきだろうと判断してちょっとハマりました。後述の Remote-SSH 経由でデバッグする場合、xdebug への接続元 IP は localhost になるようなので、ここはコメントアウトのままでいいようです。

Xdebug の設定を変更したら、変更を反映しておきます。

$ sudo systemctl restart httpd

パーミッションの緩和

VSCode では cacti のトップディレクトリである /usr/share/cacti を開くことになりますが、/usr/share/cacti 直下に VSCode から .vscode を作成できる必要があるので、一時的にパーミッションを空けます。

$ sudo chmod o+w /usr/share/cacti

今回は追跡だけなので不要ですが、VSCode から Cacti 自体のソースコードを変更したい場合は、各ファイルに対しても SSH 接続ユーザ(vagrant)からの write 権が必要になります。

SSH 設定

Remote-SSH on VSCode の設定は終わっているものとします。まだの方はVSCodeでリモートデバッグ(SSH編)を参照して、インストールとおおよその使い方を把握しておいてください。

OpenSSH for Windows の設定は以下の通りです:

PS C:\Users\hotta\vm\zabbix> sed -n '63,66p' $env:USERPROFILE/.ssh/config
Host  cacti1
  Hostname 192.168.56.74
  User  vagrant
  IdentityFile  "C:\Users\hotta\vm\zabbix\.vagrant\machines\cacti1\virtualbox\private_key"

PS C:\Users\hotta\vm\zabbix> ssh cacti1
Last login: Thu Mar 18 08:38:45 2021 from 192.168.56.1
vagrant@cacti1:~$ exit

VSCode の操作

以下は VSCode で作業します:

1.リモートへの接続
「リモートウィンドウを開きます」>Remote-SSH: Connect to Host>Cacti1>Linux

2.拡張機能で PHP Debug を(ターゲットホストである cacti1 に)インストールします。

3.「フォルダーを開く」>/usr/share/cacti

4.「実行とデバッグ」>「launch.jsonファイルを作成します」

    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
            "stopOnEntry": true,
            "pathMappings": {
                "/usr/share/cacti": "${workspaceRoot}"
            }
        },

今回は上記のように設定しました。Xdebug のデフォルトのポート番号は 9003 になっていたのでこれに合わせましたが、9003 が使用中の場合は別のポートに変更してください。その場合、/etc/php.d/15-xdebug.ini の xdebug.client_port も同じ設定にする必要があります。

なお stopOnEntry は、最初に制御が来たソースの先頭で必ずブレークする設定です。トレースが正しくできることが確認できたら、消してしまっても構いません。

5.VSCodeのエクスプローラに切り替えて、いずれかのphpファイルを選択します。

6.「実行とデバッグ」>「▶Listen for XDebug」

これで VSCode が Listen 状態に入り、XDebug からの接続待ちとなります。

7.ブラウザから http://cacti1/cacti にアクセス

以下のように、index.php の実行行の先頭で止まります。

後は ステップオーバー(F10) ボタンを押してトレースを進めます。ちなみに今回のエラーの原因は、DBへのアクセス部分で以下のエラーが起きていました。

うまく実行が止まってくれない?

久々にやってみたら、なつかしい「実行が止まってくれない」症状が発生。今回のハマりポイントは以下でした。

xdebug.log = /tmp/xdebug.log

このように指定しているのに、そもそも /tmp/xdebug.log が作られていませんでした。あれれ?

これは、PrivateTmp が有効になっていたからでした。systemd ベースでサービスが制御されている場合は、デフォルトで有効になっています。php-fpm で実行していれば前者、Apache httpd 組み込みであれば後者です。

$ grep PrivateTmp /usr/lib/systemd/system/php-fpm.service
PrivateTmp=true
$ grep PrivateTmp /usr/lib/systemd/system/httpd.service
PrivateTmp=true

PrivateTmp が有効な場合、セキュリティのため実際の /tmp は /tmp/systemd-private-XXX-サービス名-YY 配下に作られます。ハッシュ部分はランダムです。

で、xdebug.log ファイルを見てみると、

[14725] [Step Debug] ERR: No permission connecting to debugging client (localhost:9003 (through xdebug.client_host/xdebug.client_port)). This could be SELinux related. :-(

ちゃんと(おそらく)SELinux が有効だから接続できません。って書いてありました。

タイトルとURLをコピーしました