第19版のコンパイル

2007/11/18

主筆」第19版の配布用バイナリを作成するために、Solaris8でコンパイルしようとしているのだが、これがどうにもうまくいかない。時刻を取得するために使用しているlocaltime_rという関数が見つからないとか抜かし、コンパイルを完遂しないでいやがる。

原因はなんだか知らんが、どうやらSolarisとPOSIXの微妙な違いにあるらしい。とりあえず、ヘッダファイルとかマニュアルとかをみると、コンパイル時に「-D_REENTRANT」という指定を入れて、「_REENTRANT」というマクロがdefineされるようにしてやればいいらしい。

だが、この指定を入れるとスレッドやプロセスの扱いが微妙に変わるというようなことがマニュアルに書かれている。この微妙な変化が動作に悪い影響を与えなければいいのだが。

それにしても、今現在Solaris8はBlade 100のマシンにインストールしてあるのだが、これでコンパイルすると時間がかかってたまらない。64ビットで最適化を入れてコンパイルすると、すべての処理が終わるまでに25分掛かる。でもって、コンパイルの最後の方でリンクのエラーとかが出て、またやり直しになったりして、本当に疲れる。

しかも、そうこうしているうちにマシンの環境を破壊してしまい、起動しなくなってしまった。原因は分かっているので、うまくすれば復旧する事もできたのかもしれないが、面倒だから再インストールする事にした。

このところ立て続けに再インストールの作業を行っているから、さすがにそろそろ慣れてきた。Solaris8を入れた後に行う設定作業や、入れたり削除したりするパッケージ、あるいはその順番など、いくら物覚えの悪い俺でも体で覚えてきた。だから、インストールを始めてから1日ほどで元通りの環境を再現することができた。

今現在は、足止めを食らった分を取り戻すべく、Solaris8上でコンパイルを行っている。差具我にそろそろうまくいってくれても良さそうなものなのだが。

Sun Studio 12

2007/11/13

気がつくとSun Studio 12の日本語版が公開されていた。早速落としてみたが、まだ入れてはいない。

しかし、ダウンロードするファイルの容量がSun Studio 11の頃と比較して、大幅に増えている。1138.93MBもありやがる。しかも、bzip2で圧縮されている。

その上、Sun Studio 12はよく見るとSolaris 8には対応していない。ちょっとばかり、嫌なことになってきた。

古いバグ

2007/11/04

第19版を公開するために必要な作業はおよそ終了した。後はホームページの紹介の文章を多少いじくるだけでいい。だがその前に、二三気になる点を修正することにした。

そのうちの一つに、長い間原因不明のまま放置してきた、時々「主筆」が二つ起動することがあるという問題がある。これは、ファイルをダブルクリックしたり、あるいはコマンドで主筆を起動した際に、主筆が同時に二つ起動し、なおかつその双方ともが同じファイルを開いてしまうという現象である。

主筆では、同じファイルが同時に複数回開かれることの無いように制御を行っている。だがそれが時々うまくいかなくなるのだ。うまくいかなくなるだけならまだいいのだが(よくないが)、しかし、主筆サーバ内の制御ロジックは、同じファイルを開いた奴が複数個存在しないことを前提としている都合上、この問題が発生すると内部の状態が不正になる可能性がある。

しかも、このバグは滅多に発生しないという最悪な性質を持っている。そのため、いつかなる時にいかなる原因で発生するのか、追求に手間取った。というか、ほとんど対処できなかった。

当初は、この問題では起動する主筆は必ず二つであり、三つ以上になることが無いと言う事から、主筆サーバ内のロジックを疑っていた。主筆サーバでは、クライアントや主筆から受け付けた要求の処理に失敗したら、もう一度だけリトライするよう実装してある。つまり、俺はこのリトライ処理の周辺で何かおかしなことになっているのではないか、と考えたのだ。この周辺の処理、すなわち、主筆サーバが主筆を起動し、主筆サーバ内の管理リストを更新するまでの処理は、意外と複雑なことになっている。だから、この複雑なところが一番臭いと、そう踏んだのだ。

だが、事実はそうではなかった。よくよく調べてみると、結局原因はプロセスの起動処理にあることが判明した。

プロセスを起動する処理は、その処理結果として起動したプロセスのプロセスIDを返すようにしている。また、処理に失敗した場合には-1を返す。ここの処理に下らないバグがあり、生成したプロセスのpidによっては、起動に成功したにも関わらず-1が返されてしまうことがあったのだ。そのため、主筆サーバ内のリトライ制御によりもう一度起動処理が行われれ、結果として主筆が二つ起動してしまっていたのだ。

