simotin13's message

simotin13といいます。記事の内容でご質問やご意見がありましたらお気軽にコメントしてください\^o^/

Elixir入門 ~12日目 eclipseでerlangのデバッグ環境を作る~

昨日はerlangについて調べてみた結果を書いたけど、今日はソースをぼちぼちとみてみた。

mcommit.hatenadiary.com

ソース少し読んでみたが、ちまたで言われるerlangの並列性の本質が知りたくなったので本格的に調べてみることにした。
そもそも、Elixirを勉強するはずだったのになんでこんなことをしているんだろう。もはやElixirなど何も関係なくなってしまっている・・・

注意

タイトルに書いたerlangデバッグ環境というのはerlangの処理系、つまりertsのデバッグ環境をさしています。
.erlで書いたerlangのコードのデバッグ環境のことではありません。

環境構築

オープンソースのコードをまじまじとデバッグしたことはないんだけど、今回は気合をいれて環境構築から頑張ってみるとする。

というのも、ertsのソースをエディタで開いて読んでいたけど条件コンパイルでどっちが有効になっているのか分からなくて辛いと感じるところが結構あった。#if __WIN32__ 的なのはよくある話だけど、erlangの場合はSMP関係の状態によってビルド時に動作を切り替えているところが結構ある。コードを普通に読んでいるだけではどうもイメージがつかめない。

リーディングの効率をあげるのと「Erlangステップ実行できたら素敵やん」ということでEclipseデバッグ環境を作ってみた。

前提

eclipseの開発環境(C/C++)は既に構築済みとする。C/C++の環境構築自体はそんなに難しくない。

自分の場合はLinux上でNEONを使っているので、

www.eclipse.org

からCDTを含む一式をダウンロードして展開している。JREも忘れずに入れる。

ソース取得とプロジェクトの作成

workspaceフォルダがeclipseワークスペースとする。

ワークスペースに取り込む前に ./configure でMakefileの生成まではやっておく。

$ cd workspace
$ wget http://erlang.org/download/otp_src_20.1.tar.gz
$ tar xfv otp_src_20.1.tar.gz
$ cd otp_src_20.1
$ ./configure

プロジェクトの取り込み・erlangのビルド

Project Exprolerから"New"→"Project"→"Makefile Project with Existing Code"を選択する。

f:id:simotin13:20171023235322p:plain


プロジェクト名と展開したソースディレクトリを指定すれば(otp_src_20.1)問題なく取り込める。

f:id:simotin13:20171023235436p:plain


"Build Project"でerlangコンパイルされる。※もちろんビルドに必要なライブラリ類は事前に入れておく必要がある。

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とさせて頂いた上で再度ビルド&デバッグ


無事プログラムカウンタが踊らなくなったのを見届けたので今日はもう寝る。

*1:2018-02-24 追記 オープンソースではどれも -O2になっている。./configure用のテンプレートとかツールがそうなっているのかな。