PDB Introduction

PDB Introduction

对于 Python 等宽松的动态类型语言来说,其面对日益膨胀的代码库会变得非常难以维护,因此,有必要使用 Python 原生支持的 pdb debugger 工具来代替 print 大法,实现更加精准并且高效的 Debugging.

Official Docs: pdb official docs

How to set a breakpoint

1
import pdb; pdb.set_trace()

or

1
2
breakpoint()
# i recommend this!

After setting a breakpoint

在设置断点成功后,程序进入阻塞状态,等待用户命令行的输入:

help

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Documented commands (type help <topic>):
========================================
EOF cl disable ignore n return u where
a clear display interact next retval unalias
alias commands down j p run undisplay
args condition enable jump pp rv unt
b cont exceptions l q s until
break continue exit list quit source up
bt d h ll r step w
c debug help longlist restart tbreak whatis

Miscellaneous help topics:
==========================
exec pdb

控制流跳转操作

  • next:跳转到下一行但是不进入函数内部
  • step:进入函数执行
  • continue:跳转到下一个断点
  • until: 跳出循环

查看关键信息

  • where: 打印完整的函数调用链
  • list: 展示源代码的上下文
  • print: 打印变量的值
  • whatis: 打印变量名的类型
  • pp:美化打印

一些组合技:

  • pp locals(): 打印全部的局部变量
  • pp globals(): 打印全部的全局变量
  • pp {**globals(), **locals()}
  • pp dirs(): 打印全部的变量 (一个包含所有局部变量变量名的列表)
  • pp vars(obj_name): 查看对象的属性字典
  • pp dir(obj_name): 查看对象支持的所有方法和属性

interact

开启一个临时的 Python Session,进行交互式 Python 输入。

pdb 的原理

Creating my own debugger!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import sys
from typing import Any
from types import FrameType


def mini_debugger(frame: FrameType, event: str, arg: Any):
print("\n")
print("=" * 20)

if event == "call":
print("Current Event is calling")

elif event == "line":
print("Executing Current Lines")

elif event == "return":
print("The function is returning")

elif event == "exception":
print("Oh! Exception caught")

print(f"Current Code: {frame.f_code}")
print(f"Current Line: {frame.f_lineno}")
print(f"Local variables: {frame.f_locals}")
print(f"Global variables: {frame.f_globals}")
print(f"Reference to the last frame: {frame.f_back}")

print("=" * 20)
print("\n")

return mini_debugger


sys.settrace(mini_debugger)


def test_logic():
x = 10
y = 20
z = x + y
return z


z = test_logic()
sys.settrace(None)

简单来说,pdb 本质上是一个利用 Python 运行机制来监控自身的 Python 程序。Python 解释器提供了一个名为 sys.settrace() 的函数。pdb 启动过程中会调用该函数并注册一个 Trace Function, 这个 Trace Function 通常会接受 frame: FrameType, event: str, arg: Any 三个参数作为输入值:

  • frame:
    1
    2
    3
    4
    5
    print(f"Current Code: {frame.f_code}")
    print(f"Current Line: {frame.f_lineno}")
    print(f"Local variables: {frame.f_locals}")
    print(f"Global variables: {frame.f_globals}")
    print(f"Reference to the last frame: {frame.f_back}")
  • event:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if event == "call":
    print("Current Event is calling")

    elif event == "line":
    print("Executing Current Lines")

    elif event == "return":
    print("The function is returning")

    elif event == "exception":
    print("Oh! Exception caught")
  • arg:
    • 一些附加的数据

上文实现了一个非常简单的 mini_debugger,这个 debugger 不会处理用户 IO,而是直接在每一行调用时输出一些辅助信息(例如运行代码行数、运行栈帧等等)。而 pdb 的冻结功能可以实现当运行到断点时自动触发跟踪函数,启动用户输入的 while 循环,并在特定命令输入下返回特定的调试信息。


PDB Introduction
https://xiyuanyang-code.github.io/posts/PDB-Introduction/
Author
Xiyuan Yang
Posted on
February 27, 2026
Updated on
February 27, 2026
Licensed under