[Essay] Mac昔話 その1

なんかそんなの書きたくなってきたんや。まぁ、忘れないうちにって奴やな。とはいえ、だいぶ記憶も曖昧なので、ディテールは若干違う可能性が高いが…。

もう20年以上前の話やけど、一応固有名詞の一部はボカしておこうか。わかる人にはわかると思うが…。

●発端

「あんたのトコのソフトでHDDを初期化しようとしたら、爆弾マーク出るんやが」

当時、某Y社でソフト開発(主にHDDの初期化ソフトやドライバ等)をやり始めた頃に、そんなクレームが来た。割と初期の頃やったと思う。あ、今の人には爆弾マークはわからんか。端的に言うならシステムクラッシュって奴やな。当時、他のパソコンでは無言?でロックしてしまうような時でも、Macなら画面にチャンと丁寧に表示してくれたんや。まぁ、その後は大抵リセットするしかなかったんやが。

そういえば、一部の好事家向けにこの爆弾マークのぬいぐるみが出てたな。デバッグでムカついた時に投げつけるのに良いとかなんとか…実はヲイラも買って今も持ってるが…

で、社内で何度検証しても、一度もそんな問題は出なかった。実に安定してソフトは動いてたんや。これはオカシイってコトで、クラッシュした時の状況を詳しく教えてもらうコトになった。

「あ、でも再起動したら問題なく初期化できたで。なんか他のモンがアカンかったんか?」

余計にワケがわからなくなった。

●糸口

それからしばらくして同じ問題があったんだったか、それともそのお客さんが教えてくれたんだったかは覚えてないが、どうもクラッシュする条件が見えてきた。

それは、元々そのHDDが他社(当時世界中で使われ非常に有名だった某S)のソフトで初期化され、稼働している状態からウチのソフトで初期化しようとした時だけ、クラッシュするというものだった。

ここまで条件が見えてきたなら後は早いってんで、色々とデバッグツールを突っ込んで解析を開始した。

●専門的な予備知識その1:当時のMacのHDD事情

当時のHDD(20MBとか40MB程度しかないシロモノだった。1MB1万円とか言われてた)は、同じSCSIバスに繋がるとは言うものの、メーカーによって若干の差異があった。極基本的に読み書きだけは共通だったけどね。ヲイラが覚えてる一番酷いのは、容量の値をバイナリで返すべきトコロ、BCDで返してくるなんてクズがいたな。

当時のAppleは、今では当たり前の「Plug and Play」を推進してた。繋げば動くって奴やな。あの当時は、よそのは繋いでも色々せなアカンかってん。Macは「For the rest of us」なマシンだったので、そんなメンドクサイことはお客さんにさせたらアカンってコトで、全部内々で処理する方針だったんやな。まぁ、これも今は当たり前なんやが。

しかし、HDDが結構バラバラだったので、その辻褄を合わせるドライバもそれぞれに別のソフトが必要やった。しかし、システムソフトウエアの中にそんなドライバを全部抱え込むのは非現実的や。新しい機種が出るたびに抱え込まなアカンからな。サードパーティ製品のドライバなんか抱え込むなんてリスクも避けたかっただろうし。

そこでAppleは、HDDの特定の領域にドライバを書いておくコトを約束事とし、Macはその起動時に自動的にその領域からドライバを読み出してメモリ内に設置し、HDDの管理をさせるという形をとった。HDDの初期化ツールの仕事は、基本的にはその領域確保とドライバの書き込みだったんやな。実際のファイル領域の初期化(ディレクトリの作成とかな)も仕事の範疇だったけど、実はそれはシステム側でやってた。丸投げする仕組みがあったんよ。

当然、出荷するHDDは全て初期化した状態で出荷してた。そうしないとPlug and Playにならないからな。なので、初期化ソフトを使うのは何か問題があった時か、ウチのソフトの方が便利そうだからウチのに切り替える…みたいなケースであった。

●専門的な予備知識その2:当時のMacのドライバ事情

あの当時のMacのシステムが扱うドライバは、確かDevice Managerってやつが全部管理してた。メモリ内にベクトルテーブルがあり、各ドライバは5つのエントリポイント経由でシステムから仕事をもらう方式やったな。5つってのは、確かOpen、Close、Read、Write、Controlだったか。

OpenとCloseはドライバ自身の起動と終了、ReadとWriteはそのままデータの読み書き、Controlはそれ以外の雑事で、たとえばFDDなんかでメディアを排出する指示なんかはココ経由で来てた。いくつかの命令インデックスがあって、それに沿って処理する形やったな。

最初はSCSI ID毎にエントリポイントのセットが用意されてた。これは途中で方式変更になったけど。SCSI-HDDの場合、HDDからドライバ本体が自動的に読み出され、自動的に対応するエントリポイントがセットされてたと思う。

