Chrome デバッガー

GraalVMは、ゲスト言語アプリケーションのデバッグをサポートしており、Chrome DevTools Protocolの組み込み実装を提供しています。これにより、Chrome Developer Toolsなどの互換性のあるデバッガーをGraalVMにアタッチできます。

ゲスト言語アプリケーションをデバッグするには、次のNode.jsのHelloWorldプログラムの例のように、--inspectオプションをコマンドラインランチャーに渡します。

var http = require('http');

var server = http.createServer(function (request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end("Hello World!\n");
});

server.listen(8000);

console.log("Server running at http://localhost:8000/");
  1. このプログラムをHelloWorld.jsとして保存し、次を実行します。
    $JAVA_HOME/bin/node --inspect HelloWorld.js
    Debugger listening on ws://127.0.0.1:9229/SBqxI5YIqtREaDrXkFr8hLE0HL1AfKx8TjkI8qPMq2s
    For help, see: https://graalvm.dokyumento.jp/tools/chrome-debugger
    For example, in Chrome open: devtools://devtools/bundled/js_app.html?ws=127.0.0.1:9229/SBqxI5YIqtREaDrXkFr8hLE0HL1AfKx8TjkI8qPMq2s
    
  2. ブラウザでhttp://localhost:8000/に移動して、nodeアプリケーションを起動します。

  3. 別のChromeブラウザタブでdevtools:...リンクを開きます。

  4. HelloWorld.jsファイルに移動し、4行目にブレークポイントを設定します。

  5. node.jsアプリを更新すると、ブレークポイントがヒットしたことがわかります。

これで、スタック、変数を確認したり、変数を評価したり、ツールチップで選択した式などを評価できます。たとえば、カーソルをresponse変数に合わせると、下のスクリーンショットのように、そのプロパティを確認できます。

Chrome Inspector

Chrome DevToolsのデバッグ機能の詳細については、JavaScriptデバッグリファレンスを参照してください。

このデバッグプロセスは、GraalVMがサポートするすべてのゲスト言語に適用されます。RやRubyなどの他の言語も、JavaScriptと同様に簡単にデバッグでき、ゲスト言語の相互運用性中に言語境界をステップ実行することもできます。

検査オプション #

Nodeランチャー #

GraalVMのNode.jsランタイムは、V8 JavaScriptエンジン上に構築されたnode.jsと同じオプションを受け入れます。例えば、

--inspect[=[host:]<port number>]

これにより、インスペクターエージェントが有効になり、デフォルトでポート9229をリッスンします。別のポートをリッスンするには、オプションのポート番号を指定します。

--inspect-brk[=[host:]<port number>]

これは、nodeランチャーにのみ適用されます。

その他の言語ランチャー #

jspythonRscriptrubylli、およびpolyglotなどの他のゲスト言語ランチャーは、--inspect[=[host:]<ポート番号>]オプションを受け入れますが、デフォルトではアプリケーションコードの最初の行で中断されます。

--inspect.Suspend=(true|false)

--inspect.Suspend=falseを指定すると、最初のサスペンションが無効になります。

追加の共通検査オプション #

すべてのランチャーは、次の追加オプションも受け入れます。

  • --inspect.Path=<path>を使用すると、ユーザーは接続URLを生成するカスタムパスを指定できます。注:このURLを知っているブラウザで開かれたWebサイトは、デバッガーに接続できます。したがって、予測可能なパスは、ファイアウォールの内側にいる場合でも、悪意のあるWebサイトによって悪用され、コンピューター上で任意のコードを実行される可能性があります。そのため、パスはデフォルトでランダムに生成されます。
  • --inspect.SourcePath=<ソースパス>は、ソースパスを表すディレクトリまたはZIP/JARファイルのリストを指定します。検査対象のアプリケーションにソースファイルへの相対参照が含まれている場合、そのコンテンツは、このソースパスに関して解決された場所からロードされます。これは、たとえばLLVMのデバッグ中に役立ちます。パスは、UNIXシステムでは:で区切られ、MS Windowsでは;で区切られます。
  • --inspect.Secure=(true|false)がtrueの場合、TLS/SSLを使用してデバッグプロトコルを保護します。WS(Webソケット)プロトコルをWSSに変更するだけでなく、デバッグ対象に関するメタデータを提供するHTTPエンドポイントもHTTPSに変更されます。これは、デバッグ対象の情報を提供してデバッガーを起動できないchrome://inspectページとは互換性がありません。印刷されたWSS URLから直接デバッグを起動します。標準のjavax.net.ssl.*システムオプションを使用して、TLS/SSL暗号化キーを使用したキーストアに関する情報、または次のオプションを提供します。
    • --inspect.KeyStore - キーストアファイルパス
    • --inspect.KeyStoreType - キーストアファイルタイプ(デフォルトはJKS)
    • --inspect.KeyStorePassword - キーストアパスワード
    • --inspect.KeyPassword - キーを回復するためのパスワード(キーストアパスワードと異なる場合)
  • --inspect.WaitAttached=(true|false)がtrueの場合、インスペクタークライアントがアタッチされるまで、ゲスト言語のソースコードは実行されません。--inspect.Suspend=trueとは異なり、実行はクライアントがアタッチされた直後に再開されます。これにより、インスペクタークライアントによって実行が失われないことが保証されます。デフォルトではfalseです。

高度なデバッグオプション #

次のオプションは、言語の専門家および言語の開発者向けです。

  • --inspect.Initialization=(true|false)がtrueの場合、このオプションは言語の初期化フェーズを検査します。初期サスペンションがアクティブな場合、これは必ずしもアプリケーションコードの先頭ではなく、言語の初期化の開始時に中断します。デフォルトではfalseです。
  • --inspect.Internal=(true|false)がtrueの場合、内部ソースも検査されます。内部ソースは、言語実装の詳細を提供する場合があります。デフォルトではfalseです。

インスペクターバックエンドのプログラムによる起動 #

埋め込みは、適切なインスペクターオプションをEngine/Contextに提供して、インスペクターバックエンドを起動できます。次のコードスニペットは、可能な起動の例を示しています。

import org.graalvm.polyglot.*;

class DebuggerSample {
    public static void main(String... args) {
        String port = "4242";
        String path = java.util.UUID.randomUUID().toString();
        Context context = Context.newBuilder("js")
                    .option("inspect", port)
                    .option("inspect.Path", path)
                    .build();
        String hostAdress = "localhost";
        String url = String.format(
                    "chrome-devtools://devtools/bundled/js_app.html?ws=%s:%s/%s",
                    hostAdress, port, path);
    }
}

OpenJDKで実行する場合、埋め込みからChromeインスペクターツールを使用するには、次のMaven依存関係を宣言する必要があります。

<dependency>
    <groupId>org.graalvm.tools</groupId>
    <artifactId>chromeinspector</artifactId>
    <version>${graalvm.version}</version>
</dependency>

Chromeインスペクターツールは、GraalVMでは常にツールとして利用可能です。そこで明示的に依存関係を宣言する必要はありません。

お問い合わせ