目標:PENDINGゼロでVERIFICATION,TEMPORARYの完全ニュートラルを達成

コンパイルオプションを6つのカテゴリに区分し,それらにタグを付けて管理するようにした.

  1. VERSION comdebug.h COMDEBUG:
  2. INCOMPLETE nodule.h INCOMPLETE:
  3. PENDING nodule.h PENDING: 
  4. TEMPORARY bobject.h DEBUG: , LOCAL:
  5. VERIFICATION bobject.h VERIFY:
  6. TEST coupling.h TEST:

comdebug.hに入っているCOMDEBUG:はバージョンやライセンス管理などに用いるものでデバッグの対象とはならない.nodule.hにはINCOMPLETEとPENDINGが入っているが,INCOMPLETEは現在ゼロ個,PENDINGが36個ある.PENDINGの中には将来的な拡張に備えるものもあるので必ずしもすべてという訳ではないが,一応PENDINGの個数をゼロにするというのがこの作業の目標と言える.TEMPORARYはデバッグ時のダンプなど一時的に使われるコード,VERIFICATIONは検証のために常設されているプローブだが,いずれも無害コード(フローを変化させず,データの書き換えを行わないもの)でなくてはならない.TEMPORARYとVERIFICATIONがこのような意味でのニュートラルなコードになっていることを確認することもこの作業の一部に含まれる.

coupling.hに入っているTESTは包括テストなどを実施するためのオプションだが,すでにかなり古くなっているように思われる.実際,現行では包括テストはすべてヘルプメニューから実施できるようになっており,コードをいじる必要はない.システムに組み込まれた作り付けの装置のようなものになっている.TESTコードの大半は廃棄の対象になるかもしれない.オプションをオンないしオフにしてエラーが発生するとすれば,基本的には動作する側でフィックスすることになる.

不用となったコードを参考資料として温存するか否かはまた別の判断になるだろう.INCOMPLETEということはデバッグ未完了ということを意味するから,これを一応対象外とすれば,このセッションの目的は「PENDINGゼロでTEMPORARYとVERIFICATIONがデータフローニュートラルであることを確認する」ことにあると言える.

counpling.h はシステム構成図の頂点をなすCOUPLINGクラスを定義するものなので,すべてのコードから参照可能になっていると思っていたが,一部にアクセスできないものがあった.これまでヘッダファイルのヘッダファイルとして使われていたkakeizu.h はcoupling.h でもインクルードしているので,include “kakeizu.h” となっていたところをすべて include “coupling.h” に書き換えた.nodule.h や comdebug.h は元々グローバルにアクセスできるようになっている.coupling.h はkakeizu.h に入っているKAKEIZUを参照しているので, kakeizu.h から coupling.h をインクルードすることはできない.

PENDINGはデフォルト(既定でオンのオプションをオンとして),DEBUGはすべてオフ,VERIFYはデフォルトを試して動作した.ただし,Bobject::vsegmentが廃止されているため,NAMEBOX::DrawとMARGBOX::Drawで修正が発生した.DEBUGはすべてオフのまま,VERIFYのデフォルトオンをすべてオフに切り替えて試したところ,広域スプリットと描画不良が発生した.ただし,TRIBELIST:TribeBaseList→baselist,GENEBOX::getGene→getGenerationの書き換えた.⇒以下のオプションをオンにすることによって描画できた!

#define ABSOLUTEYLIST            // VERIFY: ★絶対座標変換を描画リストに沿って実施する

これはかなり驚異だ!止めてあるオプションの中には,「極大グラフ検定を実施する」,「三極検定を①結婚点一致→②衝突検定→③セグメント検定の順で実行する」,「★BRect::InterSectRect関数で接触を交差に含める」など,システムの基本仕様のようなものまで含まれている.

ともかくABSOLUTEYLISTを実施しないと描画できないことが分かったので,この定義はオプションから仕様(SPECIFICATION)に格上げするしかない.いや,そう結論するのはあまりにも単純だ.ABSOLUTEYLISTがオフのときには何もしていない,つまり相対座標系のまま放置されているのだから,描画できるはずがない.仮に描画関数がすべて相対座標に対応していればその可能性もゼロではないが,現行ではほとんどの関数はそうなっていないはずだ.

