使用vscode进行服务器python代码调试/以及使用debugpy进行复杂代码调试

前言:

大家首先要会使用vscode连接服务器,之后再考虑调试,连接服务器。可以参考下面这个帖子:
ssh使用vscode连接linux服务器【autodl服务器】,并调出命令行运行代码【允许python代码跳转】

笔者已经提前在服务器上安装了PythonPython 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中,有两种核心调试模式:LaunchAttach。我通常使用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>]...

接下来我会解释如何使用命令行调试功能

  1. 安装debugpy:
pip install debugpy
  1. 点击创建launch.json文件。
    在这里插入图片描述
  2. 我们选择Python Debugger。并且继续选择当前python文件。打开launch.json文件。
    在这里插入图片描述
    刚才是没有进入调试器时的操作,如果你已经进入了调试器,可以直接点击添加配置。打开launch.json文件。
    在这里插入图片描述
    4… 修改launch.json文件。
    初始时的launch.json文件是这样的:
    在这里插入图片描述
    launch.json中可选的调试方式有两种,一种是launch,一种是attach,之后我们把request修改成attach的模式。即如下:(注意,端口号要选择自己服务器的端口号。我是用的autodl服务器,这个服务器可选的端口号6006 (如果使用的商业服务器比如autodl,可能连接的时候不能翻墙))
    在这里插入图片描述
{
    "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

参考文档

  1. VS Code 中的 Python 调试
  2. VS Code 中的 Python 调试
  3. 在 VS Code 中开始使用 Python

命令行可选项(可以咨询gpt分别都是什么意思):
在这里插入图片描述

### 配置 VSCode 进行远程服务器上的 Python 代码分步调试 #### 安装必要的扩展 为了实现这一目标,需要先安装 Remote - SSH 扩展以及 Python 扩展。Remote - SSH 可以让开发者通过SSH协议连接到远程机器上开发;而Python扩展则提供了对Python语言的支持功能。 #### 设置远程连接 打开命令面板 (Ctrl+Shift+P),输入 `Remote-SSH: Connect to Host...` 并选择要连接的目标主机。如果这是首次连接,则需按照提示完成身份验证过程[^3]。 #### 创建或编辑 launch.json 文件 一旦成功建立了与远程服务器之间的会话,在项目根目录下找到 `.vscode/launch.json` 或者新建该文件用于定义启动配置项。下面是一个简单的例子: ```json { "version": "0.2.0", "configurations": [ { "name": "Python: Remote Debug", "type": "python", "request": "attach", "connect": { "host": "localhost", "port": 5678 // 确认此端口未被占用,并且防火墙允许访问 }, "pathMappings": [ { "localRoot": "${workspaceFolder}", "remoteRoot": "/home/user/project" } ] } ] } ``` 上述 JSON 片段中,“localRoot”指向本地工作区路径,“remoteRoot”则是指代远程服务器的工作空间位置。确保这两个值分别对应实际存在的文件夹地址[^1]。 #### 启动远程调试器 在远程服务器终端里激活相应的虚拟环境(如果有),接着运行如下命令开启监听模式: ```bash python3 -m debugpy --listen 0.0.0.0:5678 your_script.py ``` 这一步骤使得远程服务能够接收来自 Visual Studio Code 发送过来的断点指令和其他控制信号[^4]。 当一切准备就绪之后,回到 VSCode 中按下 F5 键即可触发调试流程。此时应该可以看到程序执行进度条停止于首个设定好的断点处等待进一步操作了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值