当前位置: 首页 > news >正文

pdb调试器详解

文章目录

    • 1. 启动 pdb 调试器
      • 1.1 在代码中插入断点
      • 1.2 使用命令行直接调试脚本
    • 2. 常用调试命令
      • 2.1 基本命令
      • 2.2 高级命令
      • 2.3 断点操作
    • 3. 调试过程示例
    • 4. 调试技巧
      • 4.1 条件断点
      • 4.2 自动启用调试
        • 4.2.1 运行程序时指定 -m pdb
        • 4.2.2在代码中启用 pdb.post_mortem
        • 4.2.3 使用 sys.excepthook 全局捕获异常
      • 4.3 配合 ipdb 使用
    • 5. 高级用法 bt
      • 5.1. bt 命令作用
      • 5.2 示例代码
      • 5.3. 常见用法
      • 5.4 示例:结合 bt 和 up/down

pdb 是 Python 内置的交互式调试工具,可以帮助开发者逐步调试代码、查看变量、分析问题。以下是 pdb 调试器的详解,包括用法、常见命令及技巧

1. 启动 pdb 调试器

1.1 在代码中插入断点

通过 pdb.set_trace() 设置断点,程序运行到此处时会暂停并进入调试模式。

import pdbdef example_function():x = 10y = 20pdb.set_trace()  # 设置断点z = x + yprint(f"Result: {z}")example_function()

运行程序后,会暂停在set_trace()处,进入交互式调试模式。

1.2 使用命令行直接调试脚本

通过 -m pdb 启动脚本进入调试模式:

python -m pdb script.py

程序会在脚本的第一行暂停,可以逐步执行代码。

运行脚本时加上 -m pdb 参数,发生异常时会自动进入调试模式

python -m pdb script.py

或者在代码中引入

import pdb
pdb.pm()  # 在异常后调用,进入调试模式
  • 正常运行 script.py。
  • 如果程序中发生异常,pdb 会捕获它并进入调试模式。
  • 你可以直接使用调试命令,比如 bt 查看调用栈,或者 l 查看代码。

2. 常用调试命令

2.1 基本命令

在这里插入图片描述

2.2 高级命令

在这里插入图片描述

2.3 断点操作

(1) 设置断点

b 12  # 在第 12 行设置断点
b example_function  # 在函数 example_function 的入口处设置断点
b path/script.py:15  # 在 script.py 的第 15 行设置断点

(2)查看断点

b  # 列出所有断点及其状态

(3)清除断点

cl 1  # 清除断点编号 1
cl    # 清除所有断点

(4)启动、关闭断点

disable 7  # disable breakpoint 7
enable 7   # enable breakpoint 7

(5)条件断点

b path/script.py:20, x > 10  # 在第 script 脚本的第20 行设置断点,只有 x > 10 时断点才生效

3. 调试过程示例

假设以下代码存在问题:

def add_numbers(a, b):result = a + breturn resultdef main():x = 10y = "20"  # Bug: y 是字符串类型z = add_numbers(x, y)print(f"The result is {z}")main()

我们可以用 pdb 调试:

添加断点的方式
将 pdb.set_trace() 添加到代码中

def add_numbers(a, b):result = a + breturn resultdef main():x = 10y = "20"pdb.set_trace()  # 在此处调试z = add_numbers(x, y)print(f"The result is {z}")main()

运行程序并调试:

python script.py

调试流程:

  • 程序暂停在 set_trace(),输入 n 执行下一行代码。
  • 使用 p x p y 查看变量值。
  • 当执行到 add_numbers 时,输入 s 进入函数,逐步查看函数内部。
  • 如果确定错误原因,输入 q 退出调试。

通过命令行调试
直接运行调试命令

python -m pdb script.py

调试流程:

  • 程序在第一行暂停,输入 c 跳到程序出错处。
  • 出现异常时,自动进入调试模式,输入w查看调用栈。
  • 使用p查看变量值,定位问题。

4. 调试技巧

4.1 条件断点

在某些复杂情况下,只在特定条件下暂停:

b 10, x > 50

例如:当变量 x 大于 50 时,才会触发断点。

4.2 自动启用调试

