Skip to content

Instantly share code, notes, and snippets.

@ono-max
Last active January 16, 2022 06:11
Show Gist options
  • Save ono-max/34399ea3a34a8a95168632ef997b1569 to your computer and use it in GitHub Desktop.
Save ono-max/34399ea3a34a8a95168632ef997b1569 to your computer and use it in GitHub Desktop.

Ruby アソシエーション開発助成金2021中間報告: “debug.gem”の利用体験・開発効率の改善

取り組んだこと

 前期では、本プロジェクトのゴールである Chrome でのデバッグ機能を実現する CDP サーバーと、CDPサーバー と DAPサーバー(VS Code でのデバッグ機能を実現するサーバー) のテストフレームワークの開発を中心に取り組んだ。

 CDP サーバーの開発については本プロジェクト開始前にプロトタイプとして導入されていたものを改善する形で主にバグ修正や Chrome DevTools 上の UI として提供されている機能をサポートしていった。 バグ修正については手元の環境で Chrome を用いてデバッグ機能を行いそれを元に見つかったバグを中心に修正を行っていった。提供されている機能のサポートについては、例外で止まる機能やブレークポイントなしでスクリプト実行を強制する機能などを実装した。他にもデバッガー起動時に Chrome を自動で開いて Chrome DevTools とデバッガーの接続を自動で行う機能や Chrome のコンソールで式評価をした際に標準出力に出力されるものをターミナルではなくコンソール上に出力されるものを開発した。

 テストフレームワーク開発についてはプロトタイプとしていくつかのものを Pull Request として作りながらメンテナンス性や可読性の高いものを考えていった。現在 DAP サーバーのテストフレームワークがプロトタイプとしてマージされている。

 その他の取り組みとして、デバッガーの統合テストをするテストフレームワークやテストケースジェネレーターの改善・バグ修正などを行った。具体的にはデバッギーに出力 されるものが多いとタイムアウトになってしまうテストフレームワークのバグの修正や、テストケースジェネレーターではデバッグをしたソースコードが出力先のファイルに含まれていないかチェックしてなければ出力できるようになった。

Chrome を用いたデバッグ機能の実装

バグ修正

デバッガー終了時にエラーが出るバグ修正に関するPull Request 群
  • Fix #329 by getting frame's path correctly
  • Continue the debuggee after detaching to Chrome
    • 繋いでいる状態で Chrome DevTools ページを閉じると、エラーが出て終了するバグ修正の Pull Request 。閉じた時に Chrome は Opcode に8(8は接続を閉じるという意味)を入れて送ってくるが、それに対応できていないのが原因だった。
    • この時、対応方法は以下の3通りだった。
      • デバッギーをexitで終了する。
      • デバッギーに continue コマンドを実行させる。
      • rdbg REPL に戻る。
    • gdb や リモートデバッグに合わせるのが良いと考え、デバッギーに continue コマンドを実行させる方法を採用した。
  • Fix bug that error occurs after detaching to Chrome
    • デタッチ後にエラーが出て終了するバグ修正の Pull Request 。スレッド終了後に readline メソッドが呼ばれてエラーが出てしまうということが原因だった。
Breakpoint 関係のバグ修正Pull Request 群
直接的にユーザーに影響を及ぼすものではないバグの修正に関するPull Request群
マウスオーバーをした時に表示するオブジェクトに関するPull Request 群。当時はマウスオーバーされたオブジェクトを eval して返ってきた値を返すようにしていたが、グローバル変数など値が変わってしまうという問題があった。
Chromeが自動で起動した後、 Chrome DevTools ページに飛ばないというバグを修正する為のPull Request 群。1.4.0リリース直前にこのバグを発見した。
  • Fix bug that debugger sometimes doesn't open Chrome automatically
    • ワークアラウンドとして出したPull Request。Chrome からのレスポンスの取得回数を増やした結果、筆者の環境でバグが修正されたように見えたことを根拠とした。
  • Correct changes in #445
    • ワークアラウンドのPull Requestの変更を書き直したもの。Page Domain を有効にする"Page.enable"メソッドを送信することで指定したURLへと移動する"Page.navigate"メソッドを確実に実行できるようにした。
  • Send current page's frame id when debugger sends 'Page.navigate' method
    • "Page.navigate"メソッドの中にFrame Id をパラメーターとして送ることにしたもの。
    • 感覚ではあるが、上記の Correct changes in #445 でバグはだいぶ改善された。しかし、デバッガーを使い始める1回目にバグがまだ観測された(一度終了して再起動するとこのバグはほとんど観測されない)。ドキュメントを見たところ、"Page.navigate"メソッドを送る際に Frame Id のフィールドをパラメーターとして送らない場合トップフレームを Frame Id として取得するという内容があったの遷移するフレームがトップフレームではなかった場合失敗するのではないかという推測を立て Fame Id をパラメーターとして送るようにした。その結果、現在に至るまでバグは筆者の環境で観測されていないので、バグを修正することができたと判断している。
