How to stop the Rails debugger for the current request How to stop the Rails debugger for the current request ruby-on-rails ruby-on-rails

How to stop the Rails debugger for the current request


Just put conditions on the debugger statement so that it stops only when you want it to, e.g.:

debugger if animal == 'tiger'

or if, say, you want to examine the code only on loop 384:

animals.each_with_index do |animal, i|  debugger if i == 384  # do somethingend

or put in a variable that will let you continue ad hoc:

continue_debugger = falseanimals.each do |animal|  debugger unless continue_debugger  # in the debugger type `p continue_debugger = true` then `c` when doneend


put your debugger statement somewhere before the iteration, then set a breakpoint inside the iteration which you can then clear later.

Example:

def index  debugger  @things = Thing.all  @things.each do |thing|    # ... something you want to check out in the debugger    thing.some_calculation  endend

When you enter the debugger, set a breakpoint inside:

b app/controllers/things_controller.rb:42

(Where 42 is the line number you want to break at, like thing.some_calculation above. Note that it has to be an executable line of code -- comments, blank lines won't work). The debugger will show a breakpoint number and location:

Breakpoint 1 at .../app/controllers/things_controller.rb:42

Now, every time you continue, you will stop at the breakpoint. When you're done and want to complete the request, delete the breakpoint:

delete 1

continue once more, and you will complete the request!


It looks like in the source of ruby-debug, the call to debugger will always stop execution whenever it is hit. So one solution is to do as was suggested by Mori in his 'ad-hoc' solution, to make a conditional around the call to debugger that you can tweak inside the debugger session itself, such that you avoid calling debugger. This is probably the neatest solution, and what I would do unless you have some strong nagging purity issues with the code involved.

If you really want to only do this without some external conditional and inside the debugger session itself, it is possible. What you have to do is set a breakpoint in the code itself, then you can delete that breakpoint in the debugger when it is triggered:

require 'rubygems'require 'ruby-debug'Debugger.startDebugger.add_breakpoint(__FILE__, __LINE__ + 2)while true do  puts "Hi"  puts "mom"endDebugger.stop

This produces this sort of interaction:

Breakpoint 1 at debug_test.rb:10debug_test.rb:10puts "Hi"(rdb:1) cHimomBreakpoint 1 at debug_test.rb:10debug_test.rb:10puts "Hi"(rdb:1) cHimomBreakpoint 1 at debug_test.rb:10debug_test.rb:10puts "Hi"(rdb:1) info bNum Enb What  1 y   at ./debug_test.rb:10        breakpoint already hit 3 times(rdb:1) del 1(rdb:1) cHimomHimomHimom

...and so on.

In this way, you are setting the breakpoint in code, then deleting it when you are done. Note that any time the line Debugger.add_breakpoint is called, it will re-set the breakpoint, so that's why it is outside of the loop and pointing 2 lines down. This technique can easily be extracted to require-ing a script that sets the breakpoint only when loading your server - Heck, you could write a whole framework class around controlling the Debugger module however you want. Of course, if you went this far, I would just create a singleton class that helps you implement Mori's ad-hoc solution and does or does-not call the debugger statement.