dockerでrubyの開発環境を用意してgdbでcodeを追う

rubyソースコードを読もうとしたが、自分が使っているNote PCはMacで、個人的にはLinux環境でやりたい。 またcodeを読むに当たり、gdbでゴニョゴニョしながら動きを追いたい。

そこで、dockerでrubyの開発環境を用意し、gdbを使ってコードを追うことにしたが、そのための環境の作り方について自分用にまとめておく。

docker環境を頂く

ささださんが用意してくれているものを、ありがたく使わせて頂く🙏

github.com

Note: docker 環境(Ubuntu 18.04 base)を作ってみました。 docker pull koichisasada/rhc で試してみてください。su rubydev でアカウントを rubydev でご利用ください。

docker-compose.ymlにoptionを固める

動作に必要なoptionをdocker-compose.ymlに書いておき、docker-compose upで立ち上がるようにしておきたい。 自分はこんな感じにしている。

version: '3'
services:
  rhc:
    image: "koichisasada/rhc"
    volumes:
      - ./workspace:/home/rubydev/workdir
    tty: true
    cap_add:
      - SYS_PTRACE
    security_opt:
      - seccomp:unconfined

volumesについて

コードやbuildしたものは永続化しておきたいので、volumes で手元(host)側の作業ディレクトリをcontainerにmountしておく。./workspace にはrubyソースコードがgitからcloneされたりすることを想定。container内でbuildしたり実行したりするが、fileの編集はhost側のeditorで行う。

cap_add、security_optについて

これらはコンテナ内でgdbを使うためのもの。無いと、gdbを起動した際にOperation not permitted などと怒られる。 gdbはptrace(2)システムコールを利用しているため、ケーパビリティにSYS_PTRACEを追加して許可を与える。 またsecurity_optではseccomp = secure computing modeをunconfinedにしているが、これによりseccompによる制限が無効化され、ptraceが使えるようになる。

起動

ふつうにdocker-compose up し、docker exec -it rhc_rhc_1 bash などと実行してcontainerに入り、su - rubydev でrubydevユーザになっていろいろやる。

あとは読んだりいじったりするだけ

ディレクトリ構造、ビルド方法などは、とても丁寧にRubyHackChallengeのコンテンツに書いてある。

rubyhackchallenge/2_mri_structure.md at master · ko1/rubyhackchallenge · GitHub

gdbデバッグしつつコードを追うには、上記コンテンツでconfigureを実施するときに、最適化無効のためのoptflags="-O0" オプションをつける。

$ ../ruby/configure optflags="-O0" --prefix=$PWD/../install --enable-shared 

あとはRubyHackChallengeの内容に従ってbuildし、出来たrubygdbで動かしてやればよい。 ↓がとても参考になるので読みながらやる。 techlife.cookpad.com