64ビットだと可変長メモリプールで落ちていた話

今週のメモ。夜間開発が作っている「約束ごとの試験」から、本物のバグが1つ出てきた。

■約束ごとの試験
p-kernel の芯は μT-Kernel 3.0(TRON の流れのリアルタイムOS)。この上にいろいろ載せているので、「タスクを作ったら動く」「待ったら起きる」のようなカーネルの約束を1個ずつ確かめる試験を、夜間開発に作らせている。
わざと壊したカーネルも用意して、試験がちゃんと赤を出すかも見ている。壊したのに緑なら、その試験は何も見ていないことになるので。

今週は可変長メモリプール(大きさがばらばらのメモリを貸し出す仕組み)の項目を足した。これで 133 項目、壊したカーネルは 14 種。

■足したら落ちた
足したとたん、64ビットの環境だけ tk_cre_mpl(メモリプールを作る呼び出し)でカーネルごと落ちた。32ビットの x86 は 133 項目ぜんぶ通る。

原因は構造体の並びだった。メモリプールの管理ブロックの途中を、別の構造体の先頭として読んでいる箇所がある。向こうの構造体は、64ビットだと途中に4バイトの詰め物が入る。こっちには入っていなかった。それで、空き領域をたどるたびに4バイトずれた場所を読んでいた…

mplsz   +36
areaque +40   ← 本当は mplsz から +8 のはず

32ビットでは詰め物が入らないので、元の並びで合っていた。64ビットに移したときに、並びを直し忘れていたっぽい。
直し方はメンバーを1つ前に移すだけ。ついでに、並びがまたずれたらビルドが通らないようにする検査も足した。

これまで見つからなかったのは、64ビット側にこれを呼んでいる所が無かったから。Linux 版や Android 版で、誰かが呼んだ瞬間に落ちる状態だった。(まだ誰も踏んでいない)

■赤のほうがありがたい
このプロジェクトでは「正直な赤は、塗った緑より価値がある」と決めている。試験を増やせば赤も増えるので、見た目は後退しているように見える。ただ今回の赤は、試験を増やさなければ見えなかったもの。

脳のほうも赤が多い週だった。1ビットに量子化して誤差を次に回すやつは 0/3 で赤。そのうえ、間違った作りでも正答率の合格ラインを通ってしまうことが分かった。甘かったのは合格ラインのほう。次の段では「写しのずれ」もラインに入れる。
※緑のままだったら、気づかずに先へ進んでいた。

■ほか
長く回るタスクで切り替わらない問題の続き。Linux の x86_64 と aarch64(Android の中身)でも、割込みの出口でタスクを切り替えられるようにした。

学習の後半の重みを平均するだけで、種7つすべてで少し良くなった。動いている脳を実際に良くできそうな最初の候補。監査待ちなので、まだ既定は OFF。

夜間開発は 10/8 の夜から 10/11 の朝まで止まっていた。週の使用量の枠を、自分が木曜・金曜に使いすぎて上限を超えたため。

■次
mind/hist(「1つの心」の中心の部分)と、重みの平均が長く動かしても効くかを測るところ。

※リポジトリ: https://github.com/monyuonyu/p-kernel

※この記事は、p-kernel の開発を手伝ってもらっている AI(Claude)と一緒に書いています。

コメントを書く