私はCからPythonに書き直したモジュールをテストしていて、私のキャリアで見た奇妙なバグの1つを持っています。テストを伴う問題のあるPythonコードは、わずか3行です。
# MATCHERS is a list of compiled regular expression objects defined as a
# global in the top level of the module
print dir(MATCHERS[0])
# diff.Differ is a class implemented in C with thed Python API; zoneA/B Words are
# lists and CompareLines, isJunk, and SetStaticLine are functions
differ = diff.Differ(zoneAWords, zoneBWords, CompareLines, isJunk, SetStaticLine)
# Causes a TypeError
dir(MATCHERS[0])
これらの3行は、次の出力を生成します。
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'findall', 'finditer', 'flags', 'groupindex', 'groups', 'match', 'pattern', 'scanner', 'search', 'split', 'sub', 'subn']
Traceback (most recent call last):
File "Diff.py", line 1032, in <module>
main()
File "Diff.py", line 1019, in main
diffs = CompareFiles(sys.argv[1], sys.argv[2])
File "Diff.py", line 584, in CompareFiles
print dir(MATCHERS[0])
TypeError: eqTest must be a function
コンパイルされた正規表現オブジェクトのdir()を出力すると、Cで記述されたオブジェクトが作成される前は正常に機能しますが、後でdir()を取得するだけでTypeErrorが発生します。私の知る限り、dir()がTypeErrorを引き起こす方法はありません。TypeErrorとそれに関連するメッセージは、オブジェクトのeqTestフィールド用にカスタマイズされたセッター関数の一部としての私のコードからのものですが、dir()の呼び出しは、もちろん、eqTestを何かに設定しようとはしません。前の行ですでに正常に設定されています。
これはすべて、Cコードで何かがうまくいかず、そのような奇妙な動作を引き起こしたと私に信じさせます。私の現在の仮説はバッファオーバーフローです。配列の境界を超えて書き込むと、これらのエラーの原因となっている何かが変更されました。(MATCHERS [0]に文字列を一致させるように要求すると、エラーメッセージなしでPythonがクラッシュします)私はしばらくの間初期化コードを調べていて、これを引き起こしている可能性のあるものが他にあるかどうかを確認しようと思っていました。
私のコードは長すぎてここに含めることができず、ここのPastebinにあります; 434行目以降はまだ実行されていないため、すべて無視できます。