作者

Sales Engineer at Intersystems
文章 Jeff Liu · 三月 10 4m read

调试 101:VS 代码中的第一个断点和跟踪变量

本文将讨论 Microsoft Visual Studio Code IDE中包含的所有调试工具

内容包括

  • 断点
  • 观察窗口
  • 调用堆栈

让我们从了解调试要求开始!

前提条件

有两个插件(扩展)可用于调试 ObjectScript:

第一个是 InterSystems ObjectScript 扩展包的一部分 。第二个是 Serenji,它是一个独立的插件,提供编辑器、文件管理器和调试功能。这两个插件都可以从插件商店安装。要激活关键功能,Serenji 需要许可证。在本文中,我们将使用 InterSystems ObjectScript 扩展包来降低学习难度。在掌握基础知识后,您可以考虑购买 Serenji 的付费许可证。

 

您需要

  1. 最新版本的 Microsoft Visual Studio Code IDE
  2. 安装 InterSystems ObjectScript Extension Pack 插件(安装 Visual Studio Code 后)
  3. InterSystems IRIS 实例。您可以选择 Docker 版本或安装包。(您必须在 开发人员社区 生态系统中注册)

如何将 IRIS 连接到 Microsoft Visual Studio Code IDE,请 点击此处


设置调试功能


通常,配置文件会在调试开始后自动生成。配置文件如下

{
    "configurations": [
       
    {
        "type": "objectscript",
        "request": "launch",
        "name": "ObjectScript Run current routine",
        "program": "${file}"
    }
    ]
 
}

其中 type 是调试代码的语言,request 是调试启动选项(launch - 启动并执行代码,attach - 连接到已运行的代码),name 是调试标识符,program 是调试类和方法的名称(在此配置中,将拾取打开的文件)。

断点

任何程序代码都是自上而下逐行执行的。调试时,了解程序在任何特定时刻的状态非常重要,包括局部变量和全局变量的值、文件的打开和关闭、网络连接等。

断点(Breakpoint)是一种调试工具,它允许你在特定行暂停程序的执行,以确定程序状态中不必要的变化。 在 Visual Studio Code 中开始调试非常简单。 比方说,我们有如下代码:

Class Test.MyFile Extends %RegisteredObject
{

ClassMethod TestVar() As %Integer
{
    set randomNum = $RANDOM(10)
    return randomNum
}

ClassMethod MyMethod() As %Integer
{
    set randomNum = ..TestVar()
    set numVar = 2
    set numDivision = randomNum / numVar

    return numDivision
}
}

我们需要了解存储在 MyMethod() 方法中randomNum变量的值。它由 TestVar() 方法返回。我们在第 15 行对该变量执行算术运算之前设置一个断点,然后单击调试按钮。如果不设置断点,调试只会执行代码,不会向控制台输出任何内容。

开始调试后,我们可以立即看到给定变量的值!非常方便。接下来,我们可以按 Step into 按钮或 F11 逐行查看整个程序。

好极了!现在我们知道了代码执行过程中每一步的变量值。

我们可以用同样的方法在循环中循环变量。下面是一段代码

Class Test.MyFile Extends %RegisteredObject
{

ClassMethod LoopMethod() As %List
{

    set objList = $LB("string", 1, {"name":1})
    for i=1:1:$LL(objList){
        set item = $LG(objList, i)
    }
    
    return objList
}

}

在方法的开头设置一个断点,开始调试。然后,使用 IDE 顶部调试面板上的 "Step into "按钮,向下移动程序并观察分配给项变量的值。我们还可以看到程序中所有其他变量的值,包括迭代器变量i,在本例中i 的值等于 2。
 
因此,沿着循环向前移动,就可以跟踪到循环的每一步将为 item 变量分配什么值。

观察窗口

在调试过程中,我们还可以通过将变量添加到观察模式来监控变量的状态。在观察模式下,我们可以对变量应用方法,并在每次迭代中测量其状态。例如,请看下面的代码

Class Test.MyFile Extends %RegisteredObject
{

ClassMethod WatchAVariable() As %List
{
    set list = ""
    set randomNum = $RANDOM(100)
    for int=randomNum:randomNum:100000{
        set list = list _$LB(int)
    }

    return list
}
}

我们将为 list 变量编写三个方法:
 
我们要跟踪 list 的长度 $LL(list)、最后添加的数字 $LG(list, -1) 及其平方根 $LG(list, -1) ** 0.5。我们进入循环并获取第一个值:
 
通过在观察窗口中定义函数,我们可以看到详细的调试信息!此外,变量窗口仍然显示 int iterator 变量的值和循环步骤。非常方便!

调用堆栈窗口

注意最下方的 "调用堆栈 "窗口。该窗口显示代码中函数调用的顺序。在当前状态下,我们有两个项目:循环以及分别为变量 WatchVariable+7 和 WatchVariable+6 赋值。但这里的一切都不言自明。让我们再添加一些逻辑:

Class Test.MyFile Extends %RegisteredObject
{

ClassMethod RandomlyChangeVar() As %Integer
{
    return $RANDOM(100)
}

ClassMethod WatchAVariable() As %List
{

    set list = ""
    set randomNum = $RANDOM(100)
    for int=randomNum:randomNum:100000{
        set list = list _$LB(int)
        if $LG(list, -1) ** 0.5 > 10{
            set int = int + ..RandomlyChangeVar()
        }
    }
    return list
}


}  


我们添加了一个新方法 RandomlyChangeVar(),如果上一个数字的平方根大于 10,该方法将改变下一个 int 变量。我们循环运行,直到变量的状态满足逻辑条件(这是一个 GIF):

请注意平方根函数的值和调用堆栈中函数调用的顺序。只要平方根超过 10,就会立即调用 RandomlyChangeVar() 函数!此外,通过测量列表的长度,我们还能跟踪到需要多少循环步骤才能达到所需的逻辑条件。这样,无论逻辑多么复杂,都能轻松跟踪调用多个函数的顺序和条件。
就是这样!
在本文中,我们详细介绍了VSCode 的调试功能设置了首个断点,并追踪了变量的取值变化。