意図したオブジェクトが表示されないバグを修正するためのPull Request 群
その他

リファクタリング

機能開発・改善

起動時に Chrome を自動で開いて Chrome DevTools のページに飛ぶ機能に関する Pull Request 群
  • Open Chrome automatically

    • 当初、以下の機能が実装されていたが断念した。
      • ポートなどの情報をファイルとして持たせる
        • なんらかの方法でそのファイルを書き換えることができた場合意図しない接続先にデバッガーが接続しようとしてしまうというセキュリティリスクがあり断念。
      • DevToolsActivePort ファイルからポートなどの情報を読み取る
        • 実験してみたところ、ポート番号が変わっても DevToolsActivePort ファイルが更新されなかったり、 DevToolsActivePort ファイルを用いたいくつかのプロジェクトでうまく動かないといった Issue が観測されたので断念。
  • Do not open Chrome automatically if "CONFIG[:chrome_path]" is an empty string

    • Chrome を自動で開きたくないケースがあると考え、環境変数で設定できるようにした。
Chrome のコンソールの式評価をした際に出力された標準出力をターミナルではなくコンソール状に出力するようにしたもの。
例外で止まる機能に関する Pull Request 群
ターゲットフレームにある変数を以下のように表示できるようにする為のPull Request 群。

Screen Shot 2021-11-27 at 10 47 26 PM

pp メソッドを拡張して Chrome のコンソールを使って表示できるようにしたもの。
その他

Screen Shot 2021-11-27 at 10 47 26 PM

ドキュメント修正

CDP サーバー・DAP サーバーのテストフレームワーク開発

CDP サーバー

  • Add tests for server_cdp.rb

    • 実験で作ったフレームワーク。イメージができたのでクローズした。
  • [WIP] 1. Add the test framework for CDP

    • テストフレームワークの1パターン目。以下のようにserver_cdp.rbと同じように書くような形にした。

    • def test_sample
            run_cdp_scenario PROGRAM do
              res1 = cdp_request 'Debugger.setBreakpointByUrl', condition: '', lineNumber: 7, url: "http://debuggee#{temp_file_path}"
              res2 = cdp_request 'Debugger.setBreakpointByUrl', condition: '', lineNumber: 5, url: "http://debuggee#{temp_file_path}"
              res3 = cdp_request 'Debugger.setBreakpointByUrl', condition: '', lineNumber: 3, url: "http://debuggee#{temp_file_path}"
              ...
    • メリット

      • 最も柔軟に書くことができる。
      • 行数が少なくて済む
    • デメリット

      • 可読性が低く CDP をよく知っている人にしか分からないものになっている。
  • [WIP] 2. Add the test framework for CDP

    • テストフレームワークの2パターン目。以下のようにJSON 形式でリクエスト・レスポンスを書くような形にした。テストジェネレーターも併せて作った。

    • def test_sample
            run_cdp_scenario RROGRAM do
              cdp_req({
                "id": 1,
                "method": "Page.getResourceTree",
                "params": {
                }
              })
              ...
    • メリット

      • パターン1と比べ可読性が高い。
    • デメリット

      • 毎回メソッドを通して呼んでいるので余計なカッコがついたりして可読性が下がる。
      • 行数が長くなる。

まだ実装はしていないが、3パターン目として以下のようなものを考えている。

