使用vscode进行代码调试/以及使用debugpy进行复杂代码调试
- 前言:
- 方法一:使用ipdb对程序进行调试
-
- 1.1 直接命令行运行ipdb:(不建议直接命令行运行,建议代码中插入)
- 1.2 直接在代码片段中插入ipdb(推荐使用这个方法):
- 1.3 ipdb命令行调试的一些常用指令:
- 方法二:VScode中的python调试
-
- 2.1 简单调试
- 2.2 复杂命令调试(命令行调试)
-
- 2.21 debugpy直接插入代码里:
- 2.22 如何修改复杂命令?
- 参考文档
前言:
大家首先要会使用vscode连接服务器,之后再考虑调试,连接服务器。可以参考下面这个帖子: ssh使用vscode连接linux服务器【autodl服务器】,并调出命令行运行代码【允许python代码跳转】
笔者已经提前在服务器上安装了Python和Python Debugger插件。大家也提前安装一下。
方法一:使用ipdb对程序进行调试
1.1 直接命令行运行ipdb:(不建议直接命令行运行,建议代码中插入)
首先需要安装 ipdb:
pip install ipdb
之后我们可以试着创建一个代码文件,就叫它test.py 吧。
class Book:
def __init__(self, title, author, year):
self.title = title
self.author = author
self.year = year
def __str__(self):
return f"'{self.title}' by {self.author} ({self.year})"
class Library:
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
def remove_book(self, title):
self.books = [book for book in self.books if book.title != title]
def find_books_by_author(self, author):
return [book for book in self.books if book.author == author]
def list_books(self):
for book in self.books:
print(book)
def main():
library = Library()
# 添加书籍
library.add_book(Book("1984", "George Orwell", 1949))
library.add_book(Book("To Kill a Mockingbird", "Harper Lee", 1960))
library.add_book(Book("The Great Gatsby", "F. Scott Fitzgerald", 1925))
library.add_book(Book("Brave New World", "Aldous Huxley", 1932))
# 列出所有书籍
print("All books in the library:")
library.list_books()
print()
# 查找某个作者的书籍
author = "George Orwell"
print(f"Books by {author}:")
books_by_author = library.find_books_by_author(author)
for book in books_by_author:
print(book)
print()
# 删除书籍
library.remove_book("1984")
print("After removing '1984':")
library.list_books()
# 使用循环进行一些复杂操作
print("\\nBooks published before 1950:")
for book in library.books:
if book.year < 1950:
print(book)
if __name__ == "__main__":
main()
在终端上输入
python –m ipdb test.py
就可以从程序开头一行一行的调试了:
1.2 直接在代码片段中插入ipdb(推荐使用这个方法):
但是直接在代码中运行ipdb的话,可能不能直接命中我们需要调试的片段,特别是如果我们跑一个非常大的项目的时候,只希望在项目中的某一个代码文件的某一片段检查一下,我们需要在那个需要中断的地方插入上如下代码。
import ipdb;ipdb.set_trace();
程序跑的时候就会在你设置断点的位置停下来。 我们在#删除书籍上面插入了import ipdb;ipdb.set_trace(); 程序也刚好运行到这里停了下来。如果是大项目中的某一个代码文件,这样插入也有用。
1.3 ipdb命令行调试的一些常用指令:
- h:帮助命令(help)
- s:(step into)进入函数内部
- n:(next)执行下一行
- b: (break)b line_number对某行号打断点
- cl: (clear)清除断点
- c: (continue)一直执行到断点
- r: (return)从当前函数返回
- j: (jump)j line_number,跳过代码片段,直接执行指定行号所在的代码
- l: (list)列出上下文代码
- a: (argument)列出传入函数所有的参数值
- p/pp: print 和 pretty print 打印出变量值
- r: (restart)重启调试器
- q: (quit)退出调试,清除所有信息
方法二:VScode中的python调试
2.1 简单调试
我们现在仍然使用上面创建的test.py文件作为案例来讲解。
从服务器文件中点开test.py,同时打上断点(小红点)。
之后,从左侧“运行”选项卡访问调试程序。点击“运行和调试”之后,在上方选择调试器处,我选择了“Python Debugger”调试器。(因为我想调试的是python代码,如果是其他的代码,比如Node.js,也要更换相应的调试工具。) 之后选择当前python文件(第一条,也就是我们现在点开的test.py文件)
然后程序运行到断点就停下来了。
至于调试的按钮,大家有过调试经验的,尝试一下就知道了,就不细说了。
当然也可以直接从vscode程序的右上角,进行python代码运行和调试。
2.2 复杂命令调试(命令行调试)
在vsocde中,有两种核心调试模式:Launch和Attach。我通常使用Attach模式进行复杂命令的调试。
有的时候,我不是只跑一个文件,而是跑一个非常大的项目,同时项目的执行命令非常复杂,这个时候如何调试呢?
比如我现在想调试scene graph generation benchmark项目。
其运行命令如下:
CUDA_VISIBLE_DEVICES=0,1 python -m torch.distributed.launch –master_port 10026 –nproc_per_node=2 tools/relation_train_net.py –config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL False MODEL.ROI_RELATION_HEAD.PREDICTOR CausalAnalysisPredictor MODEL.ROI_RELATION_HEAD.CAUSAL.EFFECT_TYPE none MODEL.ROI_RELATION_HEAD.CAUSAL.FUSION_TYPE sum MODEL.ROI_RELATION_HEAD.CAUSAL.CONTEXT_LAYER motifs SOLVER.IMS_PER_BATCH 12 TEST.IMS_PER_BATCH 2 DTYPE “float16” SOLVER.MAX_ITER 50000 SOLVER.VAL_PERIOD 2000 SOLVER.CHECKPOINT_PERIOD 2000 GLOVE_DIR /home/kaihua/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/kaihua/checkpoints/pretrained_faster_rcnn/model_final.pth OUTPUT_DIR /home/kaihua/checkpoints/causal-motifs-sgcls-exmp
这种情况,没有办法直接通过调试按钮进行运行。不过幸运的是,如果在您的 Python 环境中安装了debugpy,调试器也可以从命令行运行。 调试器命令行语法如下:
python –m debugpy
––listen | ––connect
[<host>:]<port>
[––wait–for–client]
[––configure–<name> <value>]...
[––log–to <path>] [––log–to–stderr]
<filename> | –m <module> | –c <code> | ––pid <pid>
[<arg>]...
接下来我会解释如何使用命令行调试功能。
pip install debugpy