将来的にすべての描画関数が相対座標系に対応するということも考えられないことではないが,ここでは一旦このオプションを仕様として確定するしかないのではないか?⇒#if defined(ABSOLUTEYLIST) を #if 1 に変えて確定したが,元の論理は残した.「Yリストに沿った変換」ではなく「座標系変換パスに沿った変換」というのも考える余地があるからだ.むしろそれを試して両者が完全一致することを確認した方がよい.ただし,それはまた後日ということにしておこう.

ここでは一旦DEBUGとVERIFYのデフォルトでオンの項目をすべて戻した上で,PENDINGの分を試してみることにしよう.⇒2つのオプションをオンに戻すことでエラーを回避することができた.一つは「GetOSDisplayStringの使用停止@20190109」でもう一つは「CHUNKFILEクラスを実装する」だ.前者がないと「’GetVersionExA’: が非推奨」の警告が出てオブジェクトファイルが作れない.また,後者がないと,カード写真イメージのロードに失敗する.従って,これらも必須オプションということになるが,ここで新たに2つのサブカテゴリないしタグを追加することを提案したい.

①SPECIFICATIONと②OPTIONSだ.前者はそれがないとシステムが動作しないもの,後者はオン・オフを切り替えても動作するが,オフのときの動作は保証しないというものだ.両者の線引きには多少微妙なところがあるが,いまの場合,上記のABSOLUTEYLISTや,「GetOSDisplayStringの使用停止@20190109」はSPECIFICATIONで「CHUNKFILEクラスを実装する」はOPTIONSでよいのではないかと思う.一旦PENDINGからSPESIFICATIONないしOPTIONSに格上げされたオプションは,基本的には確定したものと考えてよい.

このサブカテゴリに該当するものはかなりあると思われるので,整理してみよう.というか,まだデフォルトでオフのオプションをオンに切り替えるテストをやっていないので,そちらを先に片付けてしまおう.デフォルトでオンのオプションはすべてオンに戻しておくことにする.多少の修正が入っているので一度バックアップを取っておこう.いや,それどころではない.例外が発生している.

上記の環境で起動→終了で,以下のようなメモリアクセス違反の例外が発生した.

mblock->**mmptr** が 0x93203436

再現しない.障害はSaveFamilyBaseで起きているのでバックアップタイマが作動するまで待つ必要があるのかもしれない.例外はfreeblock:delmptrで発生している.バックアップファイルは作られたが正常に終了できた.バックアップが更新されるまで待ってみよう.以下の行が数回出ていたのでかなり時間が経っていたかもしれない.

書き込み:zoom_normal=0.290677 preview=0.305460

終了ボタンが効かなかったような気がするので,放置していただけで起きていた可能性もある.これまでにこのような例外の発生は見たことがないので何か微妙なタイミングがからむ超低頻度の事象がたまたま起きたという可能性もある.このプリント文はSerializeHeaderで出しているものだ.⇒再現した.上の「書き込み」を4回出したあと,例外が発生している.ただし,今度は少し状況が違う.

**this** が 0x92D0907B

というパターンだ.この障害は直ちにはシューティングできない可能性もあるので(いじっているうち消えてしまう可能性もある)現状をサンプルも入れて別にバックアップしておこう.何か止めているオプションで影響しそうなものはあるだろうか?「ファイル保存時バッファを予約する」などというのは可能性がありそうだ.バックアップタイマーのインターバルを縮めて再現できるかどうか見てみよう.現行では1分タイマーになっているので,10秒に短縮してみる.

どうも効きが悪い.この値を短くしても効果はない.これはタイマーが作動する「インターバル」でタイムアップするまでの時間ではない.この値はユーザの設定値でレジストリに保持されている.しかもこの値は1分単位だ.とりあえず,1分に変えてみよう.少しは速くなったようだ.RESCUEMINUTEという変数に格納されているので,これを直接変えることもできる.あるいは残り時間の計算をいじった方が早いかもしれない.⇒確かに4回目で起きている.比較対象のタイムスタンプが分単位なので分より速くはできない.今度は3回目で起きた.

