元数据卡
- 前置知识:调试器基础(断点 + 步进)
- 预计时间:15 分钟
- 阅读模式:高度专注 + 边读边敲
- 完成标志:能用条件断点、读调用栈、在 WATCH 面板中写表达式
你的进度
基础断点让你能停住程序看变量。但问题更狡猾了——一万步工序里只有一个步骤有 bug,你不想每次都按 F10。或者你看到了一个错误的值,但不知道是谁把参数传错了。
这时候你需要更精细的工具。
第二场战斗:只在特定条件下停住
你的锻造流程有一万个步骤,你怀疑某一步签入的参数不对。但每次设断点,前 9999 步都停住——你得一直按 F5 跳过。
你不需要在循环里每个元素都停——你可以在特定条件下才断住。
在 VS Code 里,右键点击断点 → 选择"Edit Breakpoint…":
for it in items:
● if it["weight"] == 99999: # ← 只有当重量等于 99999 时才停
valid.append(it)如何设置: 右键红点,输入条件表达式 it["weight"] == 99999效果: 前面 weight = 100、weight = 200 都不停。直到那万中无一的 weight = 99999——啪,停住了。
条件断点的本质: 同一个断点,加了一个"门卫"。程序每次经过这行都检查条件——条件为
true才停。这叫无副作用的观察——不影响程序性能,不影响状态。
第三场战斗:谁把我叫到这里来的?
淬火池的温度读数返回了 0,但你知道它不该是 0。你在温控函数里设了断点——停下了,参数正常。但问题在调用者——谁传进来的参数?
你需要回溯调用链条。
# forge_calculator.py
def calc_material_cost(item_id, weight):
discount = get_alloy_discount(weight)
def get_alloy_discount(weight):
ratio = get_discount_ratio()
return weight * ratio
def get_discount_ratio():
return 0 # 总是 0 —— bug 在这里!在 get_alloy_discount 设断点。程序停住后看 CALL STACK 面板:
CALL STACK
get_alloy_discount (forge_calculator.py:6)
calc_material_cost (forge_calculator.py:3)
<module> (forge_calculator.py:10)阅读方向:从下往上。
<module>是入口calc_material_cost调用了get_alloy_discount- 当前停住的是
get_alloy_discount(最上面一行)
你双击 calc_material_cost——调试器带你跳到调用者那一行,所有变量状态都保留着。这就是调试器的"时空穿梭"。
第四场战斗:让我算算这个表达式
你看到了变量的值——铁锭重量 = 100,杂质比例 = 0.1。但你想知道 weight * (1 - ratio) 等于多少。你不想在代码里加一个新变量来存——这轮调试完还得删。
在 WATCH 面板里输入表达式:
WATCH
weight * (1 - ratio): 90.0
round(weight * (1 - ratio), 2): 90.0如何运行: 在断点停住时,WATCH 面板下方点"+",输入任意 Python/Java 表达式 效果: 调试器在当前上下文中求值,实时显示结果
你也可以在 调试控制台(Debug Console) 里写更复杂的表达式:
>>> weight * (1 - ratio)
90.0
>>> [it["weight"] for it in items if it["weight"] > 100]
[200, 99999]甚至可以修改变量的值:
>>> n = 100 # 临时把 n 改成 100,程序继续跑会用到这个新值小心: 在调试控制台修改变量不是模拟——你是真的在改内存。可以用来测试边界情况,但要记得恢复。
日志断点:不想停,只想看
有时候你不想停程序,只想看变量在每次循环里的变化——但又懒得写 print()。
右键断点 → 选择"Log Message"(VS Code),输入消息模板:
● # 日志断点:不暂停,只输出
# Log message: "当前工件 ID: {m['id']} 重量: {m['weight']}"效果: 程序不会停,但调试控制台会打印:
当前工件 ID: 1 重量: 100
当前工件 ID: 2 重量: 0
当前工件 ID: 3 重量: 200这是"零侵入"调试——日志不是代码,关掉调试模式就消失了。不用删。
附录:GDB(不写 C/C++ 可以跳过)
GDB(GNU Debugger)是命令行版的调试器,概念同 IDE 调试器:
# 编译时加 -g 包含调试信息
gcc -g myprog.c -o myprog
gdb ./myprog
# GDB 内部
(gdb) break main # 设断点
(gdb) run # 运行
(gdb) print x # 看变量 x
(gdb) next # 步过
(gdb) step # 步进
(gdb) backtrace # 看调用栈
(gdb) quit语言: Bash / GDB 如何运行: gcc -g program.c -o program && gdb ./program
当你只能 SSH 到一个没有桌面的服务器上 debug 时,GDB 是你唯一的可能。暂时用不到——但知道它存在就够了。
→ 下一步
进阶工具在手,但脑子里还不够熟练。下一站给你一个调试练习场——热身题、递归挑战、以及几个专门设计的排障场景。