程序调试在开发过程中是十分常用的一项功能,掌握程序调试的各种方式与操作,对于开发人员和业务人员都是可以提升定位到问题和解决问题的效率的。所以本篇笔记在于简单介绍几种常用和好用的调试方式。
SAP 程序调试
一、断点介绍
1.断点类型
SAP中的断点有四种类型,这几种断点的图标样式都是不一样的。分别是:
- 调试断点:这种断点指的是在程序调试过程中打的断点。是一种临时断点,程序调试结束后断点自动消失。
- 会话断点:这种断点有两种添加方式,第一种是在程序执行前添加的,另一种是添加调试断点后点击保存按钮由调试断点转换来的。在同一个登录状态下不同的窗口中都有效,随着账户的退出而消失。
- 外部断点:只能在程序执行前添加,与账户绑定。即便是账户退出后仍然有效。
- 静态断点:这个是通过代码BREAK-POINT设置的,只要程序执行到本段代码就会进去调试状态。取消的方法就是注释掉这段代码。
2.调试断点
添加方式就是在调试界面的断点添加列处单击左键添加。之后就可以在本次调试中当作会话断点进行调试了。在本次调试结束之后设置的调试断点也就自动消失了,下次再进入调试界面时就不会再生效了。


3.会话断点
(1)调试前添加
在程序执行前,将光标放置于想要添加断点的行处,例如下图所示的第57行。当你熟练之后其实可以直接在对应的行前的断点添加列处点击左键来添加断点。


调试状态的会话短线如下所示。

(2)调试断点转换
调试断点在上面介绍过,是在程序调试过程中添加的。但是存在一个问题就是这种断点会在程序调试结束后消失,但我现在希望它能在本次调试结束之后依然能在下次调试时继续进入到这个断点的位置就需要将其转化为会话断点。
而转化的方法其实就是在添加完成调试断点之后,再点击一下上面的保存按钮就可以将其转换为会话断点。在下次调试时依然会进入这个断点的位置。



4.外部断点
(1)添加外部断点
外部断点的添加方式和上面的会话断点添加方式类似。一样是现将光标放置于需要添加的断点的行处。然后点击外部断点按钮添加。

(2)设置断点生效账户
外部断点和会话断点的一个区别就是会话断点是对自己的账号生效的,但是外部断点是可以设置为别人的账号生效的。常用于接口调试等情况。
下面介绍下如何设置外部断点与别人的账号进行绑定。先添加一个外部断点,然后再GUI窗口的最上层点击实用程序 —-> 设置。

点击完上面的按钮之后会弹出下面的弹框,再弹框的页签中点击ABAP编辑器 —-> 调试。再此处输入用户的账号,然后点击右下角的对勾按钮

当外部断点生效后的调试界面其实都是一样的。

5.静态断点
此处的静态断点其实指的是使用代码编写的断点,因为只要执行到这行代码就会触发断点调试,不受其他因素的影响所以被称之为静态断点。
1 | BREAK-POINT. |

二、程序调试运行方式
1.程序调试运行方式分类
上面介绍了进入调试状态的断点类型与添加方式。但是只是进入调试状态是不够的,还需要一步一步的执行程序看程序的执行流程是否按照自己预期的内容进行了执行。而执行的过程总共有四种执行类型。
- 单步执行 F5:一行代码一行代码的执行,不会跳过Form、Function和子程序等,会进入其中逐行执行其中的逻辑。
- 单行执行 F6:在当前页面逐行执行,不会进入Form、Function和子程序,会直接执行完他们的逻辑,但不会进入其中逐行执行他们的逻辑。
- 跳出本段子逻辑 F7:当你进入了一个Form、Function或子程序的子逻辑中,你想跳转到当前子逻辑执行完成的代码行处就是用该执行方式即可,他会帮你把当前的子逻辑全部执行完成,然后跳转到该子逻辑执行结束的行处。
- 执行到下一个断点处 F8:当你调试时设置了多个断点 ,而每两个断点间的逻辑你不关心或与你的调试无关想要直接运行到下一个断点时就是用该执行方式。它可以帮你从执行的当前行跳转到下一个断点处。
2.单步执行 F5
(1)图标位置
进入调试状态后有两种执行单步执行的方式。第一种是通过快捷键 F5单步执行;第二种是通过调试界面左上角的单步执行按钮进行调试。单步执行的调试按钮位置如下图所示,在整个调试界面的左上角。

