昨日はerlangについて調べてみた結果を書いたけど、今日はソースをぼちぼちとみてみた。
ソース少し読んでみたが、ちまたで言われるerlangの並列性の本質が知りたくなったので本格的に調べてみることにした。
そもそも、Elixirを勉強するはずだったのになんでこんなことをしているんだろう。もはやElixirなど何も関係なくなってしまっている・・・
環境構築
オープンソースのコードをまじまじとデバッグしたことはないんだけど、今回は気合をいれて環境構築から頑張ってみるとする。
というのも、ertsのソースをエディタで開いて読んでいたけど条件コンパイルでどっちが有効になっているのか分からなくて辛いと感じるところが結構あった。#if __WIN32__ 的なのはよくある話だけど、erlangの場合はSMP関係の状態によってビルド時に動作を切り替えているところが結構ある。コードを普通に読んでいるだけではどうもイメージがつかめない。
リーディングの効率をあげるのと「Erlangがステップ実行できたら素敵やん」ということでEclipseでデバッグ環境を作ってみた。
erlangはどのように動いているのか?
普通にerlangを使う場合はerlコマンドでシェルを起動することが一般的だ。
erlは何をしているかというと、実はただのシェルスクリプトでerlangを動かすのに必要になる環境変数とかを準備している。
$ which erl /usr/local/bin/erl $ cat /usr/local/bin/erl #!/bin/sh # # %CopyrightBegin% # # Copyright Ericsson AB 1996-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # %CopyrightEnd% # ROOTDIR="/usr/local/lib/erlang" BINDIR=$ROOTDIR/erts-9.1/bin EMU=beam PROGNAME=`echo $0 | sed 's/.*\///'` export EMU export ROOTDIR export BINDIR export PROGNAME exec "$BINDIR/erlexec" ${1+"$@"}
準備ができたらインストールされている erlexec というモジュールを起動している。
erlexecは
/usr/local/lib/erlang/erts-9.1/bin
にインストールされている。
eclipseでビルドしたモジュールは
/bin/x86_64-unknown-linux-gnu 以下に出来上がっている。
ということでデバッグerlangをデバッグしたい場合は環境変数を整えた上でこの erlexec をデバッグすればよいことが分かる。
erlのエントリポイントはどこか?
erlは実質的にはerlexecから始まるわけだが、ソースファイルでいうと
erts/etc/common/erlexec.c
から始まる。
ステップ実行しようとしたらプログラムカウンタがあちこち飛ぶ。
最適化の影響だろうとMakefileの該当箇所を探してみたら
make/x86_64-unknown-linux-gnu/otp.mk
make/x86_64-unknown-linux-gnu/otp_ded.mk
の2つがmakeするときに適用されているようだ。これらは./configure時に生成されるファイルだが、erts/configure にある CFLAGS="-O2" が反映されているようだ。
-O2 としているのに -g がついている・・・
「それでも僕はデバッグする」
という覚悟が感じられるオプションだ。
*1
というわけで -O0とさせて頂いた上で再度ビルド&デバッグ。
無事プログラムカウンタが踊らなくなったのを見届けたので今日はもう寝る。