Vdebugというデバッガを紹介します。
実際に動いている様子はDebug Drupal PHP in Vim with Vdebug | Mediacurrentに動画があったので、そちらを見て下さい。
Vdebugを使うにはVimが+python
でコンパイルされている必要があるので、
$ vim --version
で+python
になっているかを確認します。
インストールはShougo/dein.vimなどを使って、インストールしてください。
VdebugはDBGpというプロトコルを使うため、デバッグしたい言語でDBGpが使えるように設定する必要があります。各言語の設定はVdebugのヘルプに載っています(:help VdebugSetUp<言語>
)。
PHP
まずはPHPを例にして使い方を説明していきます(:help VdebugSetUpPHP
)。
Xdebug
PHPでデバッグするにはXdebugが必要です。xdebugのinstallのドキュメントなどを見てインストールしましょう。
Xdebugのremote debugのついての説明はXdebugのRemote Debuggingのドキュメントに書かれています。
XdebugとVdebugを使ったwebページのdebugは以下のように行われます。
+------------------+ +------------------+
| | ---------------> | 80 |
| | HTTP Request | |
| | | |
| 9000 | <--------------- | |
| | DBGP Connect | |
| Vim / Vdebug | | PHP / Xdebug |
| | <--------------> | |
| | DBGP | |
| | | |
| | <--------------- | |
| | HTTP Response | |
+------------------+ +------------------+
左側がVimで、右側がデバッグしたい対象です。
- まず、Vdebugを起動して、xdebug.remote_portで設定したポート(デファルトは9000)をリッスンしておきます。
- デバッグしたいURLにHTTPでリクエストします。このときidekeyと呼ばれる設定も送ります
- idekeyを送られたPHPはxdebug.idekeyに設定された値と一致した場合にxdebug.remote_hostに設定されたホストのxdebug.remote_portに設定されたポートに接続します
- デバッグが開始されます
- デバッグが終了するとHTTPレスポンスが返ります
Xdebugから見て、デバッグクライアントはremoteなので、xdebug.remote_...
という設定名になっています。
PHPとVimが同じ環境で動いている場合の設定
例えば、PCでPHPを動かしてVimでデバッグする場合や、サーバでPHPを動かしてそのサーバのVimでデバッグする場合、PHPのiniファイルを以下のようの設定します。
; 1にするとxdebug.remote_hostとxdebug.remote_portで設定したホストとポートをリッスンしているデバッグクライアントに
; 接続を試みるようになる。defaultは0。
xdebug.remote_enable=1
; 設定したidekeyと同じ値がPHPに送られたときにデバッグを開始する。周りの人がPhpStormを使っているなら、PHPSTORMなど。
xdebug.idekey="PHPSTORM"
; デバッグクライアントのホスト。defaultはlocalhost。
xdebug.remote_host=localhost
; デバッグクライアントがリッスンしているポート。defaultは9000。
xdebug.remote_port=9000
; HTTPのGET/POST/COOKIEのの設定にかかわらずデバッグの開始を試みる。defaultは0。
xdebug.remote_autostart=1
最後のxdebug.remote_autostart=1
は0にしても、後で入れるブラウザ拡張がうまくやって、デバッグを開始してくれるはずですが、開始しないので入れています。
サーバ上でPHPを動かして、PC上のVimでデバッグする場合
PHPのiniファイルを以下のようの設定します。
; 1にするとxdebug.remote_hostとxdebug.remote_portで設定したホストとポートをリッスンしているデバッグクライアントに
; 接続を試みるようになる。defaultは0。
xdebug.remote_enable=1
; 設定したidekeyと同じ値がPHPに送られたときにデバッグを開始する。周りの人がPhpStormを使っているなら、PHPSTORMなど。
xdebug.idekey="PHPSTORM"
; 1にするとHTTPでリクエストして来たIPに接続を試みるようになる。defaultは0
xdebug.remote_connect_back=1
; デバッグクライアントがリッスンしているポート。defaultは9000
xdebug.remote_port=9000
; HTTPのGET/POST/COOKIEのの設定にかかわらずデバッグの開始を試みる。defaultは0。
xdebug.remote_autostart=1
xdebug.remote_host
にPCのIPアドレスを設定することでもデバッグできますが、それだと一つのPCしか接続できません。xdebug.remote_connect_back
を使うと複数のPCで同時にデバッグをすることが出来ます。
サーバ上のファイルと、PC上のファイルのマッピングはg:vdebug_options['path_maps']
で設定します。この部分の設定だけを設定することは出来ないので、まず、デフォルトの設定をします。
let g:vdebug_options= {
\ "port" : 9000,
\ "server" : '',
\ "timeout" : 20,
\ "on_close" : 'detach',
\ "break_on_open" : 1,
\ "ide_key" : '',
\ "path_maps" : {},
\ "debug_window_level" : 0,
\ "debug_file_level" : 0,
\ "debug_file" : "",
\ "watch_window_style" : 'expanded',
\ "marker_default" : '⬦',
\ "marker_closed_tree" : '▸',
\ "marker_open_tree" : '▾'
\}
ide_keyは空のままでも大丈夫です。設定するとデバッグの対象をide_keyで絞り込みます。
そして、ファイルパスのマッピングの設定をします。
let g:vdebug_options['path_maps'] = {"/path/to/server/scripts": "/path/to/local/scripts"}
サーバ上でPHPが動いていて、PCでデバッグしたい人と、サーバ上でデバッグしたい人がいる場合
PCでデバッグしたい人はxdebug.remote_connect_back=1
とすることでデバッグ出来ますが、サーバ上でデバッグしたい人はlocalhostに接続してほしいので両立しません。
解決策1: サーバ上でデバッグしたいしたい人がサーバ上からリクエストする
サーバ上でデバッグしたい人が、そのサーバ上でcurl
やテキストブラウザでリクエストすれば、remote_connect_back先はそのサーバになるのでデバッグできます。ただ、PCのブラウザを使いたいですよね……。
解決策2: プロキシを立てる
Remote DebuggingのドキュメントのMultiple Users DebuggingのDBGp proxyを使い、remote_hostをproxyに設定して、proxyが振り分けるようにするとうまくいくかもしれません。
ブラウザ拡張
ブラウザからデバッグを開始したい場合は、例えばchromeの場合、Xdebug helperという拡張をインストールします1。オプションでidekeyを設定します。
デバッグの仕方
まず、VimでF5を押してデバッガを起動します。
次にwebページをデバッグしたい場合はインストールしたブラウザ拡張のDebugをonにしてアクセスします。
コマンドラインからPHPを実行する場合は、環境変数XDEBUG_CONFIGにidekeyを設定して、PHPを起動します。
XDEGUG_CONFIG="idekey=PHPSTORM" php script.php
PHPUnitを使ったテストもデバッグできます。ただし、関数名に日本語を使っていると落ちます。
XDEGUG_CONFIG="idekey=PHPSTORM" php /path/to/phpunit ...
実行後、Vimを見ると、コードの最初の行で止まっているので、F2などを押してステップ実行していきます。
デフォルトのキーは以下の通り。
<F5>: start/run (to next breakpoint/end of script)
<F2>: step over
<F3>: step into
<F4>: step out
<F6>: stop debugging (kills script) (すでにデバッグが終わっている場合はデバッガUIを閉じます)
<F7>: detach script from debugger
<F9>: run to cursor
<F10>: toggle line breakpoint
<F11>: show context variables (e.g. after "eval")
<F12>: evaluate variable under cursor
自分で設定することもできます。
let g:vdebug_keymap = {
\ "run" : "<F5>",
\ "run_to_cursor" : "<F9>",
\ "step_over" : "<F2>",
\ "step_into" : "<F3>",
\ "step_out" : "<F4>",
\ "close" : "<F6>",
\ "detach" : "<F7>",
\ "set_breakpoint" : "<F10>",
\ "get_context" : "<F11>",
\ "eval_under_cursor" : "<F12>",
\ "eval_visual" : "<Leader>e",
\}
デバッグ開始時にスクリプトの最初の行で止まらずにブレークポイントまで進んでほしい場合は
let g:vdebug_options["break_on_open"] = 0
という設定をします。
うまくいかない場合
xdebug.remote_log=/tmp/xdebug.log
を設定して、ログを確認してみるといいかもしれません。
他の言語
Vdebugのヘルプを見ると他にもPython, Perl, Ruby, Nodejs, TClでデバッグができるようです。どれもKomodo Remote Debugging Packageを使います。VdebugのヘルプとKomodoのDebugging your programsを参照すれば設定できそうです。
実際にPythonとPerlの設定について書きます。
Python
:help VdebugSetUpPython
とKomodo 11 DocumentationのDebugging Pythonを見てPythonのセットアップをしてみます。
Komodo Remote Debugging Package Downloads « ActiveState CodeからPython Remote Debugging Clientをダウンロードして解凍します。以下を実行してOKが出るかを確認します。
$ export PYTHONPATH="/path/to/Komodo-PythonRemoteDebugging-xxx/pythonlib${PYTHONPATH:+:${PYTHONPATH}}"
$ python -c "import dbgp.client; print 'ok'"
ok
Vdebugを起動して、
$ /path/to/Komodo-PythonRemoteDebugging-xxx/pydbgp -d localhost:9000 script.py
でscript.pyに対してのデバッグを開始できます。やってみると、デバッグが終了しても上記コマンドが終了せず、Ctrl-cでも終了できないのが難点でした。
非公式ですがpipでインストールできるようにした人がいました(dougn/komodo-pydbgp: Repackaging of the Komodo python remote debugging package for building into usable wheels)。
試してみるとpython 2.7.14は動きましたがpython 3.6.3ではエラーがでました。
Perl
:help VdebugSetUpPerl
を見てPerlのセットアップをしてみます。
ヘルプ曰く、特定のバージョンからうまくいかなくなったようなので、ヘルプに書いてあるバージョンを
からダウンロードします(Komodo-PerlRemoteDebugging-8.0.2-78971-xxx)。
展開して、適当な場所(~/perl5/lib/perl5/
など)に配置します。
シェルの設定ファイルに以下の設定をします。
export PERL5LIB="/path/to/Komodo-PerlRemoteDebugging-xxx/${PERL5LIB:+:${PERL5LIB}}"
export PERL5DB="BEGIN { require q(/path/to/Komodo-PerlRemoteDebugging-xxx/perl5db.pl)}"
export PERLDB_OPTS="RemotePort=localhost:9000"
export DBGP_IDEKEY="PHPSTORM"
あとはVdebugを起動して
$ perl -d script.pl
でPerlを実行すればデバッグが始まります。
webページのデバッグ
Debugging Perl | Komodo IDE/Edit Documentationにやり方が載ってます。
例えば、Apache HTTP ServerでCGIを使っている場合はApache HTTP Serverのconfファイルに
SetEnv PERL5LIB "/path/to/Komodo-PerlRemoteDebugging-xxx"
SetEnv PERLDB_OPTS "RemotePort=<hostname>:<port>"
SetEnv DBGP_IDEKEY "<ide_key>"
と書いて、デバッグしたいスクリプトのシェバンに-d
を加えます。
#!/usr/local/bin/perl -d
そして、Vdebugを起動してwebページにアクセスするとデバッグが開始されます。
Python 3への移行
Vdebugはpython2で動きますが、v2.0という名前がついたプロジェクトページにAdds Python 3 supportというissueが立ってます。そこのコメント に
@l0rb fortunately @lucc mentioned the v2-integration branch where there is continued development but still some issues to be resolved before thinking about py3
と書いてあるので、Python 3への移行はまだ先になりそうです。
-
その他のブラウザの拡張については、Remote Debuggingのドキュメントを見て下さい。 ↩