(2)执行效果
单步执行是不会跳过任何一个程序逻辑块的,可以理解成是程序自己执行的最真实的状态。像上图所示,当前调试已经执行到一个Form逻辑块处了,程序在执行时会找到当前Form逻辑块逻辑所在的位置然后一步一步的执行。而单步执行和程序执行一样,所以会进入到当前Perform的逻辑块中执行其中的逻辑。

3.单行执行 F6
(1)图标位置
和单步执行类似,这类执行方式基本都有两种。一种是通过界面按钮执行,一种是通过快捷键执行。单行的执行快捷键是F6,按钮在单步执行的后一个。

(2)执行效果
单行执行指在当前程序调试界面逐行执行。不会进入子逻辑或Function中,而是会直接获取到他们执行完成的后的结果。
以下图的执行方式为例,我们执行到Function时,使用单行执行时他会直接运行完Function,拿到Function最后运行完成的结果。

4.跳出本段子逻辑 F7
(1)图标位置
在单行执行按钮的后一个执行图标就是F7 跳出本段子逻辑的调试执行按钮。

(2)执行效果
当我们在调试时,进入到了一个逻辑十分复杂但是又与想调试的内容无太大关系的子逻辑或Function逻辑中时。我们想要快速执行完这段逻辑但又不想跳过本段子逻辑执行完后面的逻辑时就可以使用F7 跳出本段字段逻辑。
虽然叫做跳出本段子逻辑,单并不是指不执行本段子逻辑。而是执行完本段子逻辑剩余的逻辑后,停留在它的上层逻辑中。请参照下面的例子帮助理解。

下图为第404行的代码的子逻辑。在我们进入子逻辑之前可以看到返回值为0,但是在我们使用F7 跳出本段子逻辑返回子逻辑的上层逻辑时可以看到它的返回值为3。代表跳出本段子逻辑并不是直接跳过后续逻辑,而是执行完后续的逻辑,然后停留在子逻辑的上层调用逻辑处。

返回上层调用的逻辑处。

5.执行到下一个断点 F8
(1)图标位置
该执行方式的按钮是最后一个按钮。

(2)执行效果
当我们想要执行到下一个断点或直接执行完程序退出调试模式就可以使用这个按钮功能。当你执行到最后一个断点时,再次使用该按钮后就会将程序全部执行完。但如果执行到当前位置后还有断点再次点击该按钮就会执行到后面的断点。
在执行时,使用该执行方式是会将中间的逻辑全部执行完成的,例如下图所示的在执行前三个变量的值均为初始值0。

在执行到下一个断点后,这三个变量又都有值了。说明程序是会执行中间的逻辑的。

三、进阶程序调试
1.事务码进入调试状态 /H
(1)介绍
当我们想要快速进入调试状态时,可以在输入事务码的输入框内容输入’/h‘来进入调试状态。此方法十分常用也很便捷。
(2)操作步骤
例如我想要进入断点逻辑按钮的调试状态,我可以在点击按钮之前先使用/h然后按下回车键进入调试状态。

当激活调试状态后会在左下角弹框提示调试被激活的Message信息。

(3)执行效果
当进行完上面的操作之后,点击我们想要调试的功能,例如断点逻辑按钮就会进入他的调试界面。

2.通过Message信息添加断点
(1)介绍
在日常的程序调试与标准程序使用过程中我们都会遇到Message提示信息。但是只看Message信息还是不清楚被卡控的原因,这时就需要通过程序调试到报出该Message信息的地方去通过代码查看报错原因。
此时就需要我们找到报出该Message信息的Message ID与Message Number来创建断点了。当添加完该断点后再次执行程序就会停留在报出该Message信息的地方了。
(2)操作步骤
① 找到Message信息
如下图所示,当我们点击断点逻辑功能按钮时,在程序最下方提示了Message信息。

双击左下角的Message信息会弹出技术弹框,在弹框中有Message的ID与Number信息。此时我们可以选择两种添加方式,此处先介绍一种不通过Message信息添加断点的方式。
在弹框最上面的有一个技术信息的按钮,点击该按钮查看该Message信息的技术信息。

点击技术信息按钮后可以查看到该Message信息的详细内容。

