从生产 irb 调试方法

Debug into method from production irb

当我查找问题时,例如针对特定的 ActiveRecord 对象,我经常发现自己在我的生产系统上执行以下操作:

# RAILS_ENV=production bundle exec

irb(main)> article = Article.find(123)
=> #<Article id: 123, title: "Foobar">
irb(main)> article.do_something(3)
NoMethodError: undefined method `id' for nil:NilClass

有时无法重现,为什么article.do_something(3)行会报错,所以我想直接在我的服务器上,在生产模式下调试。

现在的问题是:如何在对象/实例 article 上使用参数 3 进入方法 #do_something

当然,可以在该方法中设置一个断点,重新加载生产并让他们所有的客户在该断点上等待,直到我完成调试...但这不是最好的主意。

So, is there a way to debug into a method of a specific instance from a running irb / pry session? (both would be ok)

您可以使用 pry-debugger(通过 ruby 1.9.3)或 pry-byebug(Ruby >= 2)。

这两个都允许您设置断点,允许您在代码运行时以交互方式单步执行代码,检查变量值、方法 return 值等。

我不太确定您将如何使用生产数据来管理它,但这将允许您调试特定方法。

在尝试和更多谷歌搜索之后,我想我找到了适合我的解决方案。

  1. 登录到您的 rails 控制台/irb/pry 会话
  2. 设置您的案例(例如加载您的模型、需要依赖项...),以便您可以在一行中执行要调试的代码
  3. require 'byebug'(或 require 'debugger' 旧 ruby 版本)
  4. 现在是有趣的部分:像这样 binding.pry; user.do_somethingdebugger; user.do_something
  5. 将调试器语句放在要调试的行前面
  6. 现在您在调试器中。也许您必须使用 next 跳转到下一行(如果您启用了快捷方式,则只需 n )以进入您的方法。

这是我们生产系统中的一个完整示例:

[1] pry(main)> require 'byebug'
=> true
[2] pry(main)> user = User.find(2)
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
=> #<User id: 2, name="XXX XXX">
[3] pry(main)> user.full_name
NameError: undefined local variable or method address for #<User:0x0055b168663590>

[4] pry(main)> binding.pry; user.full_name

[68, 73] in /usr/src/app/app/models/user.rb
   68:   end
   69: 
   70:   def full_name
=> 71:     "#{address.firstname} #{address.last_name}"
   72:   end
   73: end
(byebug)