问题
使用 pytracking 框架的跟踪器, 在训练时控制台无报错, 但也没有任何反应. 强行停止后发现卡在 ltr_trainer.py
的 enumerate
处, 疑似死循环.
调试
请按照教程
准备
在调试前, 请确保你是直接运行 project/lib/train/run_training.py
文件, 而不是 project/tracking/train.py
. 否则你将无法调试, 你应该在 train.py
里打印出命令行语句, 然后添加到 PyCharm 的运行配置里.
按照上图打印出运行指令, 修改后的配置如下:
复现
CV库会使用多线程来加载图片, 不利于调试, 在 project/experiments
文件夹里修改跟踪器配置文件, 将 NUM_WORKER
改为 0
. 注意是你运行的那个配置, 不要改错了.
1 | TRAIN: |
然后运行代码, 等一会儿, 当控制台没有输出后, 直接强制停止. 此时应该已经卡在死循环内. 你会看到控制台有 KeyboardInterrupt
报错,然后顺着这个报错去找死循环位置.
定位死循环
你会在控制台看到以下报错:
点击最底下的, 且位于site-packages
是库文件, 请直接跳过. 点击后会直接跳转到中断处, 为这一行打断点, 点击左侧的行号即可.
接下来调试运行, 程序暂停在断点处. 如果你的程序没有暂停, 说明你运行的是 project/tracking/train.py
, 请查看 准备 一节.
正常情况如下图所示.
可以看到现在调用的是 _read_target_visible()
函数, 左下角是调用栈, 可以查看当前线程和变量, 也可以切换到控制台. 多次点击右上角的 “恢复” 按钮(红圈里的), 然后切换到控制台选项卡, 如果每次都在这里中断, 没有进入死循环, 并且控制台没有输出, 说明当前断点位置就在死循环里.
但是这个函数里并没有 while
出现, 说明死循环在外部. 现在转到图片左下角调用栈, 按照从上往下的顺序逐个查看代码. 你只需要查看项目代码, 库文件已经自动变灰, 不用查看.
我在查看到第 3 层时, 发现 while
循环.
为了判断此处是否是死循环, 我们取消之前的断点, 在此处重新打一个断点, 然后单步运行(F8). 我们发现程序可以正常离开循环, 说明此处不是死循环.
于是我们在左下角继续查找, 发现第 4 层也是 while
循环. 同理, 我们取消掉之前的断点, 在这一层打一个新断点, 然后单步运行(F8).
此时我们发现程序无法离开循环, 并且执行到了 except
语句, 说明此处是死循环.
解决问题
我们发现此处使用了 except
语句, 这会导致控制台没有报错. 现在我们要查看具体的报错, 直接在这里打印即可.
1 | import traceback |
再次运行(现在不用调试了), 控制台会打印出一堆报错. 由于是死循环, 报错会重复打印.
定位至报错点, 打上断点, 进行调试.
现在只需要按照正常流程解决 bug 即可.
分析可知此处使用 /
来分割字符串, 但字符串里实际上反斜杠 \
, 因此出错, 只需要将代码修改为反斜杠即可解决.