« 吉里吉里Z β2 バイナリ | メイン | 吉里吉里Z β3 バイナリ »

2013年11月10日

吉里吉里Z 開発:: showModal 等で顕在化する Access Violation

    

本不具合は、偶発的にメモリ破壊を起こしうる問題で安定性に影響するため、β3は予定よりも早く出します。


【不具合概要】
TJS2 VM は関数が呼ばれると Variant 型配列のレジスタが確保される。
レジスタの確保は、配列から切り出して行う。
変数など、このレジスタが使われる。
GC は、このメモリ配列の切り詰めを行う。
この処理に不具合があった。


【解析結果】
tTJSVariantArrayStack で Current は Arrays 配列の要素のアドレスを指している。
void tTJSVariantArrayStack::InternalCompact(void) の中で realloc し Arrays を入れ換えているが、Current は変更されない。
以後、レジスタメモリの確保は、Current が指している Variant の配列要素がなくなるまで、もしくは全てが解放されきるまで、Current を基準に行われる。
当然、この Current は既に解放されてしまっている可能性があり、その場合 Arrays が保持している値とずれていく。
結果、たまに Variant へのアクセスでアクセス違反が顕在化することになる。

showModal によってこのアクセス違反が顕在化しやすかったのは……
1. showModal はウィンドウ表示中その関数は返らないので、tTJSVariantArrayStack の全てが解放されることはなく、Current の値が維持されたままになる。
2. showModal で別ウィンドウがアクティブ化し、メインウィンドウが非アクティブ化されることで、メモリのコンパクト化が走り、InternalCompact がコールされる。
この2点による。
実際にアクセス違反が顕在化するのは showModal 後に吉里吉里の非同期イベント処理で、Variant 内でかつリリースビルドのみとなっていたため、解析が困難であった(問題のある部分と離れている)。

【修正方法】
realloc された時に Current も同時に変更する。


この問題は吉里吉里2 からあったものであるが、吉里吉里2 では顕在化しない様子。
BCB の realloc では確保済みメモリよりサイズが小さい場合、再割り当てが行われないのかもしれない。
絶対に発生しないのかどうかは不明。



投稿者 Takenori : 2013年11月10日 21:10




comments powered by Disqus
Total : Today : Yesterday : なかのひと