UNDOで参照リスト管理と参照カウントの不一致が発生する

UNDOで参照リスト管理と参照カウントの不一致が発生する.かなり難しい.これが解けないと参照リスト管理を導入する意味も半減してしまう,正念場だ.参照リストのバックアップが必要なことは明らかだ.しかし,参照リストを単独でバックアップしても意味がない.リスト全体が保全されなくてはならない.だとすれば,むしろ参照リスト自体を「凍結」してしまうのが早いのではないか?

しかし,そのようなことが可能だろうか?⇒UNDONODE::UndoCopyでは,最初にそのオブジェクトの参照をすべて参照解除しているが,Shadowイメージをコピーした後で,記載された参照リンクを参照リストに登録するという動作を追加してみた.

これにより,参照リストと参照カウントの不一致は当初の34件から6件まで減少した.これら不一致のうち,4件はUndoProcess中に発生し,残り2件はその後に実施されるCOUPLING::TopologicalSortで発生している.後の2件はNAMEBOXとMARGBOXが関わるもので,これらはUNDO動作とは直接関わりがないのではないかと思われる.従って,UNDOに関わる不一致は最初の4件だけと言ってよいと思う.

障害が起きているのは,MARGLINK:#311,CARDLINK #689,UNDONODE #115324,UNDONODE #115359だが,UNDONODEの2件はかなり疑問がある.UNDONODE #115324の参照リストは72, 参照カウント2となっているが,UNDONODEが外部から72も参照されるということは考え難い.というか,UNDONODEは参照フリーだったのではなかったか?⇒UNDONODE自体はチェーンを構成するためのスロットを2つ持っているが,実ノードやShadowへのリンクはべた参照だ.もちろん,外部から72も参照されるということはあり得ない.

TRASHCAN::ReuseWasteはオブジェクトを再利用するとき,まったくクレンジングということをやっていないようだ.2020/12/10に実装したはずのClean関数の仕掛けが消えてしまっている.どこかで修正のフィックスに失敗しているのではないだろうか?再利用可能なオブジェクトがない場合にはfreeblock::getmemでメモリブロックを確保した後,ゼロクリアしているので問題ないが… doCleanは使えるので,まずこれで固有データ部をクリアし,CleanSlotでスロットを全クリアしておこう.

CleanSlotはそのオブジェクトのクラスの分しかクリアしていない.CleanSlotは主にデストラクタで使われるのでこの方式で問題ないが,スロットゼロや拡張スロットまで含めた完全なCleanSlotが必要だ.⇒~NODULEではそれと同等のことをやっている.⇒void NODULE:CleanSlot(int topslot)というのを作った.いや,この名前ではvoid CleanSlot(bool)とかち合ってしまう.⇒CleanAllSlotとしておこう.⇒完璧にrevirginizeできた!ただし,NODULE::doCleanは純粋仮想関数としているので,nodule::doCleanを明示的に呼ぶ必要がある.

この修正でUNDONODEの参照リストが変化するものと思っていたが,予定外のNAMEBOXとMARGBOXが消えて,UNDONODEの2件が残ってしまった.これはかなりおかしいので,何かしらのバグと思われる.UNDONODEが72も参照を持っているということはおよそ考えられない.何かの間違いだと思う.⇒UNDONODEと別のオブジェクトが同じ参照リストを持っている.⇒ここまでは想定通りだが,偽の参照リストを持っているのは,MARGLINK:#311とCARDLINK #689の方だった.なんでこんなことが起きるのだろう?考え難い.

どこかですり替えが起きているのだと思うが… MARGLINK:#311とCARDLINK #689はどちらも<再生>されている.つまり,一度削除されたオブジェクトを復活させたものだ.従って,<再生>の手順に誤りがあることになる.これをやっているのは,UNDOBASE:RestoreShadowだ.⇒いや,呼ばれているのはUNDOSYSTEM:RestoreShadowだ.RestoreShadowに入るときにはMARGLINKは参照リストを持っていない.まだUNDONODEの参照リストカウントも2しかない.どうもUNDOでデータを保全した時点で誤りが発生しているようだ.カード削除コマンド出口のUNDOSYSTEM::CommandEndだ.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA