Cython プログラムのデバッグ

Cython には、 Cython で書いたコードをユーザがデバッグできるよう、GNU デバッガ用の拡張があります。この機能を使うには、 Python サポート (Python 2.5 以降にリンクされたもの) を有効にした、バージョン 7.2 以降 の GDB をインストールする必要があります。 Python 3 の場合は、コードを Python 3 向けにビルドして、デバッガは Python 2 で (すくなくとも、 Python 2 向けにインストールした Cython を使える環境で) 実行せねばなり ません。

デバッガは、 Cython コンパイラのエクスポートするデバッグ情報を必要とし ます。デバッグ情報を有効にするには、 Cython の Extension クラスに pyrex_gdb=True を渡して setup します:

from Cython.Distutils import extension

ext = extension.Extension('source', 'source.pyx', pyrex_gdb=True)
setup(..., ext_modules=[ext)]

これで、デバッグ情報が指定モジュールの単位で有効になります。 もう一つの (簡単な) 方法は、コマンドライン引数に --pyrex-gdb フラ グを指定するというものです:

python setup.py build_ext --pyrex-gdb

開発時には、ビルド結果を build ディレクトリ下ではなく、現在の場所に 「置き換えで」出力する --inplace フラグも使うと便利です。

Cython をコマンドラインから直接起動する際は、 --gdb フラグを使うと、 デバッグ情報を書き出せます:

cython --gdb myfile.pyx

デバッガを起動する

Cython デバッガを実行して、Cython の出力したデバッグ情報を import する には、ビルドディレクトリ下で cygdb を実行します:

$ python setup.py build_ext --pyrex-gdb --inplace
$ cygdb
GNU gdb (GDB) 7.2
...
(gdb)

Cython デバッガを使う際は、デバッグシンボル付きでコンパイルしたインタ プリタ (--with-pydebug で configure したか、 -g CFLAG 付きでコ ンパイルしたもの) でビルド・実行を行うのが望ましいです。 Python がすで にインストールされていて、パッケージマネージャの管理下にある場合には、 デバッグサポートを別にインストールする必要があるでしょう。例えば、 Ubuntu では以下のようにします:

$ sudo apt-get install python-dbg
$ python-dbg setup.py build_ext --pyrex-gdb --inplace

この場合には python-dbg でスクリプトを実行する必要があります。

gdb に引数を渡すときには、下記の順番で指定します:

$ cygdb /path/to/build/directory/ GDBARGS

すなわち:

$ cygdb . --args python-dbg mainscript.py

のようにします。

cygdb にデバッグ情報を import させないときには、 -- を最初の引数に 指定します:

$ cygdb --

デバッガを使う

Cython デバッガは、ブレークポイントの設定、スタックのインスペクション、 ソースコードリストの表示、ステップ実行、ステップオーバーといったコマン ドをサポートしています。これらのコマンドは、ほとんどが同名の gdb コマ ンドに類似しています。

cy break breakpoints...

Python, Cython, または C の関数中にブレークポイントを設定します。 指定した名前の Cython の関数から探しはじめ、 cygdb がその名前の関 数 (またはメソッド) を見つけられなければ、 (未解決の) C のブレーク ポイントを設定します。 -p オプションを使うと、 Python のブレー クポイントを設定します。

ブレークポイントは、関数やメソッド名の他に、「完全指定 (fully qualified)」、すなわち関数の完全な “path” でも設定できます:

(gdb) cy break cython_function_or_method
(gdb) cy break packagename.modulename.cythonfunction
(gdb) cy break packagename.modulename.ClassName.cythonmethod
(gdb) cy break c_function

また、Cython コードの行番号も指定できます:

(gdb) cy break packagename.modulename:14
(gdb) cy break :14

Python のブレークポイントは、今のところ、モジュールの名前 (パッケー ジパス全体ではありません) と、関数やメソッドの名前による指定をサポー トしています:

(gdb) cy break -p pythonmodule.python_function_or_method
(gdb) cy break -p python_function_or_method

Note

Python のブレークポイントは、デバッガが Python のフレーム 情報を取得できる場合にのみ使えます。それには、 Python をデバッ グビルドするか、デバッグサポートつきでコンパイルし、 strip せずに使う必要があります。

cy step

Python や Cython, C コードをステップ実行します。Cython のコードか ら Python, Cython, C の関数を直接呼び出すと、ステップ実行に関係が あるとみなされ、ステップインします。

cy next

Python, Cython, C code をステップオーバーします。

cy run

