この前Cygwinにgit-1.8.3をインストールしましたが、 ちゃんと動かない所があったので その対処法について。
error: cannot fork()
gitをインストールしてざっと動かして大丈夫そうだと思ってたんですが、 ちゃんと使おうと思って色々動かしてたら色々問題があってちゃんと動いてませんでした。
あまり使わないのでちょっと放っておいたんですが、vimで新しい プラグインをneobundleでインストールする時に問題があるので、 ちゃんと対処しようかと。
問題としては、新しくレポジトリをcloneしようとする時、 1回目はcloneしようとするローカルのディレクトリの親ディレクトリまで 作って失敗し、2回めに成功したりしなかったり。
git pushなんかでもなんかエラーが出ます。
失敗する時のエラーを見ると
$ git push
10 [main] git 5476 child_info_fork::abort: C:\cygwin\home\USER\usr\local\bin\cygintl-8.dll: Loaded to different address: parent(0x300000) != child(0x330000)
error: cannot fork() for git-rebase: Resource temporarily unavailable
こんな感じ。
Cygwin error fork辺りで調べてみるとrebaseallすれば良い、と言うのが
見つかったので試して見ることに。
rebaseall
まず、rebase.exe及びrebaseallが/bin/にあることを確認します。
また、rebaseを走らせるのに必要なので
/bin/ash.exeまたは/bin/dash.exeがあることを確認します。
(実は今回の件では必要なかったわけですが同じような事が起こった時様に
入れておいた方が良いです。)
これらのインストールはsetup.exeを使うかapt-cygで。
インストールしたら、一度Cygwin関連で走っているものをすべて切ります。
$ cygrunsrv -L
などとしてサービス登録されているものを探して、もしあれば
$ cygrunsrv -E <svc_name>
$ cygrunsrv -R <svc_name>
などとして一度外しておきます。 後で
$ cygrunsrv -I <svc_name>
$ cygrunsrv -S <svc_name>
しなおしてください。
さらに、現在走っているcygwin関連のジョブを探して
$ tasklist /M cygwin1.dll
などとしてXサーバーなど走っていれば一度落とします。 (minttyやbashだけの状態に。) ひと通り落としたら一度cygwin自体から一度ログアウトします。
ExplorerでC:\cygwin\bin(もしくはcygwinをインストールしたディレクトリ\bin)
へ行き、ash.exeまたはdash.exeをダブルクリックで起動します。
プロンプトが出てくるので、
$ cd /bin
$ ./rebaseall
として、rebaseallを実行します。
rebaseall: only ash or dash processes are allowed during rebasing
Exit all Cygwin processes and stop all Cygwin services.
Execute ash (or dash) from Start/Run... or a cmd or command window.
Execute '/bin/rebaseall' from ash (or dash).
等と出たらまだ他にcygwinのプロセスとして走っているものが居る可能性があります。(サービスなどを再チェック)
これでいくつか見つからないファイルには適用できないよ、的な メッセージが出るかもしれませんが、取り敢えずOKです。
ということで、gitを使ってみると、以前と同じエラーがでました。
それはそのはずで、今回インストールしたgitは自分で~/usr/local
にインストールしていましたが、
rebaseallはcygwinの管理システム、setup.exeやapt-cygなど、で
管理されているものを探してrebase.exeを適用しているだけなので、
別途インストールしたものには適用されません。
(/bin/rebaseallはシェルスクリプトなので見れば何やってるか分かります。)
~/usr/localへrebase.exeを適用する
rebaseallを参考に~/usr/localにあるファイルに対してrebase.exeを適用します。
今度はCygwinでbashのまま直接rebase.exeを走らせます。
$ cd ~/usr/local/lib
$ find . -name \*dll > rebase.lst
$ find . -name \*so >> rebase.lst
$ rebase.exe -n -s -4 -T ./rebase.lst
$ rm -f rebase.lst
こんな感じで~/usr/local/lib/にあるライブラリをリストアップし、
rebase.exeを適用。
Cygwinを立ち上げている状態なので、
いくつかCygwinのコアなライブラリを変更できない、とでますが
無視してOKです。
(もし、上で一度もrebaseallをcygwinの外からやらず、これだけで
エラーが出る場合は一度外でrebaseallをやる必要があるかもしれません。)
これで、gitを実行すると問題なく動く様になりました。
今回は~/usr/localにインストールしたものについてですが、
/usr/ディレクトリなどにインストールした場合も、
setup.exeやapt-cygなどのCygwinの管理システムから
外れた方法でインストールした場合には
rebaseallで見つけてくれないので自分で見つけて
rebase.exeをかける必要があります。
大概の場合は上の~/usr/local/libの部分を/usr/lib、/usr/local/lib
と置き換えてrebase.exeを適用してあげれば大丈夫だと思います。
DefaultBaseAddress=0x40000000 ?
色々探しているうちに、rebaseallをしたら元から入ってるvimもおかしくなって
しまった、といった話を見つけました。
Ref:
Cygwin - Elegant Cat Wiki
今のところ問題は起きてないのですが、 一応同じ様な問題が起こった時用にメモ。