动态调试的一般方法

供新手入门和老手参考的教程和相关资料,包括中文帮助
User avatar
amnesiac
Posts: 186
Joined: 22 Nov 2013, 03:08
Location: Egret Island, China
Contact:

动态调试的一般方法

23 Aug 2014, 22:10

注:本文待补充设置断点的一些经验,并列举具体的脚本作为调试示例。
导言:如果你问一个经验丰富的脚本人,从计划写脚本到脚本最终可用的过程中,花时间最多的是什么阶段?除错(调试),一般情况下他的回答都是这样,或至少包含这个。为什么会这样?因为脚本需要电脑来执行,所以对准确性的要求非常高:一个微小的细节电脑无法解释就会出现错误或得不到预期结果。而人恰恰不擅长做这样的事情,很多错误就在所难免,不严谨的说写脚本的过程基本等于不断发现问题并解决问题的过程。
前言
脚本中的错误一般方式可分为语法错误(主要为静态问题)和逻辑错误(主要为动态问题),按出现时间则分为加载时错误和运行时错误。对于语法错误,一个好用的编辑器非常重要,例如语法高亮功能可让我们及时纠正命令或函数的拼写错误,这里不再详细介绍。而逻辑错误,通常需要通过动态调试来发现和解决。
逻辑错误一般指脚本能启动却无法正常执行或执行后得不到期望的结果。这时一般使用这里的调试方法找到脚本中存在的错误并进行解决。
使用 #warn 可用于减少由于误用变量产生的逻辑错误。
常规的调试方法
要判断代码中存在的问题,原始的调试方法是在编写代码时直接插入逻辑条件和输出语句。这种方法中我们一般使用其内置的命令进行辅助调试,包括 ListVars、Pause、ListLines、KeyHistory 和 OutputDebug。还有其他一些命令也能用于辅助调试,例如 Suspend 可以辅助调试热键,用 MsgBox 显示出单个变量的内容,较多内容时可以 FileAppend 写入到文件中进行查看等。
使用这些命令时,首先必须在脚本中选择好位置,接着插入相应的命令,然后观察执行的情况,这样才能获取执行到相应位置时脚本中各种我们需要的信息,恢复执行时必须从文件或托盘菜单取消暂停(一种替代方法是提前在脚本中添加含暂停命令的热键)。
注:十分重要的一点是必须把适当的命令放到精心选择的位置,一般是紧接在感觉可能存在问题的代码之后,同时注意不要影响后续代码的执行(插入的命令可能导致某些内置变量的改变,例如 ErrorLevel、上次找到的窗口等,从而影响后续代码的执行)。
这里简单介绍这几个命令的用法,详细说明请参阅帮助:
  • 使用 Pause 可以在脚本中模拟断点,这样当脚本运行到这行时将暂停执行。
  • ListVars 可以列出脚本中的变量名及其内容。
  • ListLines 显示最近执行的脚本行。
  • ListHotkeys 可以列出当前脚本使用的所有热键及状态。
  • KeyHistory 列出脚本信息和最近的按键和鼠标点击记录。
这种调试方法的好处是不依赖于调试工具(用记事本写都可以调试),不过缺点也比较明显,一方面这种方法的调试效率比较低,对一些棘手的问题不容易快速定位,另一方面是这种方法需要在程序中插入调试代码,这可能带来副作用,例如影响程序流程或出现新问题。
因此,这种方法功能有限,许多方面比较麻烦且可能影响脚本自身运行,适用于调试简单、短小的脚本。
官方论坛中一些用于调试的库函数参考:My Very Useful Debugging Functions(作者:Rapte_Of_Suzaku),UTest 测试套件(作者:majkinetor)

交互式调试
这部分属于进阶内容,该调试方法需要使用 SciTE4AutoHotkey 才能实现。
简介
严格说来, AutoHotkey Basic 中这种辅助判断脚本错误以进行修正的方法不算真正的调试(通过增加几个命令帮助除错更像是事后补救的方法)。AutoHotkey_L 中是把调试作为其自身的一部分,所以可以原生支持以下调试功能:
  • 设置和移除行中的断点 - 遇到断点时暂停执行。
  • 单步调试代码 - 逐语句、逐过程或跳出函数和子程序。
  • 检查所有变量或特殊变量(包括对象)的内容。
  • 查看正在运行的子程序和函数的堆栈。
