LoginSignup
4
0
お題は不問!Qiita Engineer Festa 2023で記事投稿!

debug.gemで2回目以降にブレイクポイントで処理が止まらない

Posted at

こちらの記事で繰り返し同じデバッグを行うために、 binding.b に引数を渡す方法を説明しました。

これを Controllerで実行しようとしたときに、

users_controller.rb
  # GET /users/1
  def show
+    binding.b(do: 'i ;; b @user.hoge')
+
+    @user.hoge

    render json: @user
  end

初回はきちんと以下のように User#hoge にブレイクポイントが設置できたのですが、

Started GET "/users/1" for ::1 at 2023-07-07 20:59:15 +0900
Processing by UsersController#show as HTML
  Parameters: {"id"=>"1"}
  User Load (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/users_controller.rb:48:in `set_user'
[8, 17] in ~/git/sample-app/app/controllers/users_controller.rb
     8|     render json: @users
     9|   end
    10|
    11|   # GET /users/1
    12|   def show
=>  13|     binding.b(do: 'i ;; b @user.hoge')
    14|
    15|     @user.hoge
    16|
    17|     render json: @user
=>#0    UsersController#show at ~/git/sample-app/app/controllers/users_controller.rb:13
  #1    ActionController::BasicImplicitRender#send_action(method="show", args=[]) at ~/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/actionpack-7.0.5/lib/action_controller/metal/basic_implicit_render.rb:6
  # and 57 frames (use `bt' command for all frames)
(rdbg:#debugger) i
%self = #<UsersController:0x00000000014aa0>
@_action_name = "show"
@_lookup_context = #<ActionView::LookupContext:0x0000000111bbc5d0 @details_key=nil, @digest_cache=nil, @cache=true, @prefixes=["users", "application"], @details={:locale=>[:en], :formats=>[:html], :va...>
@_params = #<ActionController::Parameters {"controller"=>"users", "action"=>"show", "id"=>"1"} permitted: false>
@_request = #<ActionDispatch::Request GET "http://localhost:3000/users/1" for ::1>
@_response = #<ActionDispatch::Response:0x0000000111df4438 @mon_data=#<Monitor:0x000000010795e680>, @mon_data_owner_object_id=36520, @header={"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"0", ...>
@_response_body = nil
@_routes = nil
@user = #<User:0x000000010641ea40 id: 1, name: "user1", created_at: Mon, 12 Jun 2023 00:36:48.844679000 UTC +00:00, updated_at: Mon, 12 Jun 2023 00:36:48.844679000 UTC +00:00, admin: false>
(rdbg:#debugger) b @user.hoge
#0  BP - Method  @user.hoge at /Users/kyntk/git/sample-app/app/models/user.rb:6
[1, 8] in ~/git/sample-app/app/models/user.rb
     1| class User < ApplicationRecord
     2|   validates :name, presence: true, uniqueness: true
     3|   has_many :articles, dependent: :destroy
     4|
     5|   def hoge
=>   6|     puts 'fuga'
     7|   end
     8| end
=>#0    User#hoge at ~/git/sample-app/app/models/user.rb:6
  #1    UsersController#show at ~/git/sample-app/app/controllers/users_controller.rb:15
  # and 58 frames (use `bt' command for all frames)

Stop by #0  BP - Method  @user.hoge at /Users/kyntk/git/sample-app/app/models/user.rb:6
(rdbg)

2回目に実行してもブレイクポイントが刺さらないということが置きました。

解決方法

  • 1. ブレイクポイントを設置する前に、ブレイクポイントを削除する
  • 2. b User#hoge のようにブレイクポイントを設置する

解説

2回目以降でブレイクポイントが刺さらなかった時に以下のようなメッセージが出力されていました。

duplicated breakpoint:  BP - Method  user.hoge at /Users/kyntk/git/sample-app/app/models/user.rb:6

ブレイクポイントを設置したいファイル、行数に対してはすでにブレイクポイントが設置されているようです。
しかし、同じ場所であっても、インスタンス user が異なるためブレイクポイントで処理が停止しないようです。

1. ブレイクポイントを設置する前に、ブレイクポイントを削除する

そのため、ブレイクポイントを設置する前に、前回のものを削除してあげると毎回刺さるようになりました。

users_controller.rb
  # GET /users/1
  def show
-    binding.b(do: 'i ;; b @user.hoge')
+    binding.b(do: 'del 0 ;; i ;; b @user.hoge')

    @user.hoge

    render json: @user
  end

今回は0番目のブレイクポイントしか削除していないですが、、binding.b(do: "del ;; i ;; b @user.hoge")のようにdelの引数を指定しないと、全てのブレイクポイントを削除することができます。

2. b User#hoge のようにブレイクポイントを設置する

ブレイクポイントは @user.hoge のような記法以外にも、行数を渡したり、User#hoge のように記述する方法もあります。

* `b[reak] <line>`
  * Set breakpoint on `<line>` at the current frame's file.
* `b[reak] <file>:<line>` or `<file> <line>`
  * Set breakpoint on `<file>:<line>`.
* `b[reak] <class>#<name>`
   * Set breakpoint on the method `<class>#<name>`.
* `b[reak] <expr>.<name>`
   * Set breakpoint on the method `<expr>.<name>`.

これを用いることで、2回目以降のブレイクポイントの設置は同じく duplicated のメッセージが表示されるものの、ブレイクポイントで止まってくれるようになりました。

users_controller.rb
  # GET /users/1
  def show
-    binding.b(do: 'i ;; b @user.hoge')
+    binding.b(do: 'i ;; b User#hoge')

    @user.hoge

    render json: @user
  end
4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0