Python標準添付のデバッガ「pdb」の簡単な紹介

2004年にはすでに標準ライブラリに入っていたのに「スクリプト言語でもステップ実行とかできたらいいのにね」とか言われちゃう不憫なpdbについて軽く解説。pdb不憫な子!

まず適当にスクリプトを書きます。

~$ cat t.py
for i in range(10):
    sum += i

print sum

実行するとエラーになります。

~$ python t.py
Traceback (most recent call last):
  File "t.py", line 2, in <module>
    sum += i
TypeError: unsupported operand type(s) for +=: 'builtin_function_or_method' and 'int'

ワー、なんでエラーになったんだろー(棒読み)

そこでおもむろに-m pdbをつけてステップ実行します。

~$ python -m pdb t.py
> /Users/nishio/t.py(1)<module>()
-> for i in range(10):
(Pdb) 

この(Pdb)ってのはプロンプトです。gdbと同じようにnでステップ実行したりbでブレークポイントを設定したりできます。ついでにPythonスクリプトが対話的に実行できます。(pdb の使い方 -- コマンド編参照)

(Pdb) 2 * 3
6
(Pdb) n
> /Users/nishio/t.py(2)<module>()
-> sum += i
(Pdb) p i
0

例外が飛ぶとこうなります。sum += iでエラーになっているんでp sumで値を確認してみましょう。あー、これ組み込みの関数sumになってるんだーまちがえたー(棒読み)

(Pdb) n
TypeError: "unsupported operand type(s) for +=: 'builtin_function_or_method' and 'int'"
> /Users/nishio/t.py(2)<module>()
-> sum += i
(Pdb) p sum
<built-in function sum>

ここでcontすると「post mortem debugging」(検死解剖モード)に入ってスクリプト冒頭から実行し直すので…(ここ識者のツッコミが入るかも)

(Pdb) cont
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/pdb.py", line 1285, in main
    pdb._runscript(mainpyfile)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/pdb.py", line 1204, in _runscript
    self.run(statement)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/bdb.py", line 368, in run
    exec cmd in globals, locals
  File "<string>", line 1, in <module>
  File "t.py", line 2, in <module>
    sum += i
TypeError: unsupported operand type(s) for +=: 'builtin_function_or_method' and 'int'
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /Users/nishio/t.py(2)<module>()
-> sum += i
(Pdb) s
Post mortem debugger finished. The t.py will be restarted

さきほどは初期化を忘れていたsumを、0に初期化して実行し直してみましょう。はい、正しく実行されて期待していた結果(45)が出力されました。めでたしめでたし。

> /Users/nishio/t.py(1)<module>()
-> for i in range(10):
(Pdb) sum = 0
(Pdb) cont
45
The program finished and will be restarted

と軽く紹介しましたが、個人的にはよくテストされた小さいコンポーネントを作ってボトムアップに積み上げていくことが多いのであんまりpdbを使い慣れていなかったりします。