下面主要介绍 SciTE4AutoHotkey 中进行调试的方法,如果您使用其他编辑器,请参见帮助中调试客户端页面以便在自己喜欢的编辑器上进行调试。
要求
在对脚本进行调试之前,首先您必须安装 AutoHotkey_L [AHK_L 11+] 或使用其绿色版本。然后,请在 SciTE4AutoHotkey 中打开 ahk 脚本后按下 F7,从菜单中选择【工具】>【调试】或点击工具栏上的调试按钮,SciTE 调试器将启动并且进入调试模式。下面将简要说说调试的方法:
基本调试控制
在调试模式中您可以控制脚本的执行。当脚本暂停时,即将执行的下一行会高亮显示。这里有许多有用的命令(所有这些都可以在工具栏上找到):
  • 运行(F5)。到达断点时会暂停执行(参见下面)。
  • 停止运行脚本。
  • 运行当前行代码(F10)。
  • 一直运行到下一行代码(F11)。
  • 堆栈(参见下面)。
  • 变量列表(参见下面)。
断点
断点是程序中暂停执行的点。如果 AutoHotkey_L 即将执行的行含有断点,那么执行会暂停。要在一行上设置断点,请点击行号右边的边距区点击:
2014-08-24 10 50 20.png
设置断点
2014-08-24 10 50 20.png (1.78 KiB) Viewed 5754 times

检视变量内容
您可以获取变量的内容,设置修改它们。为了实现这样的目的,找到某个变量名的实例,在上面点击右键,在出现的菜单中选择“检视变量...”来显示变量检视对话框。如果变量包含对象,出现在您前面的将是对象检视对话框。在这里,您可以双击某个字段来检视并且编辑它。
2014-08-24 10 50 29.png
查看变量内容
2014-08-24 10 50 29.png (13.21 KiB) Viewed 5754 times

2014-08-24 10 50 36.png
查看对象内容
2014-08-24 10 50 36.png (10.78 KiB) Viewed 5754 times

列出所有变量
通过点击相应的工具栏按钮您还可以列出所有变量。
2014-08-24 10 50 42.png
列出所有变量
2014-08-24 10 50 42.png (14.37 KiB) Viewed 5754 times

为了检视变量,请在变量上双击。
获取堆栈
有时知道脚本的入口是很有用的。这个列表称为堆栈。要查看这个列表,请点击相应的工具栏按钮。
2014-08-24 10 50 48.png
获取堆栈
2014-08-24 10 50 48.png (12.49 KiB) Viewed 5754 times

在堆栈视图中,双击入口点您可以到达脚本的相应位置。
在调试模式下,通过单步执行(逐语句、逐过程、跳出,依次对应 Step in/Step out/Step over)可以逐行或逐个逻辑块执行代码:
  • 逐语句是指逐行执行代码并在遇到子程序时进入调用堆栈;
  • 逐过程是指让进入函数或子程序调用堆栈的程序执行直到从函数或子程序返回;
  • 跳出是指逐行执行指令并在遇到函数或子程序时跳过调用堆栈直到后一条语句。
在 SciTE4AutoHotkey 中,逐语句、逐过程和跳出的快捷键分别是 F10、F11、Shift+F11。

小结
对于逻辑错误,需要在实践中多总结,有经验了可以在编写脚本时避免许多错误。另外必须注意到,因为实际环境复杂多变,许多情况我们需要在脚本中加上容错处理,以后可能另写一篇专门讲述关于错误处理方面的内容。
AutoHotkey 学习指南(Beauty of AutoHotkey)
I do not make codes, and only a porter of AutoHotkey: from official to Chinese, from other languages to AutoHotkey, and show AutoHotkey to ordinary users sometimes.

Return to “教程资料”

Who is online

Users browsing this forum: No registered users and 1 guest