4.2.1 运行程序时指定 -m pdb

运行 Python 脚本时,加上 -m pdb,会在发生异常时自动进入调试模式。

python -m pdb script.py
  • 正常运行 script.py。
  • 如果程序中发生异常,pdb 会捕获它并进入调试模式。
  • 你可以直接使用调试命令,比如 bt 查看调用栈,或者 l 查看代码。
4.2.2在代码中启用 pdb.post_mortem

在代码中,通过捕获异常并调用 pdb.post_mortem(),让程序在异常发生后自动进入调试模式
示例代码

import pdbdef faulty_function():x = 1 / 0  # 人为制造一个异常try:faulty_function()
except Exception:pdb.post_mortem()

工作原理

  • 当 faulty_function 发生异常时,程序会捕获 Exception。
  • 调用 pdb.post_mortem(),进入异常发生时的调试模式。
  • 在调试模式中,可以查看变量值、调用栈等。
4.2.3 使用 sys.excepthook 全局捕获异常

通过覆盖 Python 的全局异常处理机制,任何未捕获的异常都会触发 pdb 调试。

示例代码:

import pdb
import sysdef custom_excepthook(exc_type, exc_value, exc_traceback):print(f"Uncaught exception: {exc_type.__name__}: {exc_value}")pdb.post_mortem(exc_traceback)# 设置全局异常处理
sys.excepthook = custom_excepthook# 测试代码
def faulty_function():x = 1 / 0  # 人为制造一个异常faulty_function()

工作原理:

  • 覆盖sys.excepthook后,任何未捕获的异常都会调用 custom_excepthook
  • custom_excepthook 中,使用 pdb.post_mortem 进入调试模式。
  • 可以调试程序,查看异常发生的原因和调用栈。

在这里插入图片描述

  • 如果你想全局捕获异常并自动进入调试模式,sys.excepthook 是更灵活的解决方案。
  • 如果只需简单调试单个脚本,用 python -m pdb 即可。
  • 异常点进入调试,推荐用 pdb.post_mortem

4.3 配合 ipdb 使用

ipdb 是 pdb 的增强版本,提供更友好的界面和支持代码自动补全:

pip install ipdb

使用方法与 pdb 相同:

import ipdb
ipdb.set_trace()

pdb 是一个强大的调试工具,通过熟练使用断点、单步执行、调用栈分析等功能,可以帮助快速定位和解决问题。

5. 高级用法 bt

在 pdb 调试器中,btbacktrace(回溯调用栈) 的缩写,用来显示当前程序的 调用栈,包括函数的调用顺序、行号、文件等信息

5.1. bt 命令作用

  • 用途: 显示程序执行到当前断点或出错位置时的调用栈

  • 场景:

    • 调试程序时,查看函数调用路径。
    • 分析异常发生的上下文。
  • 调用栈显示的信息:

    • 从主函数(或脚本入口)到当前代码位置的调用路径。
    • 每一层的调用函数名、文件名和行号。

5.2 示例代码

以下是一个示例程序,含多个函数嵌套调用,模拟一个异常场景:

def level1():level2()def level2():level3()def level3():x = 10y = 0result = x / y  # 人为制造一个异常def main():level1()if __name__ == "__main__":main()

当运行程序时,会因 ZeroDivisionError 报错。

使用 bt 查看调用栈
(1) 启动程序并进入调试模式 启动程序,并在异常发生时自动进入调试模式:

python -m pdb script.py

(2) 异常发生后,自动进入调试器 输出类似以下信息:

Traceback (most recent call last):File "script.py", line 14, in <module>main()File "script.py", line 12, in mainlevel1()File "script.py", line 2, in level1level2()File "script.py", line 5, in level2level3()File "script.py", line 9, in level3result = x / y
ZeroDivisionError: division by zero
> File "script.py", line 9, in level3

(3) 输入 bt 查看调用栈 在调试器提示符下输入 bt

(Pdb) bt

输出如下:

Traceback (most recent call last):File "script.py", line 14, in <module>main()File "script.py", line 12, in mainlevel1()File "script.py", line 2, in level1level2()File "script.py", line 5, in level2level3()File "script.py", line 9, in level3result = x / y

