Leave a rating/review
Hello and welcome back! You currently have two bug fixes under your belts, and I have one here at home.
We’re going to continue with a bit of theory and practice, together, to show you more debugging tools and information available to you.
Continuing from the previous episode, and with a breakpoint still set on line 42, run your project.
If you look in the debug navigator to the left, you’ll see this stack of method names; this is what’s called the call stack.
The call stack is a data structure maintained in RAM by the OS, and it’s purpose is to control the way methods and functions call each other, as well as how parameters are passed to each other.
Each thread in an application has a call stack. When a method calls another method, it uses the stack to save its state and pass parameters to the new method.
Picture a scenario where you have three methods: Method 1, Method 2, and Method 3. Method 1 has two local variables. Method 2 has one input parameter and two local variables. Method 3 has two input parameters and two local variables.
We start with method 1 and its local variables on the stack.
Method 1 then calls Method 2.
At this point, the parameter for Method 2 is pushed onto the stack.
Next up, the return address of Method 1 is pushed onto the stack. This is so your application can later return to Method 1 once Method 2’s execution is complete.
The two local variables for Method 2 are now added to the stack.
Method 2 has everything it needs to run in what is commonly referred to as a stack frame, and it can look through this stack frame to find anything it needs.
Now Method 2 calls Method 3 and the same process as before takes place.
The two parameters for Method 3 are pushed onto the stack first, followed by the return address of Method 2, followed by the two local variables for Method 3.
You now have another stack frame for Method 3, allowing it to acquire any data it needs to run.
Method 3 does its magic and it now needs to return control of execution to Method 2.
The first thing that takes place is popping Method 3’s two local variables from the stack.
Next up, Method 3 can pop the return address of Method 2 in order to return control to Method 2.
Method 2 is responsible, in this example, for cleaning up the two parameters in the stack for Method 3.
At this point, Method 2 is in control and the same process follows.
Method 2 cleans up its two local variables in order to then be able to pop the return address of Method 1.
The return address for Method 1 is popped from the stack so execution and control can return to it.
Method 1 cleans up the input parameter for Method 2, and it is now ready to continue from where it left off.
Of importance is that, in this example, the stack pushes the parameters before the return address of a Method. But these kind of implementation-specific details vary between hardware architectures and operating systems.
Back in the Xcode Debug navigator, where execution of your program stopped, you can see each level in the stack, called a “frame”, for all the threads currently in use by your application.
Remember when you were using the step into and step out debug functionality? That’s really just going down or up a level in the call stack.
Click the Step out button and watch what happens. Three items on the stack disappears, but the rest of the stack remains the same. Run your project again, but click Step into this time.
New items are pushed onto the stack, and execution pauses at this point. You don’t have to wait for the stack to reach a particular point in order to debug things at that point. Click on the item with the number 1 in the stack. Notice how you are back on line 42.
There’s one quick thing to point out. You may have noticed that, in the stack, there are quite a few items that are grayed out.
If your stack doesn’t look like this, you may want to click this button, which filters the stack to only show stack frames with debug symbols. Go ahead and click the button to show the difference, then re-enable the filter.
Since Apple’s code has several frames on the stack, but you don’t have Apple’s source code, those show gray and this filter hides them for you. Click on item number 3 in the stack and you’ll see assembly code.
We don’t have the source code for this, so we seem assemble instead.
You’ll also see this if you step out of one of your methods, but Apple’s code was the previous frame on the stack. Usually in that case you just want to continue.
And there you have it! You have learned about the stack and the role it plays not only during debugging, but also to understand what happens behind the scenes when your app runs.
Hmm…I wonder what the stack equivalent is for me here at home? In any case, in the next episode we’ll take a look at how to debug your view hierarchies.
See ya then! :)