VSCode调试Python代码执行os.system(cmd)时无法调试的问题求助
问题描述
在VSCode调试Python代码时,步进执行到os.system(train_cmd)语句时,调试器不会进入train_cmd对应的子进程代码(即lib/train/run_training.py),而是直接在调试控制台运行该命令。程序能正常执行,但无法对子进程内的逻辑进行断点调试。
相关代码:
import os import random def parse_args(): # 此处省略参数解析逻辑,根据实际场景实现 ... def main(): args = parse_args() if args.mode == "single": train_cmd = "python lib/train/run_training.py --script %s --config %s --save_dir %s --use_lmdb %d " \ "--script_prv %s --config_prv %s --distill %d --script_teacher %s --config_teacher %s --use_wandb %d"\ % (args.script, args.config, args.save_dir, args.use_lmdb, args.script_prv, args.config_prv, args.distill, args.script_teacher, args.config_teacher, args.use_wandb) elif args.mode == "multiple": train_cmd = "python -m torch.distributed.launch --nproc_per_node %d --master_port %d lib/train/run_training.py " \ "--script %s --config %s --save_dir %s --use_lmdb %d --script_prv %s --config_prv %s --use_wandb %d " \ "--distill %d --script_teacher %s --config_teacher %s" \ % (args.nproc_per_node, random.randint(10000, 50000), args.script, args.config, args.save_dir, args.use_lmdb, args.script_prv, args.config_prv, args.use_wandb, args.distill, args.script_teacher, args.config_teacher) elif args.mode == "multi_node": train_cmd = "python -m torch.distributed.launch --nproc_per_node %d --master_addr %s --master_port %d --nnodes %d --node_rank %d lib/train/run_training.py " \ "--script %s --config %s --save_dir %s --use_lmdb %d --script_prv %s --config_prv %s --use_wandb %d " \ "--distill %d --script_teacher %s --config_teacher %s" \ % (args.nproc_per_node, args.ip, args.port, args.world_size, args.rank, args.script, args.config, args.save_dir, args.use_lmdb, args.script_prv, args.config_prv, args.use_wandb, args.distill, args.script_teacher, args.config_teacher) else: raise ValueError("mode should be 'single' or 'multiple'.") os.system(train_cmd) # 此处无法进入子进程调试 if __name__ == "__main__": main()
解决方案
1. 直接导入子进程代码调用(推荐)
放弃通过os.system启动子进程,直接导入run_training.py的主函数并传递参数,调试器能直接跟进代码逻辑:
# 替换原有os.system(train_cmd)的代码 from lib.train import run_training # 整理参数为字典,适配run_training的main函数参数 train_args = { "script": args.script, "config": args.config, "save_dir": args.save_dir, "use_lmdb": args.use_lmdb, "script_prv": args.script_prv, "config_prv": args.config_prv, "distill": args.distill, "script_teacher": args.script_teacher, "config_teacher": args.config_teacher, "use_wandb": args.use_wandb } # 调用run_training的main函数 run_training.main(**train_args)
注意:需要确保run_training.py的main函数支持接收关键字参数,如果原来用的是argparse,可以修改run_training.py的参数解析逻辑,支持从字典导入参数,或者手动转换参数为命令行格式后传递。
2. 开启VSCode子进程调试
如果必须保留子进程调用方式,修改VSCode的.vscode/launch.json配置,开启子进程调试功能:
{ "version": "0.2.0", "configurations": [ { "name": "Python: 当前文件", "type": "python", "request": "launch", "program": "${file}", "console": "integratedTerminal", "justMyCode": false, "subProcess": true // 关键配置:开启子进程调试 } ] }
添加"subProcess": true后,调试器会自动附着到os.system启动的Python子进程,此时你可以在run_training.py中设置断点,调试时会自动触发。
3. 分布式训练场景的特殊处理
如果是使用torch.distributed.launch的多进程/多节点模式,需要额外调整:
- 在
launch.json中添加环境变量,优化调试器的附着能力:
{ "name": "Python: 分布式训练", "type": "python", "request": "launch", "program": "${file}", "console": "integratedTerminal", "justMyCode": false, "subProcess": true, "env": { "PYDEVD_WARN_EVALUATION_TIMEOUT": "1000", "PYDEVD_UNBLOCK_THREADS_TIMEOUT": "500" } }
- 建议改用
torch.distributed.run替代torch.distributed.launch,后者是PyTorch推荐的新启动方式,对调试场景的支持更完善,配合上述launch.json配置即可正常调试每个子进程。
内容的提问来源于stack exchange,提问作者Bailien Hsieh
相关产品推荐
相关产品推荐

