Debugging with pry-byebug: moving in the stack frame
It is a truth universally acknowledged that a single developer in possession of a good codebase must be in want of a bug-free application 1.
Alas, debugging never ends. The more you learn, the more debugging becomes complex.
I think it is high time we dive deeper into
pry-byebug. Are you new to
pry-byebug? Go and check the beginners introduction to debugging your code first.
Here our menu du jour: moving in the stack frame, adding breakpoints on the fly, and some handy shortcuts (because who loves to write
Step into the stack frame:
step only recently. One easy way to understand
step is to explain it in contrast to
next executes the next line in your current context.
step steps into the specific context - the frame - of the next line in your code.
The following example is a basic endpoint that allows me to get all available books and a
Book model with a class method.
The breakpoint will pause execution before
.available and open a debugging console.
When I type
next, the result of
Book.available is assigned to
available_books and the execution stops before the next line.
What happened in
Book.available? I don’t know. I only executed that line of code and stayed in my current frame -
Let’s re-run my code and use
step takes me from my
BooksController to my
Book model. I’ve changed frames. I’m now exploring the class method
I can now check whether my class method works as intended.
step is a bit of a rabbit hole. It’s a great way to explore how Rails works. For instance, if I type
where(available: true), my console returns:
Yep, I’m now checking out ActiveRecord’s inner gut.
Move up the stack frame:
Remember when we dived into the frames? Well, how do I come back to my
up, of course.
If I type
up in my console, I’ll move up the frames towards my initial breakpoint.
What if I’ve moved down frames several times? I can either pass the number of frames I’d like to go up as an argument -
up(2) - or type
up several times.
Add and remove breakpoints on the fly
1) Add a breakpoint from the console:
If I realize, once I’m in my debugging console, that I would have needed another breakpoint, I can add it on the fly with
I can type
break 06, resume the execution, and have it paused before the
A few things to consider:
Breakpoint 1: /path/controllers/books_controller.rb @ 06 (Enabled)gives me my new breakpoint reference number:
1. This will come handly later.
- What appears after
Breakpoint 1 ...is part of my breakpoint’s information. Not where my program is currently paused.
Adding breakpoint son the fly makes for a pretty seamless debugging experience. I used to exit the
pry session, go back to my code, add a new breakpoint, then re-run execution. Let me tell you,
break 06 came as a relief!
2) Remove a breakpoint from the console:
break --delete breakpoint_number or
break -D breakpoint_number
So, now my program is paused before the line 04, and I know I added a second breakpoint on the line 06:
What if I want to remove this second breakpoint?
First, I want to find my breakpoint’s reference by listing all breakpoints with
break. Then, I can delete the breakpoint with
break --delete breakpoint_number.
break outputs the list of all the breakpoints added in the console.
break --delete breakpoint_number outputs the list of all remaining breakpoints.
3) Show breakpoints information:
break --show breakpoint_number
This is the same output that the one I get after adding a breakpoint.
Check your latest commands:
history gives me a list of all past commands I ran during the current
Commands and aliases
Finally, here’s a handy table with some commands and their aliases.
||prints out your current context|
||continue program execution|
||execute the next line in the current stack frame|
||step execution into the next line|
||delete a breakpoint|
||show a breakpoints details and source|
There’s only one thing left to say: Happy debugging!
Noticed something? Ping me on Twitter or create an issue on GitHub.
Sorry, just re-read for the umpteenth time Pride and Prejudice. ↩