RubyのC拡張ライブラリのdSYMを作成

macOS 上で RubyのC拡張ライブラリのパフォーマンスを計測するために、 Xcode 付属の Instruments というアプリを利用してます。以前は特になにもしなくともパフォーマンス計測結果を見るときにソースコードが表示されてどの箇所がパフォーマンスが悪いか表示されていたのですが、年末年始に時間があったので久しぶりに試したらアセンブラコードしか表示されずに読み解くのがとても大変でした。

C拡張ライブラリをインストールするときに、コンパイルしたときに収集したシンボル情報をもとに dSYM を作成したら解決しそうだったので試してみました。

Ruby の mkmf.rb に手を加え、C拡張ライブラリをインストールする際に生成する Makefile に dSYM を作成するためのコマンドを追加しました。

diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 768a152ca7..851261e897 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -2552,6 +2552,7 @@ def create_makefile(target, srcprefix = nil)
       else
         mfile.print "#{f} #{stamp}\n"
         mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} #{dir}\n"
+        mfile.print "\tcp -r #{fseprepl[f]}.dSYM #{dir}\n"
         if defined?($installed_list)
           mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
         end
@@ -2675,6 +2676,7 @@ def create_makefile(target, srcprefix = nil)
         mfile.print "\n\t-$(Q)#{ranlib} $(@)#{$ignore_error}"
       end
     end
+    mfile.print "\tdsymutil $(@)\n"
     mfile.print "\n\n"
     if makedef
       mfile.print "$(DEFFILE): #{origdef}\n"

dsymutil というコマンドを実行すると、ほしかった dSYM が作成されます。

あとはC拡張ライブラリを動かす Ruby スクリプトを実行しながら Instruments でパフォーマンスを計測すると、良い感じにソースコードも表示されるようになりました。