调试

Julia 扩展支持所有类型的 Julia 程序和应用程序的调试。

对于不依赖于语言的通用调试功能,例如检查变量、设置断点以及其他活动,请查看 VS Code 调试

示例

  1. 在 VS Code 中打开一个 Julia 文件。
  2. 单击运行按钮。您现在将看到默认调试器开始面板
  3. 单击运行和调试(或选择F5)可在调试器中运行活动 Julia 文件。输出显示在 Julia 调试终端中。

Debugger

在此示例中,整个程序一次性运行,并且没有任何问题结束。让我们在第 11 行设置一个断点,这样这个示例会更实用。我们只需要用鼠标单击代码编辑器的最左边列即可

Debugger

红点向我们表明我们现在已设置一个断点。接下来,我们再次启动程序(单击运行和调试或按F5)。当程序到达第 11 行时,它将暂停

Debugger

黄色行向我们展示如果继续运行程序,我们接下来将执行的位置。我们还可以看到我们在调用堆栈中的位置及所有断点列表。现在我们在文本编辑器的顶部看到一个工具栏,其中包含常用调试操作的命令:继续单步执行单步进入单步跳出等。让我们单击一次单步执行,然后单击单步进入。现在我们暂停在 bar 函数的第一行

Debugger

变量视图现在向我们展示了此函数中的哪些局部变量以及它们当前的值。当我们逐步执行程序,最终到达 bar 函数的末尾时,局部变量列表变得更长,即我们现在也将看到 cd 的值

Debugger

让我们在 行 15 上设置另一个断点,然后继续程序,直到它命中该断点。然后我们单击 调试控制台,然后看到如下视图

Debugger

在此视图中,我们可以在当前函数的上下文中评估任意 Julia 代码。例如,我们可以通过在此处运行 log(x) 来计算 x 的对数

Debugger

我们还可以在程序暂停时更改任何局部变量的值。例如,要更改 x 的值,我们可以在 变量部分中的值 27 的旁边双击,然后输入任意 Julia 表达式。此表达式返回的值将变为变量 x 的新值。在以下示例中,我们将 x 的值更改为字符串

Debugger

就此非常基本的演练结束。现在我想要重点介绍一些其他功能。

启动调试器的各种方式

有两种不同的方式来启动调试器。

  • 第一种方法您已经在演练中了解:您在调试器中运行 Julia 文件。
  • 第二种方法允许您在交互式 REPL 中调试代码。

运行 Julia 文件

在我们的示例中,我们在调试器中启动了当前活动的 Julia 文件。这是启动调试的最基本方式,但是您可以在 VS Code launch.json 文件中配置更多选项。例如,包括将固定 Julia 文件设置为启动文件,配置命令行参数等。launch.json 功用在 VS Code调试器文档中进行了更详细的描述。

从 REPL 调试代码

您还可以从 REPL 启动调试器。在这种情况下,调试器将附加到已运行的 REPL 上。要启动这样的调试会话,您在 REPL 中使用两个宏:@enter@run 宏。两者都非常简单:它们将在传递给该宏的代码上启动调试器。@run 宏将运行代码,直到命中断点,而 @enter 宏将在代码的第一行暂停调试器。例如,您可以通过输入 @enter println("Test") 从 REPL 调试 println 函数

断点

您已经学习了如何轻松地在源代码中设置断点。有另外两种断点选项:函数断点和断点条件。

函数断点

如果在 BREAKPOINTS 视图中单击小 + 标记,则可以添加函数断点。只需输入要断开的函数名称。您还可以通过指定类似 foo(::String, ::Number) 的签名,将其配置为仅断开特定方法。

断点条件

如果在编辑器中用鼠标右键单击断点,则可以选择 编辑断点... 选项,然后可以对断点添加条件。您可以在此处输入任何返回 Bool 值的有效 Julia 表达式。您当然可以完全访问此表达式的所有局部变量。

变量查看器

复合变量、数组和词典在变量查看器中具有完整的树形展开支持

Debugger

监视部分

监视部分允许您输入任意 Julia 表达式,这些表达式将在程序暂停并且显示结果时求值

Debugger

调用栈

调用栈部分允许您查看任何堆栈帧的内容,即,当您单击其中的不同函数时,它将显示所选堆栈帧的局部变量。您还可以通过单击此处给定条目旁边的较小重新启动图标,在任何堆栈帧重新启动代码执行

Debugger

请注意,此最后一项功能可能非常脆弱,尤其是当您的函数修改任何全局状态时。

异常

如果您的代码抛出异常,您将获得一个漂亮的异常视图

您还可以在 UI 的 BREAKPOINTS 部分中配置调试器在遇到异常时的行为。

编译模式

断点视图有另一个选项,称为“启用编译模式”

Debugger

此选项的功能如下

如果你选择此选项,则在从当前堆栈帧调用的任何函数中设置的断点将不再暂停代码执行。在我们的示例中,如果你已在函数 foo 中暂停,然后选择此选项,则 bar 中的断点将不再暂停执行。而 foo 中的断点仍会暂停调试器。

你为什么要使用此功能?

如果启用此选项,你的代码将运行得快得多。

疑难解答

如果你在使用调试器时遇到任何问题,请务必到Julia VS Code仓库里告诉我们。

加速调试器的设置

ALL_MODULES_EXCEPT_MAIN

为了让调试器运行得更快,我们要最大程度地减少要解释的包/模块的数量。比方说,你需要调试自己编写的代码,还需要调试由 Statistics 包提供的功能。在“调试器默认编译”扩展设置中单击一下。

Debugger

按以下方式配置此设置。

"julia.debuggerDefaultCompiled": [    
        "ALL_MODULES_EXCEPT_MAIN",   
        "-Statistics.",     
    ]

ALL_MODULES_EXCEPT_MAIN会让所有模块都以编译模式运行,除了包含了你编写的代码的主模块。我们还使用“-Statistics.” 来将此模块及其所有子模块从编译模块列表中删除,这样它将被解释。

使用自定义 sys 镜像

调试时也可以使用自定义 julia sys 镜像。转到 julia-vscode 扩展设置,然后单击编辑“其他参数”。

Debugger

进入设置后,使用“-J”选项,然后输入你自定义 sys 镜像的路径。请注意,当前“其他参数”设置仅在以 REPL 模式调试时使用,请看下面的示例中的 @run 宏。

"julia.additionalArgs": [
        "-JC:\\temp\\sys_custom.so",
    ],

用于更快速调试的示例

在以下代码中,我们使用了 GLMakie 和 Statistics 包。GLMakie 是一个绘图包,众所周知,它绘制到首次绘图所需的时间(TTFP)相当漫长,特别是对于低于 1.9 的 julia 版本。在调试时,我们肯定不想解释 GLMakie。使用上面的设置,GLMakie 被设置为以编译模式运行,我们还从 sys 镜像中加载它。确保对根函数使用 @run 宏并在 REPL 模式中进行调试。

Debugger

当调试器命中指定的代码行时,我们可以进入到 mean 函数中(统计数据)进行调试。

Debugger