Chrome 调试器

GraalVM 支持调试客语言应用程序,并提供 Chrome DevTools 协议 的内置实现。这使您可以将兼容的调试器(如 Chrome 开发者工具)附加到 GraalVM。

要调试客语言应用程序,请将 --inspect 选项传递给命令行启动器,如下面的 Node.js HelloWorld 程序示例所示

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 https://#: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.java.net.cn/tools/chrome-debugger
    For example, in Chrome open: devtools://devtools/bundled/js_app.html?ws=127.0.0.1:9229/SBqxI5YIqtREaDrXkFr8hLE0HL1AfKx8TjkI8qPMq2s
    
  2. 在浏览器中导航到 https://#:8000/ 以启动节点应用程序。

  3. 在另一个 Chrome 浏览器选项卡中打开 devtools:... 链接。

  4. 导航到 HelloWorld.js 文件,并在第 4 行设置断点。

  5. 刷新 node.js 应用程序,您会看到断点命中。

现在,您可以在工具提示中检查堆栈、变量、评估变量和选定表达式等。例如,将光标悬停在 response 变量上,您可以检查其属性,如下面的屏幕截图所示

Chrome Inspector

有关 Chrome DevTools 调试功能的详细信息,请参阅 JavaScript 调试参考

此调试过程适用于 GraalVM 支持的所有客语言。其他语言(如 R 和 Ruby)可以像 JavaScript 一样轻松地进行调试,包括在客语言 互操作性 期间逐步执行语言边界。

检查选项 #

节点启动器 #

GraalVM 的 Node.js 运行时接受与 基于 V8 JavaScript 引擎构建的 node.js 相同的选项,例如

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

这将启用检查器代理,默认情况下监听端口 9229。要监听其他端口,请指定可选的端口号

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

这仅适用于 node 启动器。

其他语言启动器 #

其他客语言启动器(如 jspythonRscriptrubyllipolyglot)接受 --inspect[=[host:]<port number>] 选项,但默认情况下会在应用程序代码的第一行暂停。

--inspect.Suspend=(true|false)

如果您指定 --inspect.Suspend=false,这将禁用初始暂停。

其他常见检查选项 #

所有启动器还接受以下其他选项

  • --inspect.Path=<path> 允许用户指定自定义路径,该路径生成连接 URL。注意:在浏览器中打开的任何了解此 URL 的网站都可以连接到调试器。因此,可预测的路径可能会被恶意网站滥用,以在您的计算机上执行任意代码,即使您在防火墙后面也是如此。 因此,路径默认情况下是随机生成的。
  • --inspect.SourcePath=<source path> 指定表示源路径的目录或 ZIP/JAR 文件列表。当受检应用程序包含对源文件的相对引用时,其内容将从相对于此源路径解析的位置加载。例如,在 LLVM 调试期间很有用。路径在 UNIX 系统上由 : 分隔,在 MS Windows 上由 ; 分隔。
  • --inspect.Secure=(true|false) 当为 true 时,使用 TLS/SSL 来保护调试协议。除了将 WS(WebSocket)协议更改为 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 上运行时,必须声明以下 Maven 依赖项才能从嵌入中使用 Chrome 检查器工具

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

Chrome 检查器工具始终作为 GraalVM 上的工具可用。在那里,不需要显式声明依赖项。

与我们联系