なので、一部の悪いアプリなんかはこのドライバのエントリを直叩きして高速化とかやってたワケよ。まぁ、徐々にアウトになったけどな。

で、このSCSI-HDDのドライバに関してはAppleがサンプルコードを提供していた。それも、物凄くわかりにくい場所にコッソリとあったと思う…もしかするとInsideMacのどこかのページだったかもしれない。当時はネットではなく、紙媒体とかFDDで資料が配布されてたからな。オマケに、ロクにドキュメントもなく、さらには68KのフルASMだった。確か、バイナリで2〜3kByte程度だった気がする。全部Pascalで書き換え、更にはCで書き換えたな。それでも5kByte程度だったか。

SCSIバスの管理に関してはSCSI Managerってのがあったので、直接ハードウエアを叩くコトは無かった。しかし、このサンプルコードがこの問題の原因の一旦になってたとは、開発当初は気づいていなかった。

●そして解析…発覚した恐るべき罠

クラッシュする条件がわかったので、デバッガを使って初期化ソフトをステップバイステップで動作させていった。既に稼働している状態のHDDだったので、まずマウント状態からアンマウントした。次にHDDの重要領域を初期化し、各種領域を確保し、自前のドライバを書き込むところまでは順調に動作していた。HDDのデータを確認しても、何ら問題はなかった。

当然、お客さんにはそのまま再起動せずに新しく初期化されたHDDを使って欲しいので、既存のドライバを解除する必要があった。でないと、システムは既存のドライバの方へアクセスしてしまい、ドライバは古いままなのにHDDの内容がウチのに合わせて綺麗に書き変わってるので、それこそシステムクラッシュを引き起こしてしまうからだ。

そのため、初期化ソフトは次のステップとして既存のドライバのCloseエントリを呼び出した。普通なら、それで既存のドライバは自身の後始末をしてくれるハズなので、安心して5つのエントリポイントを自前のものに書き換え、HDDの制御を自前のドライバが管理できるハズであった。

しかし、結果は「ココで爆弾マーク」だったのだ。ヲイラのソフト、関係ないがな。既存のドライバ…つまり、HDDを初期化してた元の某Sのデバイスドライバは、Closeを呼ばれるとシステムクラッシュを引き起こしたのであった。

そして、そこでハタと気がついた…そう、さっきのSCSI-HDDドライバのサンプルコード、実はCloseはカラだったというコトに。サンプルコード自体、Close処理は何もしていなかったのである。

当然、何もしなくてもそのまま順当に戻ってくれば何の問題もない。しかし、某Sのドライバはどういうワケかここでシステムクラッシュを引き起こすのである。詳しくは解析しなかったが、確かエントリポイントにあるCloseのエントリ自体が何かデタラメな値だったのではなかったかと思う。

もう一度書く…そんなん、ヲイラのソフト、関係ないがな!

●対策

そもそも某SのドライバがCloseを呼ばれるとダメになるなら、いっそのコト呼ばなければ良いということにした。

基本的に、ドライバは先の5つのエントリポイントを介して外部とやり取りをしているので、ココを塗り替えられると「単なるメモリ上のゴミ」になる。とはいえ、内部的に何か割り込み的な処理をしていないとも限らないので、既存のドライバのメモリ空間まで破壊するのは危険と判断し、そのまま放置することにした。迂闊にやると、これまたシステムクラッシュするからね。

本来ならそのドライバが某Sかどうかを判定すべきではあるのだが、サンプルコードの一件を考えると他のメーカのドライバでも同じ傾向が出る可能性があったので、Closeは完全に無視するコトにした。有無を言わさず、エントリポイントを全部自前のものに書き換える形にするコトで、爆弾マークは出なくなった。

当然ではあるが、Mac自身が再起動すれば先にHDDに書き込んでおいた自前のドライバがロードされるし、既存のドライバはメモリの屑として消え去るので、何か問題が起きるとしても初期化後から最初に再起動/シャットダウンされるまでだしな。

というか、お客さんトコで「再起動したらイケた」ってのはそういうコトだったんだろう。

●教訓

  • いくら世界的に使われてて有名なソフトだからといっても、クソはクソである
  • ロクにドキュメントも出してなかったAppleの当時のあの辺りの担当もクソである
  • 表から見て問題を起こしているソフトが、真の原因とは限らない

たぶん、三つ目の教訓は今でも有効ではないかと思う。なので、何かソフトで問題があったとしても、すぐに表面上の原因だけを叩いちゃダメだよ。

おしまい

Zak について

基本的にヲタクです。いや、別に萌えとかいうのではなく、ハマるとトコトン進めようとする癖があるので、自制が必要だという…。
カテゴリー: Apple, ソフトウエア, 書き物 パーマリンク