跳转至
🧪 本课内容基本定稿,校对中——发现错漏欢迎评论区指出。

第6课:ABAP 调试器

45分钟 | 阶段:基础篇 | 建议边读边做

前置依赖

  • 第5课:有可运行的 zac_sql_crud(本课的调试靶子)。

问题引入

程序跑出来的数不对——你怀疑 SQL 写错了,但不知道错在哪。用 WRITE 逐个打印变量是上个时代的做法。调试器就是那台"透视镜":程序暂停在你指定的行,你可以逐行看它执行、随手翻任何变量的值。调试能力直接决定你的排错速度,这节课值得慢讲。

时间安排

时段 内容 时长
场景引入 "结果不对但不知道为什么"的困境 3 分钟
Demo 跟做 断点 + 单步 + 内表 + Watchpoint 全流程 10 分钟
知识讲解 断点类型 / 单步语义 / 变量区 / 高级技巧 22 分钟
知识总结 调试速查卡 8 分钟
课后思考 练习 2 分钟

本课目标

完成本课你将能够:

  • 用行断点在任意位置暂停程序,并区分静态/动态/会话断点;
  • 熟练使用 F5 / F6 / F7 / F8 单步控制;
  • 在调试器中查看变量、结构体、内表和系统变量;
  • 用 Watchpoint 捕捉"某个变量变成某值的瞬间";
  • 在调试中临时修改变量值以测试不同分支。

Demo:调试 zac_sql_crud(分步跟做)

步骤 1:设置断点并触发

  1. SE38 打开 zac_sql_crud
  2. 光标放在第 2 段查询的 SELECT * FROM sflight(约第 20 行)行首,点"停止"图标或直接在行号左侧点击设置断点(该行变"停止"高亮)——这就是动态(会话)断点
  3. F8 运行。

你会看到什么: 屏幕切换进新式调试器(分屏:左边源代码,右边变量/调用栈等工作区),程序停在断点行——这行还没执行。

步骤 2:单步执行,亲眼看第一条查询

  1. F6(Step Over)两次——执行完 SELECT SINGLE,光标停在 IF sy-subrc = 0.
  2. 在右侧变量区(或直接在源码里双击变量名)查看 ls_sflight:展开结构体能看到每个字段的当前值;
  3. 单击工具栏的 SY 页签(系统变量):确认 SY-SUBRC = 0

步骤 3:翻内表

  1. F8 继续到下一个断点前?没有断点了——先按 F8 会直接跑完。重新来:再设一个断点在第 3 段 LOOP AT lt_join 处,F8 运行到那;
  2. 双击 lt_join:调试器以内表形式展示——可展开逐行翻看,每行再展开字段;
  3. 试着在翻看时对照第 5 课的 JOIN 逻辑:每行都有 carrname + cityfrom + cityto。

步骤 4:Watchpoint——捕捉"那一刻"

任务:想知道哪一轮操作后 sy-subrc 变成 4。

  1. 断点状态下,切换到 Watchpoints 页签 → 创建;
  2. Variable 填 SY-SUBRC,条件 <> 0
  3. F8 一路运行——程序会在 sy-subrc 首次非 0 的那行自动停下,而不是每个断点都停。

这就是 Watchpoint 与断点的本质区别:断点按"位置"停,观察点按"条件"停

步骤 5:调试中改值

双击某个变量进入 Field Contents 视图 → 修改值(如把 lv_rows 从 10 改成 3)→ 继续执行。后续逻辑会按改过的值走——"伪造现场"是测试 IF/ELSE 分支的快捷方式。

知识点

1. 断点类型全景

类型 怎么设 生命周期 场景
会话断点 编辑器/调试器中点行 当前登录会话 日常开发 90%
静态断点 BREAK-POINT 写在代码里 跟随代码,激活后在任何人的运行中触发 临时定位;上线前必须删
用户断点 BREAK jack 写在代码里 只对该用户触发 代码里留断点但只拦自己
外部断点 Settings → External Debugging 系统级(HTTP/RFC 入口) 调试 WebService / RFC / 接口调用(第16课)

生产环境的 BREAK-POINT 是事故

静态断点在生产系统会拦截所有用户的进程(后台作业直接挂起)。上线前搜索一遍代码里的 BREAK-POINT / BREAK 是发布检查单的固定项。

2. 单步语义:F5/F6/F7/F8

语义 什么时候用
F5 Step Into 进入 怀疑问题在被调 FORM/FM/方法内部
F6 Step Over 越过 默认选择:把当前行执行完,停在下一行
F7 Step Return 返回 已钻进子程序、想直接跑完它回到调用者
F8 Continue 放行到下一个断点 / Watchpoint / 结束

纪律:默认 F6,只在需要时 F5。 一头扎进系统标准函数里逐行走,是新手迷路的第一原因——迷路了就 F7 或看调用栈。

3. 看什么:变量区工具箱

  • 双击任意变量:进入详细视图(结构体逐字段、内表逐行、字符串完整内容);
  • 内表视图支持排序、滚动、查看行数;
  • 调用栈(Call Stack):当前断点"是怎么到达的"——从下往上读,排查标准程序里的增强入口时是关键工具(第15课增强查找会回收它);
  • 系统变量页签:SY-SUBRCSY-DBCNTSY-TABIX(当前循环行号)、SY-INDEX——排错时四个一起看。

4. 高级技巧速览

  • 语句断点:调试器里 Settings → Breakpoints → Statement:对"所有 CALL FUNCTION"这类语句设断点,不用知道位置;
  • Goto Statement:跳过不想执行的行(慎用,可能跳过必要的初始化);
  • 数据库变化视图:调试写操作时可在 Table 工具里直接查表数据看效果(配合第5课的"COMMIT 前后"观察);
  • /h:在任意屏幕命令栏输入 /h 回车,下一个动作直接进调试器——调试没源码入口的标准屏幕时是神器。

💡 实战经验

90% 的调试只需要 F6 + 双击变量

不要一上来 F5 钻进系统函数。先用 F6 扫完自己的逻辑,锁定"值从哪行开始不对",再对那一小段精耕。

Watchpoint 是 LOOP 的克星

"循环到第几轮出错"这类问题,手工单步要按几百次 F6;给嫌疑变量设条件 Watchpoint(如 <fs>-seatsocc < 0),程序自己停在出事现场。

外部断点别忘了

调试"从接口/WebService 进来的调用"(第16课的场景),普通断点拦不住——必须设外部断点并确认用户与调试开关匹配。这是接口调试第一天必撞的墙。

📖 延伸阅读

课后思考

把你的回答写在页面底部评论区,注明题号,一起讨论。

  1. F5 和 F6 的区别?什么信号告诉你"该 F7 了"?
  2. 断点与 Watchpoint 的本质区别是什么?各举一个适用场景。
  3. 实操:给 zac_sql_crud 设 Watchpoint,捕捉 SY-DBCNT 首次大于 0 的时刻,截图或描述程序停在哪一行、为什么。
  4. 为什么生产系统代码里绝对不能留 BREAK-POINT?它和 BREAK 用户名 的风险差异在哪?

下一课:第7课:选择屏幕——基础篇收官,进入核心篇。

留言讨论