読者です 読者をやめる 読者になる 読者になる

なんかよく分からない error

OS X で FTDI 社製の USB chip FT245RL を制御しています。Python から ftd2xx という module を経由して、FTDI の配布する libftd2xx を使っているのですが、次のような error で死にました。

2010-05-11 19:06:01.745 Python[20974:2303] In '__CFRunLoopLock', file /SourceCache/CF/CF-550.19/RunLoop.subproj/CFRunLoop.c, line 438, during lock, spin lock 0x1006d3099 has value 0x8b4cf075, which is neither locked nor unlocked.  The memory has been smashed.

 *** Break *** bus error

 *** Break *** segmentation violation

 *** Break *** segmentation violation

Python script の該当する箇所は次の通り。usb.usb としている部分は、ftd2xx から open した USB device です。

for i in range(100):
    usb.usb.write('\xd6\x11@\x90\x00@\x90\x00@\xbf&`')
    print len(usb.usb.read(3*3278))

ほぼ同じなんですが、次のように書き換えるとちゃんと動作しました。

for i in range(100):
    usb.usb.write('\xd6\x11@\x90\x00@\x90\x00@\xbf&`')
    l = len(usb.usb.read(3*3278))
    print l

こことかここに似たような報告がありますが、どうやら、for 文で回すうちに buffer overflow 的な何かが起きているようです。原因は何だかよく分かりませんが、一応回避できたということで。

ただし、↓こういう script だと、当然だけど何も起きずにちゃんと動作します。USB device への access が絡んだ場合に発生する問題のようです。

s = "0"*9834

for i in range(100):
    print len(s)

=== 追記 (2010.6.26) ===
ROOT と C++ の環境で Python を経由せずに直接 libftd2xx を使用しても、同様の問題が発生しました。FTDI に問い合わせましたが、返事はありません。恐らく Snow Leopard 環境で発生する libftd2xx の潜在的な bug です。ROOT のように thread を使うものと衝突しているように見えますが、詳細は謎。__CFRunLoopLock という関数は、CoreFoundation 独自の semaphore 的な物のようです。