2011-12-22

バグの原因究明

Sagittariusにはドキュメント化されていないライブラリが結構ある。理由はさまざまで、APIが固定されていないとか、近い将来変更になるのでその後とか、バグが取れてないとか、まぁいろいろだ。
その中の「バグが取れていない」の代表格暗号化ライブラリでどこに不具合があるのかがようやく分かった。
結論を言えば、メモリ割り当ての際にオーバーラップして割り当てているせいで、メモリ破壊を起こしているというものだ。
原因はおそらく2つに分けられるだろうが、1つはBoehmGCがマークミスを起こしている。これは回避しようがないので、あきらめるしかない。もう一つは何らかの理由により、割り当てたメモリが使われていないという状態になり、GCによって回収されている(一緒くさいな・・・)。とりあえず前者っぽい挙動をしている。なぜだ?

今回はどうやって直すかというのではなく、どうやって探したかをメモしておく。場所を特定するのに非常に面倒なバグだったので。

起きた環境:
  • VCでコンパイルしたバイナリ
  • 自宅ノートPCのCygwinでコンパイルしたバイナリ
職場のPCでは起きないという隠密バグ(職場もCygwin)。BoehmGCのコンパイル時フラグかな?
使用したツール:
  • WinDbg
  • GDB
NMakeを使っているので、VC++ Expressではデバッグできなかった(評価版なのでプロセスアタッチできない)。
デバッグ方法:
WinDbgでウォッチ式を指定。地道に起きるまでステップ実行(涙)。WinDbgではウォッチ式をしていしても、人の目で監視しないとだめだった。面倒すぎ。
ある程度特定したのちに、自宅PCのGDBでデバッグ。何が壊れているのか分かっているので、ブレークポイントでその値が設定される場所で停めて、アドレスを確認。以下のコマンドを打つ。

watch *0x{上記で調べたアドレス}
最初、丁寧にキャストして実行したらGDBが終わらなかった。キャストせずに上記のように打つとハードウェアウォッチポイントになるらしく、実行がすごく速かった。っで、たどり着いた先はBoehmGCのmalloc。。。どうしろと?
さて、解決方法でも考えるか・・・

No comments:

Post a Comment