Docker上のEmacsのビルドでハマった話
Docker上でEmacsをビルドしようとしてハマったので対処方法と、ついでに簡単に調査したメモです。
現象
環境は次のような感じでした。
まず、確認用に次のDockerfileを用意します。なお、centos:7
としても現象は同じでした(ただし、yumのインストール対象にmakeを追加する必要があります)。
FROM centos:6 ARG emacs=emacs-24.5 RUN yum install -y gcc lcurses-devel wget ncurses-devel ARG work_dir=/tmp/setup RUN mkdir ${work_dir} RUN cd ${work_dir} && \ wget http://mirror.jre655.com/GNU/emacs/${emacs}.tar.gz && \ tar zxf ${emacs}.tar.gz && \ cd ${emacs} && \ ./configure --without-x && \ make
これをビルドしてみると・・・
$ docker build --no-cache -t test-emacs-build . ~略~ Finding pointers to doc strings... Finding pointers to doc strings...done Dumping under the name emacs ************************************************** Warning: Your system has a gap between BSS and the heap (22442648 bytes). This usually means that exec-shield or something similar is in effect. The dump may fail because of this. See the section about exec-shield in etc/PROBLEMS for more information. ************************************************** /bin/sh: line 7: 5952 Segmentation fault (core dumped) ./temacs --batch --load loadup bootstrap make[1]: *** [bootstrap-emacs] Error 1 make[1]: Leaving directory `/tmp/setup/emacs-24.5/src' make: *** [src] Error 2
makeで死にます。
対処方法その1
とりあえず、メッセージに従ってetc/PROBLEMS
(テキストファイル)でexec-shield
を検索してみます。見てみると、Linuxのセキュリティ機構であるExec-shield
(プロセスのメモリ配置のランダム化?)が問題のようです。
解決方法だけ抜粋すると、下記の通りです。
echo 0 > /proc/sys/kernel/exec-shield echo 0 > /proc/sys/kernel/randomize_va_space
ということで以下のようにして、「ホスト側で」一時的にrandomize_va_space
を無効化してからdocker build
すればOKです(exec-shield
の方は無関係でした)。
$ cat /proc/sys/kernel/randomize_va_space 2 $ sudo bash -c "echo 0 > /proc/sys/kernel/randomize_va_space" $ docker build --no-cache -t test-emacs-build .
emacsのビルド部分が通った後はrandomize_va_space
を元に戻して問題ありませんでした。といっても、Emacsのビルド部分を通るたびにこれが必要なのは何かと不便そうです。
少し調査
randomize_va_space
というキーワードが手に入ったのでGoogle先生に聞いてみると、次のissueが引っ掛かりました。
Ubuntu 16.04: Dockerfile cannot build emacs · Issue #22801 · docker/docker · GitHub
これはDocker側のissueですが、ここからEmacs側のスレッド(同じ人?)にもリンクが張られています。
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=23529
で、斜め読みしかしていないのですが、Emacsのスレッドで示されている下記コードのpersonality
というsyscallが問題になっているようです。これで、一時的にrandomize_va_space
に0をセットするのに相当する操作をしているようですが、これがDockerのゲスト上ではうまく働かない(ホスト側を変更する必要があるのにそれができない)ということだと思います。
https://github.com/emacs-mirror/emacs/blob/master/src/emacs.c#L802-819
結局のところ、Docker側がpersonality
が動作するようなオプションを入れるかEmacs側がこの動作を修正するかですが、前者はDockerのポリシー的におそらく難しく、後者は望ましいが技術的に難しいという話になっているようです(斜め読みなので違ったらすみません)。
対処方法その2
最新版の利用や細かいバージョンの指定ができないのは残念ですが、この辺りの融通が効くのであれば大人しくRPM使っとけというのが多くの場合正しいでしょう。
個人的には24系が入ればそれで良かったので、CentOS6系であれば、「centos6.5にemacs24.5をrpmからインストールする | joppot」を参考に以下のようにすればOKでした。なお、CentOS7系であれば単にyum install
するだけで24系のEmacsが入るはずです。
FROM centos:6 RUN yum install -y gcc lcurses-devel wget ncurses-devel gpm-libs alsa-lib perl gnutls-devel RUN cd /etc/yum.repos.d && \ wget https://gist.githubusercontent.com/AaronTheApe/5540012/raw/5782a8d6a95f76daeed6073dc0c90612fefe2fb3/emacs.repo && \ yum --disablerepo="*" --enablerepo="emacs" --nogpgcheck -y install emacs-nox
追記(2016/08/11)
今現在は/proc/sys/kernel/randomize_va_space
が2でも、上記の問題は起きず問題なくビルドできています。
Emacsの描画崩れの問題でDocker側を1.11にアップデートしたのですが(参考:「Dockerを1.10から1.11へアップデート on CentOS7 - eshamster’s diary」)、その影響でしょうか?ただ、上記のissueの時点では1.11.1や当時のmaster(1.12)でも再現しているようですが…。続報もないので(また、改めて1.10に戻して試す気もないので)結局良く分からないです。
一応バージョンはissueの時点よりも少し進んで、1.11.2だという差はあります。
$ docker --version Docker version 1.11.2-cs3, build c81a77d