distcc その後の顛末....

どうも「クライアントとサーバ間で通信はできている」しかし「サーバ側でのコンパイルに失敗している」という感じのようです。

によると、distccd では、

  1. DOTI という、いわゆるシリアライズ化(と思われる)されて distcc から送信されてくるソースを受信してコンパイル
  2. コンパイル後は、DOTO という、こちらもいわゆるシリアライズ化(と思われる)形式でバイナリを distcc に返信

という流れのようです。そこで、

distccd_flags="(snip) --verbose"

フラグを付けて詳細なログを取得。すると....

(snip)
Apr 21 17:39:21 xxx distccd[5986]: (dcc_r_token_int) got DOTI00027efd
Apr 21 17:39:21 xxx distccd[5986]: (dcc_r_file) received 163581 bytes to file /tmp/distccd_d3708639.i
Apr 21 17:39:21 xxx distccd[5986]: (dcc_r_file_timed) 163581 bytes received in 0.003290s, rate 48555kB/s
Apr 21 17:39:21 xxx distccd[5986]: (dcc_set_input) changed input from "nkf.c" to "/tmp/distccd_d3708639.i"
Apr 21 17:39:21 xxx distccd[5986]: (dcc_set_input) command after: /usr/bin/gcc -O2 -fno-strict-aliasing -pipe -m32 -march=pentium3m -march=pentium3m -c /tmp/distccd_d3708639.i -o nkf.o
Apr 21 17:39:21 xxx distccd[5986]: (dcc_set_output) changed output from "nkf.o" to "/tmp/distccd_d0fc8639.o"
Apr 21 17:39:21 xxx distccd[5986]: (dcc_set_output) command after: /usr/bin/gcc -O2 -fno-strict-aliasing -pipe -m32 -march=pentium3m -march=pentium3m -c /tmp/distccd_d3708639.i -o /tmp/distccd_d0fc8639.o
Apr 21 17:39:21 xxx distccd[5986]: (dcc_spawn_child) forking to execute: /usr/bin/gcc -O2 -fno-strict-aliasing -pipe -m32 -march=pentium3m -march=pentium3m -c /tmp/distccd_d3708639.i -o /tmp/distccd_d0fc8639.o
Apr 21 17:39:21 xxx distccd[5986]: (dcc_spawn_child) child started as pid7791
Apr 21 17:39:21 xxx distccd[7791]: (dcc_increment_safeguard) setting safeguard: _DISTCC_SAFEGUARD=1
Apr 21 17:39:21 xxx distccd[5986]: (dcc_collect_child) cc child 7791 terminated with status 0x100
(snip)

多分、この部分が当該箇所なのでしょう。

Apr 21 17:39:21 xxx distccd[5986]: (dcc_r_token_int) got DOTI00027efd
Apr 21 17:39:21 xxx distccd[5986]: (dcc_r_file) received 163581 bytes to file /tmp/distccd_d3708639.i

まず、ここで nkf.c のソースを受信。一時ファイル化しているようです。

Apr 21 17:39:21 xxx distccd[5986]: (dcc_set_input) changed input from "nkf.c" to "/tmp/distccd_d3708639.i"
Apr 21 17:39:21 xxx distccd[5986]: (dcc_set_input) command after: /usr/bin/gcc -O2 -fno-strict-aliasing -pipe -m32 -march=pentium3m -march=pentium3m -c /tmp/distccd_d3708639.i -o nkf.o

次に、nkf.c を保存した一時ファイル名に変更。コマンド列の nkf.c も当該ファイル名に置換。出力先である nkf.o についても同様の措置を行なった後、

Apr 21 17:39:21 xxx distccd[5986]: (dcc_spawn_child) forking to execute: /usr/bin/gcc -O2 -fno-strict-aliasing -pipe -m32 -march=pentium3m -march=pentium3m -c /tmp/distccd_d3708639.i -o /tmp/distccd_d0fc8639.o
Apr 21 17:39:21 xxx distccd[5986]: (dcc_spawn_child) child started as pid7791

さぁ、コンパイル!と行きたいところなのですが、

Apr 21 17:39:21 xxx distccd[7791]: (dcc_increment_safeguard) setting safeguard: _DISTCC_SAFEGUARD=1
Apr 21 17:39:21 xxx distccd[5986]: (dcc_collect_child) cc child 7791 terminated with status 0x100

あえなく失敗。思うに、この

/tmp/distccd_d3708639.i

という一時ファイルの中身がおかしいのではないか? と、

export DISTCC_SAVE_TEMPS=1 (or setenv DISTCC_SAVE_TEMPS 1)

で発掘してみると....ビンゴでした。何とバイナリファイルのまま。多分、ここでは、テキストファイルでの nkf.c が再現できていなくてはダメだと思うのですね。

試しに、以下の 7種類の組み合わせで確認してみましたが、すべて同じ結果になりました。

こうなると、distcc 本体の問題だと思われるのですが、linux の方では同様の障害が発生している様子ではありませんので、FreeBSD と distcc の組み合わせの問題、ということになるのでしょう。

であれば、ここからはデバッガで追うことになりますが、そこまで手間を掛けなくとも、package でインストールしておいて、アップデートされたものから順次 ports で少しずつビルド、という手もありますので、今回はここまでにしようと思います(buildworld で使うことができないのはイタいですが)。

ちなみに、どの BSD でも同様ですが、ソースを弄ることを前提にしつつも、バイナリパッケージによる手っ取り早感、というのは、linux のディストリには無い魅力ですね。


[追伸]

一応、7.2 と 7.1 のタグが打たれていますが、最終更新が 7.1 のリリース前、昨年の 8月ですからね。仮に 7.0 まで動いていたとしても、7.1 以降で動作する、ということにはなりませんね。この問題が解決できないから 8ヶ月も放置されている、と邪推していますが、FreeBSD では distcc の需要って、あんまり無いんでしょうか?