下らないバグというのの概要はこうだ。

プロセス起動では、親プロセスでforkして子プロセスを生成し、その子プロセスからさらにもう一度forkを行い孫プロセスを生成して、その孫プロセスがexecする。そして中間の子プロセスはそのまま_exitする。こうすることによって、起動された孫プロセスをinitの子として、ゾンビプロセスなどの諸々の問題を回避するようにしている。これは、ゾンビプロセスの発生を防ぐ古典的なんだそうだ。

主筆では、この処理の中で子プロセスはforkする以外にもう一つだけ仕事を行っている。それは、親プロセスに孫プロセスのpidを通知する処理である。すなわち、親プロセスは孫プロセスのpidを知り得ないから、子か孫に教えてもらわねばならないのである。

そして本問題の原因は、このpidの通知方法にあった。なんと恐ろしいことに、子プロセスはその終了ステータスとして孫プロセスのpidを通知しようとしていたのだ。でもって、親プロセスのその終了ステータスをもって、起動した孫プロセスのpidとして関数の戻り値としていた。

もうね、ほんとに俺はアホかバカかと。プロセスの終了ステータスは1バイトしか返せないのだから、pidを終了ステータスにして_exitしたら、その下位1バイトしか親プロセスに返されないに決まっているではないか。下位1バイトしか返されないのであれば、たまたまそのバイトが0xFFになることだってあるではないか。0xFFであれば、データの扱いによっては-1になることも十分にあり得るではないか。

結局、このバグがたまにしか発動しない理由もこれでわかった。下位1バイトがたまたま0xFFになるのが、たまにしか起こらないからなのだ。

原因がわかれば対処法も自ずと明らかになる。用はpidの伝達に終了ステータスは使えないのだから、おとなしくパイプで通知してあげるようにすればいいだけだ。ちょっと面倒だとはいえ、ほかに方法はない。

この対応を入れることにより、問題は解消されたはずだ。生成された孫プロセスのpidが確実に親プロセスに通知されることも確認できたし、孫プロセスの下位1バイトが0xFFになる場合においても、主筆が二つ起動されることがない事は確認した。

バグというのは、たとえどんなに不可解な現象で、原因が全く推定できないようなものであっても、わかってみればこんな下らない事だったのかと、思わずにはいられないものだ。こんな些末な、あるいはこんな明白なものであればもっと早くに気がついて然るべきだと、いつもそう思うのではあるが、それがなかなかそうもいかない。人間というのは不思議なものだ。

CD-R

2007/11/03

Solarisにパッチを当てる度、いつも二・三個失敗して余ってしまう物がある。どうやら8/07以降のSolarisに含まれているとか言うパッケージを入れねばならないらしい。ならば、それを落としてきてCD-Rに焼かねばならないのだが、しかし、俺の手元にあるCD-Rの残弾は心許ない。

普段CD-Rはバックアップ取得用に少しずつ消費しているのではあるが、LinuxやSolaris等、特にOSのディスクイメージを落としてきてインストールする場合などには、まとまって消費される事がある。

腐るものでも無し、まとめて買って備蓄しておけば、それでいいのかも知れんが、しかし普段の消費量が少ないことを考えると、つい買わずにいてしまう。そしていざという時に不足に泣く事となる。

最近では店に行ってもCD-Rがあまり売っていなかったりもする。ほとんどがDVD-Rであり、昔ながらのCD-Rは棚の片隅で埃を被っていたりする。ちょっと買うのが恥ずかしい。このままでは直に手に入らなくなるのではないだろうか。もはや100円ショップではCD-Rやフロッピーディスクが姿を消しつつあるように。

それを考えればそろそろDVDかあるいはBlu-rayディスクか何かにしたほうがいいのかも知れないが、しかしいかんせん、3年掛かりの超大作といえ圧縮すれば数MBにも満たないものをバックアップするのだけであり、640MBでも多すぎるのに、なぜにわざわざ金を出してまでまでして、いらんものを買わねばならないのか。

技術革新にはおおむね肯定的な俺とはいえ、やはり規格の乱立と製品寿命の短縮には賛成できない。「あなたの損は私の利益」という言葉は経済の本質を表したものではあるのだが、しかし、消費者の利益を害する企業に将来は無いというのもまた一面の真実である。

DVD-RがCD-Rの代用品として使えるのであれば、それでもいいと思うのだが、どうもそんなことができるようになっているとは思えないし、新しいドライブを買う気はさらさら無いし。かといって磁気テープもまた規格乱立と非互換の泥沼だし、何か良い方法はないのだろうか。

まぁ、新しいドライブが只で手に入れば全ては丸く収まるんだがな。