プログラムを実行します。デフォルトのインタプリタは、拡張モジュール をビルドするのに使ったものです。ただし、 「デバッグ情報を import しない」オプションが有効な状態では、 cygdb を実行しているインタプリタを使います。 インタプリタは gdb の file コマンドでオーバライドできます。

cy cont

プログラムをコンティニューします。

cy up
cy down

スタック中の関連するとみなされるフレームを上下に移動します。

cy finish

上の関連フレームに到達するか、何らかの理由で実行停止が起きるまでプ ログラムを実行します。

cy bt
cy backtrace

関連するとみなされるフレーム全体にわたるトレースバックを出力します。 -a オプションがついている場合、 (全ての C フレームを含む) 完全 なトレースバックを出力します。

cy select

cy backtrace の出力するリストの番号を使ってスタックフレームを 選択します。このコマンドが存在するのは、 cy backtrace がスタッ クを逆順に出力するので、 gdb の bt と違うフレーム番号が出てし まうからです。

cy print varname

Cython, Python, C の、ローカルまたはグローバルの変数値を出力します (どちらが出力されるかは、コンテキストに依存します)。変数は参照渡し でも指定できます:

(gdb) cy print x
x = 1
(gdb) cy print *x
*x = (PyObject) {
    _ob_next = 0x93efd8,
    _ob_prev = 0x93ef88,
    ob_refcnt = 65,
    ob_type = 0x83a3e0
}
cy set cython_variable = value

Cython のスタック上の Cython の変数の値をセットします。

cy list

現在の行の周辺のソースコードをリスト表示します。

cy locals
cy globals

全てのローカルおよびグローバル変数と、その値を出力します。

cy import FILE...

デバッグ情報を引数に指定したファイルから import します。デバッグ情 報の import には、 cygdb コマンドラインツールを使うほうが楽です。

cy exec code

現在の Python または Cython フレーム上でコードを実行します。 Python のインタラクティブインタプリタのように動作します。

Python の実行フレーム上では、Python フレームの globals および locals を使います。Cython のフレーム上では、 Cython モジュールの globals 辞書と、ローカルの Cython 変数の入った新しい辞書を使います。

Note

cy exec は、デバッグ対象の中で状態の変更やコードの実行を 行うので、プログラムのクラッシュやデータ破損の危険があります。

実行例:

(gdb) cy exec x + 1
2
(gdb) cy exec import sys; print sys.version_info
(2, 6, 5, 'final', 0)
(gdb) cy exec
>global foo
>
>foo = 'something'
>end

コンビニエンス関数

以下の関数は gdb 関数で、gdb の式の中で使えます。

cy_cname(varname)

Cython コード中の変数に対する C の変数名を返します。グローバル変数 の場合、実際には有効でない値のことがあります。

cy_cvalue(varname)

Cython コード中の変数の値を返します。

cy_eval(expression)

Python コードを最近傍の Python または Cython フレームで評価して、 結果を gdb の値として返します。実行に成功した場合には新しい参照を 返し、エラーのときは NULL を返します。

cy_lineno()

選択中の Cython フレームにおける現在の行番号を返します。

実行例:

(gdb) print $cy_cname("x")
$1 = "__pyx_v_x"
(gdb) watch $cy_cvalue("x")
Hardware watchpoint 13: $cy_cvalue("x")
(gdb) cy set my_cython_variable = $cy_eval("{'spam': 'ham'}")
(gdb) print $cy_lineno()
$2 = 12

デバッガの構成

デバッガの動作は、gdb パラメタを使って構成できます。例えば、コードの色 付け表示や端末の背景色、ブレークポイント名の自動補完といった機能を構成 可能です。

cy_complete_unqualified

Cython デバッガに、 cy break が、関数名だけに対しても補完を行 うかどうかを指示します。例えば、モジュール M に入っている spam という名前の関数があるときに、 M.spam だけを補完す るのか、 spam も補完するのかを決めます。

デフォルトの値は true です。

cy_colorize_code

ソースコードを色付け表示するかどうかを指示します。デフォルト値は true です。

cy_terminal_background_color

デバッガに端末の背景色を教えます。背景色は、ソースコードの色付けに 影響します。デフォルト値は “dark” です。他には “light” があります。

パラメタは、以下のように使います:

(gdb) set cy_complete_unqualified off
(gdb) set cy_terminal_background_color light
(gdb) show cy_colorize_code

Table Of Contents

Previous topic

並列化

Next topic

リファレンスガイド

This Page