2010年4月13日火曜日

ひさしぶりにはまった…。

コーダーならば、たった一文字の違い == が = になっていた…という類の超くだらないバグに丸1日を費した経験があると思います。PHP Extension の記事を書いていて、SegFault で落ちる不可解なバグに昨日の晩から悩まされました。
手がかりは
PHP Warning:  Function registration failed - duplicate name - __construct

まぁ、冷静に考えてみよう。ダブル・アンダースコアやアンダースコアから始まる名前は使ってはいけなかったのだ。そんな事は百も承知だった。参考にしたURLのコードが、このような関数名を使っており、一個目に作成した PHP Extension がこれで、動いてしまったもんだから、これが流儀だと思い込んでしまったのだ。関数名がバッティングしていて、PHP_METHOD の定義がへたれなんだろうと思って調べてみたけど
#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))

と、ちゃんと処理してるっぽい感じです。ともかく、コンストラクタの名前を正規の名前に変更したら、動作するようになりました。PHP Extension を書くにあたって、ありきたりのクラス名と、ありきたりのメンバ関数名の組み合わせは、御法度なのかもしれません。

追記:コンストラクタがコールできへんやんけーわりゃーーーーなめとんのかーーー
追記:現在進行形 nm コマンドで、関数エントリを調べてみたが、マクロの意図通りの関数名に展開されていた。これは、まったく違うところではまっているに違いない…。
追記:gdb で調べてみたが、登録処理でまともに成功しなかったため、モジュール・アンロード時の処理でSegFaultしていた。ちゃんと登録処理のところを重点的にステップ実行しないとダメそうだ。本腰を入れてgdbの勉強もしないとダメだこりゃ…。
追記 2012/01/09: 引数ありのコンストラクタと引数無しのコンストラクタで関数名が異なるのが原因だと推察しているが、放置プレー。Cベースで記述されていると、こういう問題にぶち当たる。

0 件のコメント: