この記事について
Neovimではnvim-dap,nvim-dap-ui を使用することで、デバッグを行うことができます。 しかし、Neovimからデバッグを開始する方法では引数を与える場合、通常ターミナルで実行する場合とは異なる慣れない入力をする必要があるため なかなか面倒です
デバッグの手法の中には、デバッガ側でプログラムを起動した状態にしておき、そこにエディタ側からアタッチする方法があります。 この方法ではデバッガとエディタの間の通信がTCP/IPで行なわれ、別のマシンで実行しているプログラムをデバッグすることができるので、リモートデバッグと呼ばれています。
Python向けには、1年ほど前にリモートデバッグが実行できるように設定していました。 しかし、C/C++,Rustの設定は長いこと設定していなかったので、ようやく重い腰を上げて設定をしました。
今回はあくまでも、同一ホストで動かしているプログラムのデバッグに限定しますが、接続先のホスト名(もしくはIPアドレス)を変更すれば本当に"リモート"なデバッグにも応用できます。
前提
今回の記事ではNeovimでのデバッグ実行の設定ですが、以下のことを前提にしています。
- デバッガの実行はmfussenegger/nvim-dapを使用する
デバッガ側
Pythonの場合
Pythonのデバッグにはdebugpyを使用し、インストールはプロジェクトごとに以下のように実行します。
|
|
ここで、uvによるインストールですが、uv add <pkg name>でインストールする際には--devを付けることでdev-dependencyとしてインストールすることができます。
この場合、uv buildでwheelをビルドする場合などで、dev-dependencyとしてインストールされたパッケージが除外されます。
C/C++/Rustの場合
gdbをインストールして、gdbserverが実行できるようになっていればOKです。
Neovim側
Python by debugpy
nvim-dapの設定は以下のように行いました。
内容としては、IPアドレスlocalhost(127.0.0.1),ポート5678で立てたサーバー(debugpy)に対してクライアント(エディタ)をアタッチするようになっています。
|
|
C/C++/Rust by gdb
以下を参考に設定しました。Pythonの場合と意味としては同じで、IPアドレスlocalhost(127.0.0.1),ポート5678で立てたサーバー(gdbserver)に対してクライアント(エディタ)をアタッチするようになっています。
|
|
デバッグの実行
Pythonの場合は、以下のコマンドでデバッガのサーバーを起動します。
|
|
一方、C/C++,Rustの場合では以下のようにデバッガのサーバーを起動します。
|
|
サーバー側が起動した後では以下の手順でデバッグを開始します。
require('dap').continue()を実行してポップアップからattach to gdbserver(C/C++,Rustの場合)もしくは,attach to debugpy(Pythonの場合)となるアダプターを選択する。require('dap').toggle_breakpoint()で適当な場所にブレークポイントを設定する。require('dap').continue()でデバッグ開始する。
筆者はこれらの操作を以下のようなキーに割り当てています。
| key | function | 操作 |
|---|---|---|
| :B | require(‘dap’).toggle_breakpoint() | 現在のカーソル位置でのブレークポイントのトグル |
| :Bc | require(‘dap’).clear_breakpoints() | 設定したブレークポイントをすべてクリア |
| :C | require(‘dap’).continue() | 継続 |
| :Cr | require(‘dap’).restart() | セッションの再起動 |
| :Ct | require(‘dap’).terminate() | セッションの終了 |
| Alt + n | require(‘dap’).step_over() | 次の行の実行で、関数呼び出しは実行するが、中には入らない |
| Alt + s | require(‘dap’).step_into() | 次の行の実行で、関数呼び出しがあったら、その中に入る |
| Alt + f | require(‘dap’).step_out() | 現在いる関数を最後まで実行して、呼び出し元に戻る |
コンテナの名のプラグラムをデバッグする場合
また、コンテナの中のプログラムをデバッグするには、コンテナの起動時にポートフォワーディング(-p <port>:<port>)して、コンテナ内でのサーバーの起動時のIPアドレスとポートを"0.0.0.0:<port>“に設定するとそのまま使用できます。
感想
C/C++,Rustのgdbによるリモートデバッグの設定は結構ややこしいように感じていましたが、思ったよりも簡単に設定できました。 これからのデバッグがより快適になりそうです。