Windowsとstat()と僕

GMVというのを
ずっと作っている。普段の開発環境は Mac だが、GTK+ を使っており、いちおう
cross platform ということになっていて、各種 Unix (X11) で動くのはもちろん
のこと、いちおう Windows でも動くことになっている。
で、バイナリ配布もやっており、研究室にある僕の iMac でスクリプトを実行すると、
– ソース
– Mac 用の Universal な application bundle (gmv.app)
– Windows 用のバイナリ (gmv.exe)
を生成するようになっている。Windows 向けのビルドには MinGW を使っており、
iMac には MinGW のライブラリと MinGW な gcc のクロスコンパイラがインストール
してある。
しかし、いくら MinGW を使っているといっても、Windows との互換性を維持する
のはけっこう大変で、Mac や FreeBSD できっちり動くプログラムが MinGW な環境でもコンパイルがちゃんと通ったからといって、動くとは限らないのだ。
幸いにして、GMV を使ってくださっている方々の大半 (というか、全員) はMac および Unix 陣営なので、これが問題になることは普段はないのだが、自分の大学の、4月の学生実験だけは別だ。なにしろ、数十人の学生がいっせいにWindows で GMV を使う。これは、ものすごく怖い。
去年は、Windows なテスト環境を PentiumM な ThinkPad T42 しか持っておらず、SMP な環境でたまに落ちるバグ、というので苦しんだ。最近の計算機はみんなPentium4 Hyperthreading をはじめとして、CoreDuo や Core2Duo なわけで、純粋に uniprocessor な環境、というのはほとんどない。で、このときはMinGW なコンパイラを gcc-3.4 から gcc-4.0 にアップデートすることで解決した。
今年はどうかというと、1月にかなり Windows でデバッグをしたので、完璧に動くとタカをくくっていた。まったく甘かった。
Windows native な開発環境は、Cygwin と NTEmacs がメインで、コンパイラやライブラリはやはり MinGW だ。Cygwin はまあ、そこそこ便利なのだが、Windows には fork() がないのが原因なのか、とにかくプロセスが起動するまでがものすごく遅い。したがって、細かいソースファイルをたくさんコンパイルしたりだとか、そういう作業がとてもしんどい上に、MinGW なライブラリを使っていることが関係するのかどうかわからないが、gdb の出力は概ね意味不明であり、stack backtrace なんかはほとんど役に立たないといってよいレベル。したがって、Mac とかそのほかの Unix で完璧に動くようにしておいてからじゃないと、Windows で作業するのは非常にきつい。
今回のバグはなんだったかというと、ファイルのタイムスタンプを調べるのに使っていた stat() の挙動が怪しい、というものだった。thread safe になっていないとか、そういうことが原因なのかなんだかは結局わからずじまいだが、stat() それ自体は成功するものの、そこから数行を実行する間にプログラムがクラッシュするのだ。結局のところ、GLib にある g_stat() を使うことで解決した。この関数は、結果を返す構造体も OS 依存な struct stat のままだし、実際のところ中では何をしているのか見ていないんだけど、g_stat() にしたらあっけなく動くようになった。はー。
まあでも、デバッグの途中で別のバグをみつけて、直すことができたのでそれはそれでいいとしよう。
つらい二日間だった…

コメントを残す