はじめに
今回のネタは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 が有効だから接続できません。って書いてありました。