def test_sample
      run_cdp_scenario PROGRAM do
        {
          "id": 1,
          "type": "request"
          "method": "Page.getResourceTree",
          "params": {
        }
        ...
  • メリット
    • DAP と同じ形式なので読みやすい。
  • デメリット
    • 返り値を使ってリクエストを送ることができないなど柔軟性が低い。
    • 行数が長くなる。

DAP サーバー

その他

バグ修正

Debuggeeの出力が多いときテストフレームワークが動かないというバグを修正する為のPull Request 群
テストを実行したときに表示される警告を消す為のPull Request群
その他
  • Fix test
    • CIが落ちていたのでその修正。assert_finish メソッドをAPIから削除後、まだ消し忘れが残っていたことが原因だった。

リファクタリング

使われていない・意味のないコードの削除。
Rubocop で検出されたメッセージを参考に修正したもの。
その他
  • Use snake case instead of camel case
    • キャメルケースで変数が定義されていたのでスネークケースに変数を書き直したもの。VS Code のフィールド名であることを強調する為意図的にキャメルケースで書かれていたものだった為、マージされなかった。
  • Refactor the logic by removing an intermediate variable
    • 中間変数を削除するもの。テストが通らずクローズした。

機能開発・改善

ドキュメント修正

プロジェクトの評価

 本プロジェクト開始時のゴールに対する進捗は以下のようになっている。全体的には順調にプロジェクトを進めることができていると考えている。Chrome に関してはプロジェクト開始時のゴールを達成できた。テストフレームワークについても先述したようにいくつかのプロトタイプができているので問題はない。

  • Chrome でのデバッグ機能を実現する CDP サーバーの開発
    • vscode-rdbg と遜色ない機能を持ったデバッグができる。
    • Chrome DevTools 上の UI として提供されている機能のサポートをする。
  • CDPサーバー と DAPサーバー のテストフレームワークの開発
    • CDP サーバー
      • テストフレームワークがマージされる。
      • テストフレームワークが安定して動く。
    • DAP サーバー
      • テストフレームワークがマージされる。
      • テストフレームワークが安定して動く。

現時点での本プロジェクトの社会的インパクト

 現時点で “debug.gem” の利用体験を向上することができたと考えている。VS Code を用いたデバッグと同様の機能を Chrome でも実現することができ、 Chrome を用いた JavaScript のデバッグに慣れ親しんでいるユーザーが “debug.gem” を使いやすくなったということができる。さらにこれらの Chrome DevTools を用いたノウハウを活かしてデバッグ体験にとどまらず、 irb を Chrome のコンソールで実行することでより良い体験を実現かもしれないという新たな可能性が出てきた。開発者支援ツールはターミナルをメインの UI として用いられることが多いものもあるが、よりリッチな体験を実現できる Chrome を一つの選択肢として考える機会を作ったという意味で有用な成果を得ることができた。

後半でやっていくこと

 前半ではデバッグを問題なくできることに多くの時間を費やしたので後半では Chrome の強みを活かしたリッチな開発体験向上に取り組んでいく。また、テストフレームワークの開発では DAP のテストフレームワークを安定させ CDP のテストフレームワークもマージしていきたい。

  • Chrome を用いた機能開発
    • プログラム中で出力される p メソッドなど標準出力に出力するものをターミナルではなく Chrome のコンソール上で表示できるようにする。
    • Ruby の補完機能を利用できるようにする。
    • pp メソッドを拡張して Chrome のコンソールを使って表示できるようにする。
    • irb のような使い方を Chrome のコンソールでできるようにする。
      • ブラウザの強みを活かしたターミナル上では実現できないリッチな出力をできるようにする。
  • テストフレームワーク開発
    • DAP サーバーのテストフレームワークを安定させるようにする。
    • CDP サーバーのテストフレームワークを開発する。

謝辞

 本プロジェクトを進めるに当たって笹田耕一さんには Pull Request のレビューを始め沢山の助言をいただきました。Ruby に関する知識はもちろんのこと、一流のプログラマとしての姿勢や視点からは沢山のことを学ばせていただきました。本当にありがとうございました。これからもどうぞ宜しくお願い致します。

 また、このような素晴らしい機会を与えてくださった Ruby アソシエーション関係者の皆様に感謝します。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment