Privileged instruction 3

phobosデバッグ用にコンパイルして、例外をログファイルに落とすようにしていたおかげで大体内容が分かった。


while ((e = *pe) != null)
{ int c;

//printf("\te = %p, e.left = %p, e.right = %p\n", e, e.left, e.right);
assert(e.left != e);
assert(e.right != e);
c = key_hash - e.hash;
if (c == 0)
c = keyti.compare(olde + 1, e + 1);
if (c < 0)
pe = &e.left;
else if (c > 0)
pe = &e.right;
else
assert(0);
}


このassert(0)がなぜ起こるのか・・・。
ぱっと見この部分は、キーのハッシュ値を先に比べて、同じならデータを比較して、大小を判断しているところなんだけど、連想配列の仕組み上、ハッシュ値も同じでデータも同じ要素が含まれるわけがないというassert(0)に見えるが、要素がクラス(=ポインタ)なので、setするときからキーが変更されている可能性があって、いつの間にか同じキーが含まれてしまったということか。

・・・たしかに、ありそう・・。

そこらへんをチェックしてみるか。

  • 追記

早とちりか。
見直したら、キーは構造体で作ってから書き換えないので、値が変わるはずないんだが・・。
valuesがコピーでないので触ったらまずいとか?
んんん、いろいろ試してみなければ・・・。

  • 追記

長い間起動していると、いろいろとバグってくる気がする。


char[] toString()
{
return format("CommandCode(%d) Length(%d)\n", cast(ubyte)commandCode, length);
}

このformat()の中で落ちたりもする。
基本的に落ちないが、長い間起動しておくとごくまれにこの中で落ちる。
commandCode、lengthというメソッドにアクセスしたタイミングならまだ分かるが、formatの奥地で呼んでいるstd.utf.encode関数の中で落ちる。
スレッドに割り当てるスタックが少なくて、オーバーフローしてるとか、そういうやばいレベルなのか。
GCが頻繁に動いているようなので、GCがバグってんじゃないのかとか思ってしまうんだが・・・多分俺だろうなぁ。

コーディングレベルでここまでひかかることになるとは・・・・・。