Techioz Blog

lldb を使用して Macbook で Rails アプリケーションをデバッグするにはどうすればよいですか?

概要

私は大規模なヤク剃りの真っ最中で、私の Mac で Rails アプリケーションが次のエラーでクラッシュする理由を解明しようとしています。

$rails s -e production
=> Booting WEBrick
=> Rails 6.1.6.1 application starting in production http://0.0.0.0:3000
=> Run `bin/rails server --help` for more startup options
ruby(18016,0x202c48240) malloc: double free for ptr 0x7fe670963a00
ruby(18016,0x202c48240) malloc: *** set a breakpoint in malloc_error_break to debug

インターネット上の提案の 1 つは、デバッガー (lldb または gdb) を使用してこれをデバッグすることです。 lldb を「実行中のプロセス」にアタッチすると、次のようなエラーが発生します。

$lldb --attach-pid 18016
(lldb) process attach --pid 18016
error: attach failed: tried to attach to process already being debugged
(lldb)
error: attach failed: debugserver is x86_64 binary running in translation, attach failed.

これは、Rosetta2 変換層を使用して実行されているプロセスに lldb を接続できないことを示しているようです。また、アプリは Ruby-oci8 gem を使用しており、ruby-oci8 gem に必要な基盤となる Oracle クライアント ライブラリの arm64 バージョンがないため、Rosetta2 でアプリを実行する必要があります。

したがって、次の試みは、lldb でプロセス自体を起動してみることです。これを試してみます:

$lldb --arch x86_64 `asdf which rails` s -- -e production
(lldb) target create --arch=x86_64 "/Users/rohith/.asdf/installs/ruby/3.0.1/bin/rails"
error: '/Users/rohith/.asdf/installs/ruby/3.0.1/bin/rails' doesn't contain the architecture x86_64

lldb は Rails を直接起動しようとしていると述べていますが、これはバイナリではなく Ruby ファイルです。したがって、理想的には、lldb に Ruby を起動させ、Rails を起動させたいと考えています。

これらの問題を解決する方法について何かアイデアはありますか?

更新 1: lldb を使用して Ruby をデバッグできます

lldb --arch x86_64 `asdf which ruby`
(lldb) target create --arch=x86_64 "/Users/rohith/.asdf/installs/ruby/3.0.1/bin/ruby"
Current executable set to '/Users/rohith/.asdf/installs/ruby/3.0.1/bin/ruby' (x86_64).

ここで必要なのは、直接ではなく Ruby 経由で Rails を起動する方法だけです。

解決策

答えはとても簡単だったので、自分自身を蹴りたいです

$lldb --arch x86_64 `asdf which ruby` `asdf which rails` -- s -e production
(lldb) target create --arch=x86_64 "/Users/rohith/.asdf/installs/ruby/3.0.1/bin/ruby"
Current executable set to '/Users/rohith/.asdf/installs/ruby/3.0.1/bin/ruby' (x86_64).
(lldb) settings set -- target.run-args  "/Users/rohith/.asdf/installs/ruby/3.0.1/bin/rails" "s" "-e" "production"

必要なのは、ruby を呼び出して、引数の 1 つとして Rails を渡すことだけでした。ヒントは、rails ファイルを開いたとき、ファイルの先頭に次のような記述があったことです。

#!/usr/bin/env ruby

したがって、rails を呼び出すことは、ruby に Rails Ruby ファイルを実行させることと同じです。