此时我们双击下面的行输入框,可以跳转到报出该Message信息的代码行。然后可以在这里添加一个会话断点。

② 进入调试状态,添加断点
除了上面的那种方式外,还可以使用下面的方式添加Message 断点。先使用/h进入调试状态。

点击断点逻辑按钮,进入调试界面后点击新建断点的按钮,然后选择子页签为消息。

当断点设置成功后会在左下角显示Message:断点设置。此时我们再次点击执行到下一个断点(快捷键F8)按钮就可以运行到相应的Message处了。

(3)执行效果

3.创建监控点
(1)介绍
此处的创建监控点的运用场景是我想要测试当某一个变量的值为X时的场景,但是当前变量的值为X时还要执行很多次才行的场景。就可以使用这种断点添加方式。
用实际例子举例的话,就是循环。当我们在调试循环中的某一个变量在第300次循环时的情况时,我们就可以创建一个系统变量SY-TABIX = 300的监控点。
(2)执行步骤
① 添加监控点
如下图所示,我现在执行到了一个20次循环的语句。现在我想要调试他在第15次循环时LV_INDEX的值。此时我们就可以点击图中红框圈起来的按钮创建变量SY-INDEX = 15的监控点。

在下面的弹框中输入你要监控的变量名称与断点生效时变量的值。以本次的例子来讲,在弹框的最上面变量输入框中填入变量名称,下方的附加条件处填入断点生效时变量的值,当你不填值时每当这个变量的值产生变化时断点就会生效。最后点击右下角的对勾按钮添加监控点。

当你添加完成监控点之后,可以在调试界面的断点/监控点页签中选择下方的监控点页签查看你本次调试添加的监控点信息,在此处你还可以对其进行编辑或删除等操作。

(3)执行效果
进行完上面的操作之后,回到调试界面按下执行到下一个断点(快捷键F8)的按钮就可以直接执行到第15次循环时停下。下图是执行前的截图,可以看到当前执行到第419行而右侧的两个变量值都是0。

在我们按下执行到下一个断点的按钮后,可以看到程序在第420行停住了。而右侧的SY-INDEX变量值变为了15,左下角也提示了Message 已到达监控点(SY-INDEX)。此时就可以对你想要调试的内容进行调试了。

4.转到语句
(1)介绍
该功能是可以将程序执行移动到其他行然后开始执行,是一个十分实用的功能。当我们在调试时按键太快导致我们不小心执行过我们想要调试的逻辑处了,但重新调试执行又很麻烦。我们就可以使用转到语句功能直接跳转到想要调试的语句处,从新的位置开始执行。
但是有个注意事项。转到语句是跳转到某一行,并不是执行或回溯到某一行语句。在跳转时会保持跳转前各变量的值。所以在调试时如果你想要跳转到之前的语句的话需要考虑是否要变更部分变量的值到执行前的值。
(2)执行步骤
我想要调试第402行到第408行的全部内容,但是我现在的执行位置是第419行。此时我想要重新回到第402行进行调试就可以先将光标置于第402行,然后使用快捷键Shift + F12或右键 —> 转到语句。使程序重新跳转到第402行进行执行,此时请注意右侧的变量值是跳转前的变量值。

(3)执行效果
跳转后可以在第402行前面看到一个黄颜色的箭头,他代表当前程序执行的行。右侧的变量值没有变化,说明这个功能不是程序的回溯,仅仅只是跳转。因为本次的调试逻辑即便回溯到402行也不会影响结果,所以就不需要再次变更此时再执行的变量值了。

5.执行到当前行
(1)介绍
此功能是可以在不添加断点的情况下,直接执行到光标所在的行。和添加断点后使用执行到下一个断点(快捷键F8)的效果相同,但是这种方式不需要添加断点,只需要使用快捷键Shift + F8即可。
(2)执行步骤
如下图所示,我现在执行到了419行。但是我想要调试第430行的代码,如果我一行一行的执行过去的话,执行完20次循环十分耗费时间。此时我可以先将光标放置在第430行,此时可以先留意右侧变量LV_INDEX = 0。

(3)执行效果
然后使用快捷键Shift + F8直接让程序执行到第430行。此时可以观察到第430行前面有一个黄色的小箭头,代表程序现在停留在这一行。而此时的LV_INDEX变量值由0变为了20。说明程序是从第419行执行过来的,而不是跳转。