OPENQUICKDB(ファイル保存時バッファを予約する)をオンにしてみよう.⇒確かにこれだ.すでに9回「書き込み」が発生しているが,例外は起きていない.つまり,このオプションも必須ということになる.バッファを使わないという方法もあるいは可能なのかも知れないが少なくとも現状ではそうなっていない.これでSPECIFICATIONに入るものが3つになった.「CHUNKFILEクラスを実装する」を含めそれ以外のPENDINGのかなりのものはOPTIONSに移すことができる.

もう一つサブカテゴリ(タグ)としてDEFECTIVEというのを作っておこう.これは「欠陥がある」という意味ではINCOMPLETEと同じだが,INCOMPLETEは完全なものに仕上げる必要があるのに対し,DEFECTIVEは「当面使用禁止」というもので放置しておくことができるものだ.TESTに入っているオプションはほとんどそこに入ると思う.INCOMPLETEはnodule.hが一元管理しているが,DEFECTIVEはそのオプションが配置された特定ヘッダファイルの中で個別管理することにする.⇒DEFECTIVEはタグではなく,#if defined(DEFECTIVE)のブロックで隔離するだけでよい.多分これで相当整理されると思う.RESCUEINTERVALは1分では粗すぎるので,20秒にしておこう.

PENDINGの中からOPTIONSに移せるものを拾い出してみよう.テストを公平なものにするために,DEBUGとVERIFYはすべて止めておくことにする.その上でオンで動くものはOPTIONS候補だ.IMPLEMENTCHUNKFILE(CHUNKFILEクラスを実装する)もSPECIFICATIONとしておこう.カード写真イメージが読めないというのは致命的ではないが,欠陥であることは明らかだ.PENDINGのうちデフォルトでオンの項目すべて(17件)をオンにしてテストしてみよう.サンプルはZTシステム構成図7.ZELとする.

上記設定で起動→部分図→全体図でエラーが発生した.PAIRBOX::getLocationで(Deleted())が起きている.「一時的にSTOPを抑制する@20201026」で止めてあったところだ.シューティングを試みることにしよう.PAIRBOX::getLocationで失敗している.⇒getLocationを呼び出す前にすでに「ノード対世代不一致」が検出されている.このノード対はすでに削除されてゴミ箱の中に入っている.StillAliveという検査をすり抜けている.なぜだろう?StillAliveでは#2434が返っている.USERECYCLESYSTEM (描画オブジェクトのリサイクルシステムを用いる)はオンになっている.「DEBUGとVERIFYはすべて止めておく」という設定にはなっていない.

確かにここではまだ死んでいない.PairBoxGeneChangeを実行した時点で削除されている.PairBoxGeneChangeでは「世代差ゼロ以下でノード対を破棄」が実行される.この関数はnewboxを返しているので戻り値を見れば成功したか否かは判定できる.それをやっていないのが致命的だ.⇒対処した.

USERECYCLESYSTEM(描画オブジェクトのリサイクルシステムを用いる)をオフにしているのに,削除されたオブジェクトがゴミ箱に入っている.USERECYCLESYSTEMというのはリサイクルを実施する/しないではなく,リサイクルシステムを使っているときにはCARDLINKとMARGLINKを初期化する必要があるというだけの話だ.これをオフにしても動作しているのは,特に必要な処理ではないということを意味するように思われる.ゴミ箱はシステム木のルートであるCOUPLINGを生成する以前に生成されている.⇒ゴミ箱を生成しないようにしてみたが問題なく動作している.オブジェクトはフロート状態になっているが,アクセスは可能だ.つまり,ゴミ箱はなくても動く.deleteしても直ちには削除されず,Nringが管理しているのだろう.

リサイクルシステムはCANが空のときは実質無動作になるので,USERECYCLESYSTEMのときはCANを生成しないようにすれば,名実ともに「リサイクルシステムを用いる」の言葉が活きてくる.リサイクルシステムはなければ動作しないというものではないから,SPECIFICATIONというよりはOPTIONSとすべきだろう.

