pdb
--- Python デバッガ¶
ソースコード: Lib/pdb.py
モジュール pdb
は Python プログラム用の対話型ソースコードデバッガを定義します。 (条件付き)ブレークポイントの設定やソース行レベルでのシングルステップ実行、スタックフレームのインスペクション、ソースコードリスティングおよびあらゆるスタックフレームのコンテキストにおける任意の Python コードの評価をサポートしています。事後解析デバッギングもサポートし、プログラムの制御下で呼び出すことができます。
デバッガーは拡張可能です -- 実際にはクラス Pdb
として定義されています。現在これについてのドキュメントはありませんが、ソースを読めば簡単に理解できます。拡張インターフェースはモジュール bdb
と cmd
を使っています。
参考
faulthandler
モジュールUsed to dump Python tracebacks explicitly, on a fault, after a timeout, or on a user signal.
traceback
モジュールStandard interface to extract, format and print stack traces of Python programs.
The typical usage to break into the debugger is to insert:
import pdb; pdb.set_trace()
Or:
breakpoint()
at the location you want to break into the debugger, and then run the program.
You can then step through the code following this statement, and continue
running without the debugger using the continue
command.
バージョン 3.7 で変更: The built-in breakpoint()
, when called with defaults, can be used
instead of import pdb; pdb.set_trace()
.
def double(x):
breakpoint()
return x * 2
val = 3
print(f"{val} * 2 is {double(val)}")
The debugger's prompt is (Pdb)
, which is the indicator that you are in debug mode:
> ...(2)double()
-> breakpoint()
(Pdb) p x
3
(Pdb) continue
3 * 2 is 6
バージョン 3.3 で変更: readline
モジュールによるコマンドおよびコマンド引数のタブ補完が利用できます。たとえば、p
コマンドの引数では現在のグローバルおよびローカル名が候補として表示されます。
You can also invoke pdb
from the command line to debug other scripts. For
example:
python -m pdb myscript.py
モジュールとして pdb を起動すると、デバッグ中のプログラムが異常終了したときに pdb が自動的に事後デバッグモードに入ります。事後デバッグ後 (またはプログラムの正常終了後)、pdb はプログラムを再起動します。自動再起動を行った場合、pdb の状態 (ブレークポイントなど) はそのまま維持されるので、たいていの場合、プログラム終了時にデバッガーも終了させるよりも便利なはずです。
バージョン 3.2 で変更: Added the -c
option to execute commands as if given
in a .pdbrc
file; see デバッガコマンド.
バージョン 3.7 で変更: Added the -m
option to execute modules similar to the way
python -m
does. As with a script, the debugger will pause execution just
before the first line of the module.
Typical usage to execute a statement under control of the debugger is:
>>> import pdb
>>> def f(x):
... print(1 / x)
>>> pdb.run("f(2)")
> <string>(1)<module>()
(Pdb) continue
0.5
>>>
クラッシュしたプログラムを調べるための典型的な使い方は以下のようになります:
>>> import pdb
>>> def f(x):
... print(1 / x)
...
>>> f(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
ZeroDivisionError: division by zero
>>> pdb.pm()
> <stdin>(2)f()
(Pdb) p x
0
(Pdb)
バージョン 3.13 で変更: The implementation of PEP 667 means that name assignments made via pdb
will immediately affect the active scope, even when running inside an
optimized scope.
このモジュールは以下の関数を定義しています。それぞれが少しづつ違った方法でデバッガに入ります:
- pdb.run(statement, globals=None, locals=None)¶
デバッガーに制御された状態で (文字列またはコードオブジェクトとして与えられた) statement を実行します。あらゆるコードが実行される前にデバッガープロンプトが現れます。ブレークポイントを設定し、
continue
とタイプできます。あるいは、文をstep
やnext
を使って一つづつ実行することができます (これらのコマンドはすべて下で説明します)。オプションの globals と locals 引数はコードを実行する環境を指定します。デフォルトでは、モジュール__main__
の辞書が使われます。(組み込み関数exec()
またはeval()
の説明を参照してください。)
- pdb.runeval(expression, globals=None, locals=None)¶
デバッガーに制御された状態で (文字列またはコードオブジェクトとして与えられる) expression を評価します。
runeval()
から復帰するとき、式の値を返します。その他の点では、この関数はrun()
と同様です。
- pdb.runcall(function, *args, **kwds)¶
function (関数またはメソッドオブジェクト、文字列ではありません) を与えられた引数とともに呼び出します。
runcall()
から復帰するとき、関数呼び出しが返したものはなんでも返します。関数に入るとすぐにデバッガプロンプトが現れます。
- pdb.set_trace(*, header=None, commands=None)¶
Enter the debugger at the calling stack frame. This is useful to hard-code a breakpoint at a given point in a program, even if the code is not otherwise being debugged (e.g. when an assertion fails). If given, header is printed to the console just before debugging begins. The commands argument, if given, is a list of commands to execute when the debugger starts.
バージョン 3.7 で変更: header キーワード専用引数。
バージョン 3.13 で変更:
set_trace()
will enter the debugger immediately, rather than on the next line of code to be executed.Added in version 3.14: The commands argument.
- pdb.post_mortem(traceback=None)¶
与えられた traceback オブジェクトの事後解析デバッギングに入ります。もし traceback が与えられなければ、その時点で取り扱っている例外のうちのひとつを使います。 (デフォルト動作をさせるには、例外を取り扱っている最中である必要があります。)
- pdb.pm()¶
Enter post-mortem debugging of the exception found in
sys.last_exc
.
run*
関数と set_trace()
は、 Pdb
クラスをインスタンス化して同名のメソッドを実行することのエイリアス関数です。それ以上の機能を利用したい場合は、インスタンス化を自分で行わなければなりません:
- class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True, mode=None)¶
Pdb
はデバッガクラスです。completekey, stdin, stdout 引数は、基底にある
cmd.Cmd
クラスに渡されます。そちらの解説を参照してください。skip 引数が指定された場合、 glob スタイルのモジュール名パターンの iterable (イテレート可能オブジェクト) でなければなりません。デバッガはこのパターンのどれかにマッチするモジュールに属するフレームにはステップインしません。 [1]
デフォルトでは、Pdb は
continue
コマンドが投入されると、(ユーザーがコンソールから Ctrl-C を押したときに送られる) SIGINT シグナル用ハンドラーを設定します。これにより Ctrl-C を押すことで再度デバッガーを起動することができます。Pdb に SIGINT ハンドラーを変更させたくない場合は nosigint を true に設定してください。readrc 引数はデフォルトでは真で、 Pdb が .pdbrc ファイルをファイルシステムから読み込むかどうかを制御します。
The mode argument specifies how the debugger was invoked. It impacts the workings of some debugger commands. Valid values are
'inline'
(used by the breakpoint() builtin),'cli'
(used by the command line invocation) orNone
(for backwards compatible behaviour, as before the mode argument was added).skip を使ってトレースする呼び出しの例:
import pdb; pdb.Pdb(skip=['django.*']).set_trace()
引数無しで 監査イベント
pdb.Pdb
を送出します。バージョン 3.1 で変更: skip パラメータが追加されました。
バージョン 3.2 で変更: Added the nosigint parameter. Previously, a SIGINT handler was never set by Pdb.
バージョン 3.6 で変更: readrc 引数。
Added in version 3.14: Added the mode argument.
デバッガコマンド¶
デバッガーに認識されるコマンドは以下に一覧されています。たいていのコマンドは以下のように 1、2 文字に省略できます。例えば h(elp)
は h
か help
がで help コマンドを呼び出すことを意味します (ただし he
, hel
, H
, Help
, HELP
は使用できません)。コマンドの引数はホワイトスペース (スペースかタブ) で区切ってください。コマンド構文として任意の引数は大括弧 ([]
) で括られています (実際に大括弧はタイプしないでください)。いくつかから選択できる引数は縦線 (|
) で分割されて記述されています。
空行を入力すると入力された直前のコマンドを繰り返します。例外: 直前のコマンドが list
コマンドならば、次の 11 行がリストされます。
デバッガが認識しないコマンドは Python 文とみなして、デバッグしているプログラムのコンテキストおいて実行されます。先頭にに感嘆符 (!
) を付けることで Python 文であると明示することもできます。これはデバッグ中のプログラムを調査する強力な方法です。変数を変更したり関数を呼び出したりすることも可能です。このような文で例外が発生した場合には例外名が出力されますが、デバッガの状態は変化しません。
バージョン 3.13 で変更: Expressions/Statements whose prefix is a pdb command are now correctly identified and executed.
デバッガーは エイリアス をサポートしています。エイリアスはデバッグ中のコンテキストに適用可能な一定レベルのパラメータを保持することができます。
Multiple commands may be entered on a single line, separated by ;;
. (A
single ;
is not used as it is the separator for multiple commands in a line
that is passed to the Python parser.) No intelligence is applied to separating
the commands; the input is split at the first ;;
pair, even if it is in the
middle of a quoted string. A workaround for strings with double semicolons
is to use implicit string concatenation ';'';'
or ";"";"
.
To set a temporary global variable, use a convenience variable. A convenience
variable is a variable whose name starts with $
. For example, $foo = 1
sets a global variable $foo
which you can use in the debugger session. The
convenience variables are cleared when the program resumes execution so it's
less likely to interfere with your program compared to using normal variables
like foo = 1
.
There are three preset convenience variables:
$_frame
: the current frame you are debugging$_retval
: the return value if the frame is returning$_exception
: the exception if the frame is raising an exception
Added in version 3.12: Added the convenience variable feature.
If a file .pdbrc
exists in the user's home directory or in the current
directory, it is read with 'utf-8'
encoding and executed as if it had been
typed at the debugger prompt, with the exception that empty lines and lines
starting with #
are ignored. This is particularly useful for aliases. If both
files exist, the one in the home directory is read first and aliases defined there
can be overridden by the local file.
バージョン 3.11 で変更: .pdbrc
is now read with 'utf-8'
encoding. Previously, it was read
with the system locale encoding.
- h(elp) [command]¶
引数を指定しない場合、利用できるコマンドの一覧が表示されます。引数として command が与えられた場合、そのコマンドのヘルプが表示されます。
help pdb
で完全なドキュメント (pdb
モジュールの doctring) が表示されます。command 引数は識別子でなければならないため、!
コマンドのヘルプを表示するにはhelp exec
と入力します。
- w(here) [count]¶
Print a stack trace, with the most recent frame at the bottom. if count is 0, print the current frame entry. If count is negative, print the least recent - count frames. If count is positive, print the most recent count frames. An arrow (
>
) indicates the current frame, which determines the context of most commands.バージョン 3.14 で変更: count argument is added.
- d(own) [count]¶
スタックフレーム内で現在のフレームを count レベル (デフォルトは 1) 新しいフレーム方向に移動します。
- u(p) [count]¶
スタックフレーム内で現在のフレームを count レベル (デフォルトは 1) 古いフレーム方向に移動します。
- b(reak) [([filename:]lineno | function) [, condition]]¶
With a lineno argument, set a break at line lineno in the current file. The line number may be prefixed with a filename and a colon, to specify a breakpoint in another file (possibly one that hasn't been loaded yet). The file is searched on
sys.path
. Acceptable forms of filename are/abspath/to/file.py
,relpath/file.py
,module
andpackage.module
.With a function argument, set a break at the first executable statement within that function. function can be any expression that evaluates to a function in the current namespace.
第二引数を指定する場合、その値は式で、その評価値が真でなければブレークポイントは有効になりません。
引数なしの場合は、それぞれのブレークポイントに対して、そのブレークポイントに行き当たった回数、現在の通過カウント ( ignore count ) と、もしあれば関連条件を含めてすべてのブレークポイントをリストします。
Each breakpoint is assigned a number to which all the other breakpoint commands refer.
- tbreak [([filename:]lineno | function) [, condition]]¶
一時的なブレークポイントで、最初にそこに達したときに自動的に取り除かれます。引数は
break
と同じです。
- cl(ear) [filename:lineno | bpnumber ...]¶
filename:lineno 引数を与えると、その行にある全てのブレークポイントを解除します。スペースで区切られたブレークポイントナンバーのリストを与えると、それらのブレークポイントを解除します。引数なしの場合は、すべてのブレークポイントを解除します ( が、はじめに確認します ) 。
- disable bpnumber [bpnumber ...]¶
ブレークポイント番号 bpnumber のブレークポイントを無効にします。ブレークポイントを無効にすると、プログラムの実行を止めることができなくなりますが、ブレークポイントの解除と違いブレークポイントのリストに残っており、(再び) 有効にできます。
- enable bpnumber [bpnumber ...]¶
指定したブレークポイントを有効にします。
- ignore bpnumber [count]¶
与えられたブレークポイントナンバーに通過カウントを設定します。count が省略されると、通過カウントは 0 に設定されます。通過カウントがゼロになったとき、ブレークポイントが機能する状態になります。ゼロでないときは、そのブレークポイントが無効にされず、どんな関連条件も真に評価されていて、ブレークポイントに来るたびに count が減らされます。
- condition bpnumber [condition]¶
ブレークポイントに新しい condition を設定します。condition はブレークポイントを制御する条件式で、この式が真を返す場合のみブレークポイントが有効になります。condition を指定しないと既存の条件が除去されます; ブレークポイントは常に有効になります。
- commands [bpnumber]¶
ブレークポイントナンバー bpnumber にコマンドのリストを指定します。コマンドそのものはその後の行に続けます。
end
だけからなる行を入力することでコマンド群の終わりを示します。例を挙げます:(Pdb) commands 1 (com) p some_variable (com) end (Pdb)
ブレークポイントからコマンドを取り除くには、
commands
のあとにend
だけを続けます。つまり、コマンドを一つも指定しないようにします。bpnumber 引数を指定しない場合、
commands
は最後にセットしたブレークポイントを参照します。ブレークポイントコマンドはプログラムを走らせ直すのに使えます。単に
continue
コマンドやstep
、その他実行を再開するコマンドを使えば良いのです。Specifying any command resuming execution (currently
continue
,step
,next
,return
,until
,jump
,quit
and their abbreviations) terminates the command list (as if that command was immediately followed by end). This is because any time you resume execution (even with a simple next or step), you may encounter another breakpoint—which could have its own command list, leading to ambiguities about which list to execute.If the list of commands contains the
silent
command, or a command that resumes execution, then the breakpoint message containing information about the frame is not displayed.バージョン 3.14 で変更: Frame information will not be displayed if a command that resumes execution is present in the command list.
- s(tep)¶
現在の行を実行し、最初に実行可能なものがあらわれたときに (呼び出された関数の中か、現在の関数の次の行で) 停止します。
- n(ext)¶
現在の関数の次の行に達するか、あるいは関数が返るまで実行を継続します。 (
next
とstep
の差はstep
が呼び出された関数の内部で停止するのに対し、next
は呼び出された関数を (ほぼ) 全速力で実行し、現在の関数内の次の行で停止するだけです。)
- unt(il) [lineno]¶
引数なしだと、現在の行から 1 行先まで実行します。
lineno を指定すると、番号が lineno 以上である行に到達するまで実行します。どちらにしても現在のフレームが返ってきた時点で停止します。
バージョン 3.2 で変更: 明示的に行数指定ができるようになりました。
- r(eturn)¶
現在の関数が返るまで実行を継続します。
- c(ont(inue))¶
ブレークポイントに出会うまで、実行を継続します。
- j(ump) lineno¶
次に実行する行を指定します。最も底のフレーム中でのみ実行可能です。前に戻って実行したり、不要な部分をスキップして先の処理を実行する場合に使用します。
ジャンプには制限があり、例えば
for
ループの中には飛び込めませんし、finally
節の外にも飛ぶ事ができません。
- l(ist) [first[, last]]¶
現在のファイルのソースコードを表示します。引数を指定しないと、現在の行の前後 11 行分を表示するか、直前の表示を続行します。引数に
.
を指定すると、現在の行の前後 11 行分を表示します。数値を 1 個指定すると、その行番号の前後 11 行分を表示します。数値を 2 個指定すると、開始行と最終行として表示します; 2 個めの引数が 1 個め未満だった場合、1 個目を開始行、2 個めを開始行からの行数とみなします。現在のフレーム内の現在の行は
->
で表示されます。例外をデバッグ中の場合、例外が発生または伝搬した行は、それが現在の行とは異なるとき>>
で表示されます。バージョン 3.2 で変更:
>>
マーカーが追加されました。
- a(rgs)¶
Print the arguments of the current function and their current values.
- p expression¶
現在のコンテキストにおいて expression を評価し、その値をプリントします。
注釈
print()
も使えますが、これはデバッガーコマンドではありません --- これは Python の関数print()
が実行されます。
- whatis expression¶
expression の型を表示します。
- source expression¶
expression のソースコードの取得を試み、可能であれば表示します。
Added in version 3.2.
- display [expression]¶
expression の値が変更されていれば表示します。毎回実行は現在のフレームで停止します。
expression を指定しない場合、現在のフレームのすべての式を表示します。
注釈
Display evaluates expression and compares to the result of the previous evaluation of expression, so when the result is mutable, display may not be able to pick up the changes.
以下はプログラム例です:
lst = [] breakpoint() pass lst.append(1) print(lst)
Display won't realize
lst
has been changed because the result of evaluation is modified in place bylst.append(1)
before being compared:> example.py(3)<module>() -> pass (Pdb) display lst display lst: [] (Pdb) n > example.py(4)<module>() -> lst.append(1) (Pdb) n > example.py(5)<module>() -> print(lst) (Pdb)
You can do some tricks with copy mechanism to make it work:
> example.py(3)<module>() -> pass (Pdb) display lst[:] display lst[:]: [] (Pdb) n > example.py(4)<module>() -> lst.append(1) (Pdb) n > example.py(5)<module>() -> print(lst) display lst[:]: [1] [old: []] (Pdb)
Added in version 3.2.
- undisplay [expression]¶
現在のフレーム内で expression をこれ以上表示しないようにします。expression を指定しない場合、現在のフレームで display 指定されている式を全てクリアします。
Added in version 3.2.
- interact¶
Start an interactive interpreter (using the
code
module) in a new global namespace initialised from the local and global namespaces for the current scope. Useexit()
orquit()
to exit the interpreter and return to the debugger.注釈
As
interact
creates a new dedicated namespace for code execution, assignments to variables will not affect the original namespaces. However, modifications to any referenced mutable objects will be reflected in the original namespaces as usual.Added in version 3.2.
バージョン 3.13 で変更:
exit()
andquit()
can be used to exit theinteract
command.バージョン 3.13 で変更:
interact
directs its output to the debugger's output channel rather thansys.stderr
.
- alias [name [command]]¶
Create an alias called name that executes command. The command must not be enclosed in quotes. Replaceable parameters can be indicated by
%1
,%2
, ... and%9
, while%*
is replaced by all the parameters. If command is omitted, the current alias for name is shown. If no arguments are given, all aliases are listed.エイリアスは入れ子になってもよく、pdb プロンプトで合法的にタイプできるどんなものでも含めることができます。内部 pdb コマンドをエイリアスによって上書きすることが できます。そのとき、このようなコマンドはエイリアスが取り除かれるまで隠されます。エイリアス化はコマンド行の最初の語へ再帰的に適用されます。行の他のすべての語はそのままです。
例として、二つの便利なエイリアスがあります (特に
.pdbrc
ファイルに置かれたときに):# Print instance variables (usage "pi classInst") alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}") # Print instance variables in self alias ps pi self
- unalias name¶
指定したエイリアス name を削除します。
- ! statement¶
Execute the (one-line) statement in the context of the current stack frame. The exclamation point can be omitted unless the first word of the statement resembles a debugger command, e.g.:
(Pdb) ! n=42 (Pdb)
To set a global variable, you can prefix the assignment command with a
global
statement on the same line, e.g.:(Pdb) global list_options; list_options = ['-l'] (Pdb)
- run [args ...]¶
- restart [args ...]¶
デバッグ中の Python プログラムを再実行します。args が与えられると、
shlex
で分割され、結果が新しいsys.argv
として使われます。ヒストリー、ブレークポイント、アクション、そして、デバッガーオプションは引き継がれます。restart
はrun
の別名です。
- q(uit)¶
デバッガーを終了します。実行しているプログラムは中断されます。
- debug code¶
Enter a recursive debugger that steps through code (which is an arbitrary expression or statement to be executed in the current environment).
- retval¶
Print the return value for the last return of the current function.
- exceptions [excnumber]¶
List or jump between chained exceptions.
When using
pdb.pm()
orPdb.post_mortem(...)
with a chained exception instead of a traceback, it allows the user to move between the chained exceptions usingexceptions
command to list exceptions, andexception <number>
to switch to that exception.以下はプログラム例です:
def out(): try: middle() except Exception as e: raise ValueError("reraise middle() error") from e def middle(): try: return inner(0) except Exception as e: raise ValueError("Middle fail") def inner(x): 1 / x out()
calling
pdb.pm()
will allow to move between exceptions:> example.py(5)out() -> raise ValueError("reraise middle() error") from e (Pdb) exceptions 0 ZeroDivisionError('division by zero') 1 ValueError('Middle fail') > 2 ValueError('reraise middle() error') (Pdb) exceptions 0 > example.py(16)inner() -> 1 / x (Pdb) up > example.py(10)middle() -> return inner(0)
Added in version 3.13.
脚注