简易版 pdb watchpoint

本文最后更新于 2025年9月23日

在开发大型项目的时候,经常会出现某个变量不知道在哪里就被莫名其妙更改的情况。

以vLLM(ac0048c0a)为例,FusedMoEfoward_native开头有一段神秘的padding代码

1
2
3
4
5
6
7
og_hidden_states = hidden_states.shape[-1]
if self.hidden_size != og_hidden_states:
# runtime behavior: 3072 != 2880
hidden_states = F.pad(hidden_states,
(0, self.hidden_size - og_hidden_states),
mode='constant',
value=0.0)
但是FusedMoE初始化的时候,self.hidden_size = 2880,所以我们需要debug工具追踪self.hidden_size到底是在哪里被改了。

vLLM的多进程使得直接使用pdb debug很困难,并且pdb似乎没有简单直接的类似gdb watchpoint一样的功能。

一个简单的办法是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import traceback

class MyClass:
def __init__(self):
self._value = None

@property
def value(self):
return self._value

@value.setter
def value(self, new_value):
print(f"{self._value} -> {new_value}")
traceback.print_stack() # or import pdb; pdb.set_trace()
self._value = new_value

a = MyClass()
a.value = 10

当然,如果想要更优雅一点还可以使用装饰器。