上記サンプルでDEBUG, VERIFYはすべてオフ,PENDINGのデフォルトオンはすべてオン,OPTIONSもすべてオンの環境で,源氏物語全系譜6.ZELを開いて停止した.(primarynode->getmarglink() != getOyalink())が起きている.障害はTRIBEBOX::decidePrimaryNodeで起きている.インストールされているアプリでは以下のような別の障害が起きる.この版は2.2.0.015 R 2020-11-05だ.

image

この後も操作の度にエラーが出る.源氏でこんなにエラーが出るなんて信じられない.どこかで間違ってしまったのではないだろうか?再開発スタート版を見てみよう.その前に開発機でバックアップを取っておこう.⇒確かにスタート版ですでに起きている.この版を採用するとき十分なチェックをしたつもりだったのだが…ZELKOVA_2020-10-12★では,「非連結グラフ」というのは出るが,ここまでひどくはない.ZELKOVA_2020-10-24では問題なく開ける.再開発スタートは10月14日だから,それより後の版だ…無傷で開けるのは10月24日が最後でその後は重婚同類検定で以下のようなエラーが出るようになる.

image

リリース版は滅多に作らないので日付と内容が一致しているとは限らない…デフォルトでオンのオプションをすべてオンに戻してみたが,動作は変わらない.ともかく,少し追いかけてみよう.どうもかなりおかしい.TRIBEBOX::Oyalinkには値を設定しているところがない.だからつねに空だ.10月24日版で見ると,ASSERT_NEVERの行は「仮修正@20190129」としてコメントアウトしてある.どうもそれを不用意に外してしまったようだ.TRIBEBOX::Oyalinkには値が設定されていないのだから,このパラメータはすでに廃止になっているのと同じだ.その方針で修正してみよう.

勘違いしていた.Oyalinkは活きている.これがなくては動かない.Oyalinkというのは,「従系列に属する優先仮ノードの親の結婚リンクへの参照」だ.いまの場合は軒端の荻が優先ノード,主系列は光源氏のいる一院系列,従系列は配偶者の蔵人の少将が先祖ノードになっている.軒端の荻の親の伊予介は先祖ノードで別の系列を立てている.軒端の荻の出現箇所は以上の3箇所だが,蔵人の少将の系列では配偶者ポジションなので親はいない.つまり,Oyalinkは空だ.従って,優先ノードのgetmarglinkと系列のgetOyalinkが一致することはあり得ない.しかし,それ以外の論理には抜けはないと思われるので,ASSERTION行だけの誤りということになる.以下のような記録がある.

@20190129 → 廃止@20201107 decidePrimaryNode,SetMinorTribe

仮修正@20190129を廃止したという意味だろう.decidePrimaryNodeというのはいまの問題箇所,SetMinorTribeにも同様の(おそらく)誤りがあるが,この2箇所にはSTOP文が入っているため,間違っていても停止するだろうという見込み(安全を見込んで)で廃止で確定したのだろう.@20190129の修正は3箇所あって,もう一つのNAMEBOX::IfBTWPossibleの修正は活きている.

もう一度DEBUGとVERIFYのオンをオフに戻して次に進もう.SEPARATEVHZONEはすでにどこからも参照されていないので廃止.HORIZONTALQUICKARANGE,BESTEFFORTCHANNELTROUBLEも同様.ファイルへ出力をサポートしない@20180314はいまのところは「仕様」と考えられるのでSPECIFICATIONに移しておこう.PUREBLOODLINE 純正血統図をサポートするも完全に仕様だが,オフでどういう動作になるのか見ておく必要がある.

多重カードのカウントがおかしい.ZTシステム構成図7.ZELで多重が10件以上出ているのに,表示では多重ゼロ,不可避ゼロとなっている.

image

いや,何か勘違いしていたようだ.上の図では多重14で合っている.ただし,不可避が1で多重が14も出るというのはよく分からない.重婚同類循環は3となっている.

▲書き込み:zoom_normal=0.322251 preview=0.034721の表示にタイムスタンプを追加する⇒タイマーのインターバルを確認したい

コメントを残す

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

CAPTCHA