{
"version": "0.2.0",
"configurations": [
{
"name": "Python 调试程序: 当前文件",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 6006
}
}
]
}
之后我们在命令行运行如下命令(因为wait-for-client服务器端开始受到调试指令,并等待客户端的进一步命令):
python –m debugpy ––listen 6006 ––wait–for–client ./test.py
接着我们点击F5。和远程服务器成功连接,并且可以从我们打断点的地方开始调试: 运行大项目的时候,使用attach调试模式会非常方便。
2.21 debugpy直接插入代码里:
实际上可以直接把debugpy放在代码里运行(这个方法不用修改命令行的命令,可能会简单一点?):
在代码入口放入:
import debugpy
debugpy.listen(("localhost", 5678))
print("Waiting for debugger attach…")
debugpy.wait_for_client()
# debugpy.breakpoint()
print("Debugger attached.")
# 你的程序代码
之后本地运行你的Python脚本,点击F5:
python your_script.py
(我一步直接修改命令,这个方法没有尝试过)
2.22 如何修改复杂命令?
比如我们运行的程序命令如下,如何修改成attach可以识别并调试的命令呢?
CUDA_VISIBLE_DEVICES=0,1 python -m torch.distributed.launch –master_port 10026 –nproc_per_node=2 tools/relation_train_net.py –config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL False MODEL.ROI_RELATION_HEAD.PREDICTOR CausalAnalysisPredictor MODEL.ROI_RELATION_HEAD.CAUSAL.EFFECT_TYPE none MODEL.ROI_RELATION_HEAD.CAUSAL.FUSION_TYPE sum MODEL.ROI_RELATION_HEAD.CAUSAL.CONTEXT_LAYER motifs SOLVER.IMS_PER_BATCH 12 TEST.IMS_PER_BATCH 2 DTYPE “float16” SOLVER.MAX_ITER 50000 SOLVER.VAL_PERIOD 2000 SOLVER.CHECKPOINT_PERIOD 2000 GLOVE_DIR /home/kaihua/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/kaihua/checkpoints/pretrained_faster_rcnn/model_final.pth OUTPUT_DIR /home/kaihua/checkpoints/causal-motifs-sgcls-exmp
方法一: 在项目入口代码里直接放上debugpy,就不用修改复杂命令了。 方法二:交给gpt就好啦。让GPT去修改。
我问gpt:
我现在想要使用vscode的debugpy调试一个项目,项目的运行命令如下: CUDA_VISIBLE_DEVICES=0,1 python -m torch.distributed.launch –master_port 10026 –nproc_per_node=2 tools/relation_train_net.py –config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL False MODEL.ROI_RELATION_HEAD.PREDICTOR CausalAnalysisPredictor MODEL.ROI_RELATION_HEAD.CAUSAL.EFFECT_TYPE none MODEL.ROI_RELATION_HEAD.CAUSAL.FUSION_TYPE sum MODEL.ROI_RELATION_HEAD.CAUSAL.CONTEXT_LAYER motifs SOLVER.IMS_PER_BATCH 12 TEST.IMS_PER_BATCH 2 DTYPE “float16” SOLVER.MAX_ITER 50000 SOLVER.VAL_PERIOD 2000 SOLVER.CHECKPOINT_PERIOD 2000 GLOVE_DIR /home/kaihua/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/kaihua/checkpoints/pretrained_faster_rcnn/model_final.pth OUTPUT_DIR /home/kaihua/checkpoints/causal-motifs-sgcls-exmp
我现在想要使用vscode的attach调试功能,使用6006端口号,像运行这个小文件一样运行这个项目: python -m debugpy –listen 6006 –wait-for-client ./test.py
那我应该如何修改这个项目的运行指令呢?我说的不是在文件中添加debugpy代码,而是命令行直接运行并调试。
gpt回答: gpt回答:
CUDA_VISIBLE_DEVICES=0,1 python -m debugpy –listen 6006 –wait-for-client -m torch.distributed.launch –master_port 10026 –nproc_per_node=2 tools/relation_train_net.py –config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL False MODEL.ROI_RELATION_HEAD.PREDICTOR CausalAnalysisPredictor MODEL.ROI_RELATION_HEAD.CAUSAL.EFFECT_TYPE none MODEL.ROI_RELATION_HEAD.CAUSAL.FUSION_TYPE sum MODEL.ROI_RELATION_HEAD.CAUSAL.CONTEXT_LAYER motifs SOLVER.IMS_PER_BATCH 12 TEST.IMS_PER_BATCH 2 DTYPE “float16” SOLVER.MAX_ITER 50000 SOLVER.VAL_PERIOD 2000 SOLVER.CHECKPOINT_PERIOD 2000 GLOVE_DIR /home/kaihua/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/kaihua/checkpoints/pretrained_faster_rcnn/model_final.pth OUTPUT_DIR /home/kaihua/checkpoints/causal-motifs-sgcls-exmp
之后我们再对master_port的端口号做一些修改,比如修改成6006这样,稍微改一改,复杂命令的项目就能成功运行啦。
我在这里贴一下我的源命令和修改过后的命令,方便大家参考(这里去掉了master_port 和 nproc_per_node ,实际上我觉得修改过就可以了,重新加上也可以,可能是我当时跑的时候线程不够用了。):
原命令:
CUDA_VISIBLE_DEVICES=0 python -m torch.distributed.launch –master_port 10027 –nproc_per_node=1 tools/relation_test_net.py –config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL True MODEL.ROI_RELATION_HEAD.PREDICTOR TransformerPredictor TEST.IMS_PER_BATCH 1 DTYPE “float16” GLOVE_DIR /home/Scene-Graph-Benchmark.pytorch/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/Scene-Graph-Benchmark.pytorch/checkpoints/rtpb-precls-exmp OUTPUT_DIR /home/Scene-Graph-Benchmark.pytorch/checkpoints/rtpb-precls-exmp
修改后的命令:
CUDA_VISIBLE_DEVICES=1 python -m debugpy –listen 45396 –wait-for-client tools/relation_test_net.py –config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL True MODEL.ROI_RELATION_HEAD.PREDICTOR TransformerPredictor TEST.IMS_PER_BATCH 1 DTYPE “float16” GLOVE_DIR /home/Scene-Graph-Benchmark.pytorch/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/Scene-Graph-Benchmark.pytorch/checkpoints/rtpb-precls-exmp OUTPUT_DIR /home/Scene-Graph-Benchmark.pytorch/checkpoints/rtpb-precls-exmp
参考文档
命令行可选项(可以咨询gpt分别都是什么意思):
评论前必须登录!
注册