Notes: 02. Work with Breakpoints
The student materials have been reviewed and are updated as of SEPTEMBER 2022.
Visual Studio code offers us with a great in-built debugger that helps us debug our Flutter apps. One of this tool is the “Breakpoint.” When code is executed, they run pretty fast. If there is an error we’re are trying to fix, thinking at the same speed of a program’s execution would be impossible. And that’s where breakpoints comes in.
A breakpoint is just a tool that helps you execute your code in a step by step manner with you the user having full control to step through the code execution. As its name suggests, it simply breaks the execution of the program at a selected point so that you can control your code to execute as slow as a human thinks.
With this, we can track changes to variables and see how our code executes which could be helpful in finding a bug.
For this episode, we’ll be working with the starter app that is generated when you create a new Flutter application. It is a simple counter app that increaments a counter variable when a button is pressed. I’ve cleared out all the comments in this file and added a method called displayMessage which prints a message to the console. I also added a print statement in the build method that displays the current counter value in the debug console.
I’ve got the app up and running in debug mode. You do this by hitting the F5 key. Notice the debug toolbar over here. It appears whenever a debug session starts. It has some buttons which we would be working with shorthly.
Once your app is up and running, go ahead and hit the FAB. And you can see, the counter increments accordingly. To make this execute step by step, let’s add a breakpoint.
You can add a breakpoint by clicking on the editor margin of the current line you want to add a breakpoint to. Let’s add that to the first line of the incrementCounter method.
This adds a red symbol to that line to show it has a breakpoint. This can also be done by hitting the F9 key which toggles the breakpoint. With this, our code would break whenever it gets to that point of execution. I’ll do a hot restart to set the counter back to zero. Then I’ll hit the button.
You can see that execution stops at the point we set our breakpoint. If you look at the app screen, you’ll see that the value of counter is still zero. To continue the app’s execution, hit the continue button on the debug toolbar.
And the code execution continues and the counter is incremented on the screen. But that’s not really useful, right? Okay, let’s see what other buttons can do. Do a hot restart to set the counter to its initial value which is zero.
Press Ctrl + shift + Y on windows or Cmd + Shift + Y on mac to open up the debug console.
You can see that the counter value is printed in the debug console.
Now hit the button once more. The code stops at the breakpoint as expected. This time around, we want to navigate the code execution step by step. We can click on the step over button to step over the call to setState. This executes the setState function and goes to the next statement.
So if i click it over here. So with the step over button, you dont need to enter into the setState function. It is used when you dont want to track the internal execution of the function step by step but just want to run it and move on to the next statement.
Next, to enter into the displayMessage method, click the step into button. And this takes you into the method. You can see that the code is executing step by step. So if there was an error in the previouse line, you’ll see it print to the console.
To execute the contents of the displayMessage method and step out of it, you click on the step out button. This takes you out of the method and goes to the next point of execution. In this case, that would be the end of the incrementCounter method.
The displayMessage method has completed its execution and the value is printed out to the console. Let’s keep stepping into our code. This takes us to the next execution point which is the build method. And this is so because the setState method, triggers a widget rebuild which in turn draws the new value to the screen.
You can see on the console that the value of the counter varieble is equals to 1. But our UI still displays the zero as the counter value. This happens because the build method has not completed execution.
Let’s keep stepping over the execution. As you can see, Flutter is going through the build method to process and it in turn would know the part to update.
Now we’re back at the Scaffold and this is what the build method returns. Notice that the value of counter on the screen is still zero. I’ll go ahead and step over the code once more. And you can see the value is updated to one. This is because the build method has been completed and Flutter has redrawn the new counter value to the screen.
You can see this gives you a sense of how Flutter executes code and checks which part of the UI needs to be updated. We can also edit a breakpoint to only trigger based on a given expression. Lets go to the breakpoint. Right click on it and select “Edit Breakpoint.” Enter the following expression:
_counter == 5
Hit the enter or the return key. This breakpoint would only trigger when the counter is equal to 5. Do a “Hot Restart.” Keep hitting the increment button until the counter becomes 5. You can see that the breakpoint hasn’t tirggered. Since the counter value is now 5, I’ll hit it once more. You can see this breakpoint only triggers when the expression returns true.
A good example of using this could be when you want a breakpoint to only trigger when lets say an api returns an empty List instead of a populated List. You might want to debug your code only when this condition is met.
Finally, you can disable breakpoints. To disable an individual breakpoint, right click on it then select “Disable Breakpoint.” You can see the breakpoint turns grey. To enable it, right click on it once more and select “Enable Breakpoint.” And it turns back to red.
We can also do this from the Debug side bar. I’ll fold all the other panes to give more room. In here we have the “Breakpoints” section which shows a list of the breakpoints in the project. We can set a breakpoint to trigger on “All Exceptions.” Or for only “Uncaught Exceptions” and this is the default behaviour.
Next, we can see the breakpoint which we added the line number. Unchecking it disables the breakpoint and you can see it turns grey. Checking it enables it once again. And it is back to red.
We can also deactivate all breakpoints by hovering on the panel which shows us some additional actions. Then click on “Toggle Activate Breakpoints.” And all the breakpoints we added are disabled.
This is useful when you have breakpoints at different locations and don’t want to manually disable them one by one. This breakpoints pane gives us easy access to breakpoints without having to scroll through our project to find the breakpoints we’ve set.
Let’s reactivate the breakpoints. Hover on the brekapoints panel once more and click on the “Toggle Activate Breakpoints” button. And they all turn back to red.