bt 输出解析

  • 调用顺序: 从底部到顶部依次列出函数调用的路径。
  • 每一层信息:
    • File “script.py”, line 5, in level2:文件名、行号、函数名。
    • result = x / y:错误发生的代码上下文。

5.3. 常见用法

  • 在异常发生时分析调用路径 如果程序抛出了异常,可以用 bt 命令查看是在哪一层函数中出现了问题,从而快速定位问题。

  • 分析深层嵌套调用 如果程序包含多层函数调用,bt 可以帮助明确每一层函数调用的顺序,以及当前所处的位置。

  • 结合上下文调试

  • 使用 up/down 命令上下移动调用栈,查看不同层级的变量值。

  • 使用 l 查看特定调用层的代码。

相关命令
在这里插入图片描述

5.4 示例:结合 bt 和 up/down

继续调试前面例子的代码:

(Pdb) bt
Traceback (most recent call last):File "script.py", line 14, in <module>main()File "script.py", line 12, in mainlevel1()File "script.py", line 2, in level1level2()File "script.py", line 5, in level2level3()File "script.py", line 9, in level3result = x / y

(1) 使用 up 进入上一层函数 level3:

(Pdb) up
> File "script.py", line 5, in level2
level3()

(2) 查看 level3 的上下文代码:

(Pdb) l
4     def level2():
5 ->     level3()

(3) 使用 down 返回当前函数栈:

(Pdb) down
> File "script.py", line 9, in level3
result = x / y
  • bt 是调试调用栈的核心命令,可以快速分析程序运行路径,尤其适用于深层嵌套和异常场景。
  • 结合 up/down 和 l 可以更深入了解上下文和变量状态。
  • 使用这些工具,可以高效地调试 Python 程序,快速定位和修复问题!
   -   在指定的文件设置断点: b /dataset/private_data/dataset.py:509      #(在dataset.py 的第509行设置断点)-   b  # 显示所有断点-   n  # next-   c  # 跳到下一个断点-   s  # 进入函数-   r  # 执行代码直到从当前函数返回-   cl # 删除所有断点-   p  # 查看变量值-   q  # quit-   disable 7  # disable breakpoint 7-   enable 7   # enable breakpoint 7
http://www.lryc.cn/news/503752.html

相关文章:

  • 项目15:简易扫雷--- 《跟着小王学Python·新手》
  • Flink CDC实时同步mysql数据
  • 题解 - 自然数无序拆分
  • dfs_bool_void 两种写法感悟
  • MySQL 主从复制与 Binlog 深度解析
  • 大连理工大学《2024年845自动控制原理真题》 (完整版)
  • Java性能调优 - 多线程性能调优
  • 行为树详解(4)——节点参数配置化
  • 计算机网络中的三大交换技术详解与实现
  • 《杨辉三角》
  • ARM学习(35)单元测试框架以及MinGW GCC覆盖率报告
  • 边缘计算+人工智能:让设备更聪明的秘密
  • neo4j知识图谱AOPC的安装方法
  • 图像分割数据集植物图像叶片健康状态分割数据集labelme格式180张3类别
  • Python学习(二)—— 基础语法(上)
  • Cesium-(Primitive)-(CircleOutlineGeometry)
  • 计算机网络技术基础:2.计算机网络的组成
  • EasyExcel使用管道流连接InputStream和OutputStream
  • OpenWebUI连接不上Ollama模型,Ubuntu24.04
  • C#C++获取当前应用程序的安装目录和工作目录
  • Linux中vi和vim的区别详解
  • 2021 年 6 月青少年软编等考 C 语言四级真题解析
  • UE5编辑器下将RenderTarget输出为UTexture并保存
  • 【漏洞复现】CVE-2024-34102 Magento Open Source XXE漏洞
  • soul大数据面试题及参考答案
  • GLM-4-Plus初体验
  • 基于springboot+vue的高校校园交友交流平台设计和实现
  • Nacos 3.0 Alpha 发布,在安全、泛用、云原生更进一步
  • 【前端开发】HTML+CSS网页,可以拿来当作业(免费开源)
  • 【人工智能-中级】卷积神经网络(CNN)的中阶应用:从图像分类到目标检测