强大功能揭秘:仓颉反向调试与时间线回放使用教程,让Bug无处遁形
强大功能揭秘:仓颉反向调试与时间线回放使用教程,让Bug无处遁形
仓颉 VSCode 插件(vscode_cangjie)内置了基于记录重放的「反向调试 + 时间线回放」能力:它会自动记录你正向调试时的所有停止点(断点、单步)以及对应的线程、堆栈、变量信息,让你可以"回到过去",直接查看 Bug 发生那一刻的程序现场。本教程带你从零配置到熟练掌握,5 步搞定仓颉反向调试,告别"复现不了"的崩溃 Bug。
1. 先搞懂原理:反向调试是怎么工作的?🕰️
传统调试只能"往前走",一旦错过了关键现场,就只能重启程序重新复现。仓颉插件的反向调试(Reverse Debug)反其道而行之:
- 自动记录:开启后,调试服务会记录正向调试过程中的每个停止点(断点 + 单步),连同该时刻的线程、栈帧、变量值一并缓存;
- 反向控制:进入反向模式后,支持反向单步、反向继续,一步步"倒带";
- 时间线回放:所有历史停止点以时间轴形式展示,点击任意记录点即可回到那一刻。
⚠️ 注意:反向调试目前仅支持 CJNative(原生)调试模式,CJVM 模式暂不支持。
2. 一键开启:3步启用反向调试自动记录
- 单击 VSCode 左下角齿轮图标,选择 Settings(设置);
- 在搜索栏输入
cangjie,找到 Reverse Debug 区域,勾选 Enable reverse debug; - 按需调整记录粒度(线程个数、堆栈个数、变量作用域、复杂类型子变量展开层数与个数),修改后重新启动仓颉调试即可生效。
相关配置项在源码中由 reverse-debug-config-property.ts 统一管理,会随调试启动下发给调试服务端。
3. 预埋反向断点:让关键代码"留个证据"
反向断点是一种特殊的源码断点(Log Point):正向调试时它不会停止程序,但调试服务会在后台默默记录进程经过它时的现场;进入反向模式后,它就变成一个可回看的停止点,能查看该处的线程、堆栈和变量。
支持 3 种设置方式:
方式一:单行手动设置——光标停在目标行,右键选择 Cangjie: Add Reverse Breakpoint:
方式二:整个文件自动设置——在仓颉源文件上右键选择 Cangjie: Add Auto Reverse Breakpoints,插件会自动分析文件内所有函数的入口和出口并批量设置反向断点:
方式三:整个文件夹自动设置——在文件夹上右键选择同名命令,插件会分析目录下所有仓颉源文件中函数的入口/出口位置,一次布好"证据链":
⚠️ 注意:进入反向调试模式后不能再设置新的反向断点,请在正向调试阶段提前设置。断点分析依赖 LSP 的
cangjie.location.entryAndExit命令,实现在 cangjie-reverse-debug.ts。
4. 时间线回放:拖动游标"穿越"到Bug现场
时间线(Timeline)是反向调试的"时光机"入口,位于 VSCode 右下方面板:
- 在右下角 Tab 标签行右键,勾选 Cangjie Debug Timeline 即可显示(也可通过
View菜单 >Open View开启):
时间线操作技巧:
| 操作 | 效果 |
|---|---|
| 拖动左右游标 | 框选出一段时间区域 |
| 选中区域后按住拖动(鼠标变小手) | 平移查看的时间窗口 |
| 在主时间线按住拖动(十字光标) | 划选一个新的时间区域 |
Ctrl + 鼠标滚轮 |
放大 / 缩小选中区域 |
| 单击时间线上的记录点 | 编辑器定位到对应源码行,调试信息面板同步刷新线程、栈帧和变量 |
每条时间线标识一个仓颉线程或系统线程,多线程问题也能各看各的。时间线界面由 debug-ui/ui-timeline/ 模块渲染,支持记录点定位与范围选择交互。
5. 反向单步与回看现场 🎬
- 单击顶部调试工具栏上的时钟图标进入反向调试模式;
- 使用工具栏上的反向单步、反向继续按钮逐步"倒带",每走一步都能查看历史记录的线程、堆栈、变量信息;
- 单击方块图标退出反向模式,调试会回到正向调试的最后停止点。
对应的调试请求(stepInReverse / reverseStep / continueInReverse / reverseContinue)实现在 cangjie-reverse-debug.ts。
回到历史停止点后,查看现场的方法与正向调试一致:
- VARIABLES 视图看变量树,鼠标悬停变量名可快速预览;
- Debug Console 调试控制台直接输入变量名查看值;输入以
-exec开头的 cjdb 命令可执行原生命令,例如:
6. 常见问题速查 💡
Q:为什么开启后时间线上没有任何记录?
确认已勾选 Enable reverse debug 并重启了调试会话;且当前为 CJNative 原生模式。
Q:为什么反向模式下加不了反向断点? 反向断点只能在正向调试阶段预设,进入反向模式后会被禁止,这是产品设计使然。
Q:记录点是什么? 只有"停止点"(断点命中、单步执行)会被记录为可回放的记录点,普通执行过的代码不会逐行记录。
Q:记录太多会不会拖慢调试? 可通过设置项控制线程个数、堆栈个数、变量展开层数等记录粒度,按需平衡性能与回放深度。
7. 延伸阅读
- 官方调试服务完整文档:docs/source_zh_cn/debug_service.md
- 反向调试核心源码:src/dap/src/reverseDebug/
- 时间线 UI 模块:debug-ui/ui-timeline/
掌握仓颉反向调试与时间线回放后,那些"偶现、难复现"的 Bug 将无处遁形——开启记录、预埋反向断点、拖一拖时间线,现场即刻重现。🎯





