🦁

Positron で R パッケージ中の C/C++ や Rust のコードをデバッグする

2024/07/14に公開

デモ

こういうのができます。

https://x.com/yutannihilation/status/1812300168563450281

背景

先週やってた UseR! 2024 で Posit 社の Lionel Henry 氏[1]が ark について発表してました。動画はまだないですが、スライドはすでに公開されています。

https://lionel-.github.io/slidedecks/2024-07-11-ark/

ark は Positron の裏側で動いている、R のプロセスをラップしていろいろ便利に使えるようにしてくれるもの、です。いろいろ便利に、というのが具体的にどういうことかというと、スライド中では、

  • LSP のサーバーで、
  • DAP のサーバーでもあり、
  • Jupyter のカーネルにもなる。

と言っています。この 3 つの中で、エディタに詳しい人でも「LSP と Jupyter のカーネルは聞いたことあるけど、DAP ってなに?」という感じかもしれません。DAP は Debug Adapter Protocol の略で、エディタのデバッガとバックエンドがやりとりする通信についての規格です。

https://microsoft.github.io/debug-adapter-protocol/

とまあ、DAP 自体については私もあまり理解できていないので置いておいて、Lionel のスライドの中で、R のパッケージから呼ばれている C++ の関数に breakpoint を設定してステップ実行する、というデモがあって感動したのでやり方を調べた、というのが今回書きたいことです。

やり方

準備

まずは、CodeLLDB という拡張機能を入れます。LLDB とついてますが、LLVM (Clang) でコンパイルしたもの以外にも使えます。

https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb

ちなみに、CodeLLDB について検索すると、Python を入れないといけないとか LLDB を入れないといけないとか出てくるんですが、今はバンドルされているので必要ないっぽいです。とりあえず私は何も設定しなくても動いたんですが、あまりちゃんと調べていません。

CodeLLDB bundles its own copy of Python

CodeLLDB can use external LLDB backends instead of the bundled one.

(https://github.com/vadimcn/codelldb/blob/master/MANUAL.md#installing-packages)

設定

以下のような設定を .vscode/launch.json に書きます。この GitHub issue のコメントに書かれていたものそのままです。

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "attach",
            "name": "Debug",
            "program": "ark", // Windows の場合は ark.exe
        }
    ]
}

breakpoint を設定する

デバッグしたい C / C++ / Rust コードに breakpoint を設定します。行番号のあたりをクリックすれば設定できると思います。その後、Load R Package でパッケージを読み込みましょう。

デバッガにアタッチする

ここはちょっとわかりづらい点ですが、今のところは、breakpoint があるだけでは自動でデバッガを起動してくれたりはしません。まずデバッガにアタッチした状態で、breakpoint がある行を通る必要があります。

F5 を押して、もしくは左サイドバーからデバッグ開始の再生ボタンを押して、R プロセスをアタッチしましょう。その状態で、デバッグしたい C / C++ / Rust コードを呼び出す R の関数を実行すると、ステップ実行のモードになります。

ちなみに、もし「ark っていうプロセスが複数あります」みたいなエラーが出た場合は、起動する Positron をひとつだけにするか、この GitHub issue のコメントにあるように pid を指定する必要があるみたいです。

ステップ実行中の操作

冒頭の動画のように、ステップごとに進めたり、変数の中身を覗くことができるようになります。ここはあまり語ることがないので説明は省略します。

デタッチする

ここもちょっとわかりづらい点です。関数を抜けてもデバッガは起動したままなので、手動でデタッチする必要があります。まずは一番左の「Continue」(F5)を押して関数を抜けましょう。そして、コンソールが入力可能な状態に戻ったら、いちばん右の「Disconnect」(Shift+F5)を押してデタッチします。

(余談)お気付きいただけただろうか?

実は...、冒頭の動画はこの操作を間違えています。一番左の「Continue」を押してるように見えますが、手元で Shift + F5 を押して「Disconnect」していました。関数を抜けない状態でデタッチしてしまった一方、R のプロセスはデバッグ中だった位置で止まってしまっていて、入力を受け付けない状態になっています。こうなると、プロセスを強制終了するしかなくなってしまいます。

このあたりのユーザー体験は今後改善されるとは思いますが、現状はこんな感じです。撮りなおすのめんどくさいしこのままでいいか...、と紛らわしい動画になってしまっていてすみません。

脚注
  1. 彼は Emacs のヘビーユーザーです。「Still need to build support in other editors」というのもこの人が言うと説得力ありますね。 ↩︎

Discussion