Welcome to part one of X (where X = however many postings it takes) of debugging in REALbasic. I'll start out by discussing what debugging is, and why you must do it if you wish to be successful at programming. Then I'll move on to how to debug in REALbasic (for this part of the discussion, I'll be using REALbasic 2005's debugger), starting out with the basics, and moving on to steadily more advanced debugging techniques. Finally, I'll also be discussing how debugging actually works (from the computer's point of view), and why remote debugging is an important tool in your kit even if you don't develop cross-platform applications.
We've got a lot of ground to cover, so hang on and here we go!
Debugging, in the most generic sense, is the act of removing bugs from your program. Let's face it, every application has bugs in it. Everyone's got em, from hobbyist programmers right on up the line to huge outfits like NASA. And once you've got a bug, you need to find a way to get rid of it, right!
There's a handful of different ways people can debug their applications without the use of a software debugger. For example, you might be able to debug your code via code inspection. This is where you review your code by hand, looking for places where you know you wrote some incorrect code. A good example of when you've done code inspection debugging in the past is when you've run your application and noticed there's one too many items in your ListBox; so you go back to your code, hunt down the for loop which fills the listbox, and notice that you forgot to put a -1 in there. Ta da! You just inspected your code, noticed a bug, and fixed it.
Another way which people sometimes debug code is by using MsgBox or, hopefully, System.DebugLog. You can strew these calls throughout your code and read the messages as they arrive so that you can see where your logic breaks down. A lot of times you notice the bug because a message you expected to see was never shown, or a message was shown multiple times when you only expected to see it once. I tend to call this logical debugging because you're writing code to debug the logic without really peeking at the code to try to understand what it does. This sort of debugging technique has its place, so don't dismiss it as useless. However, I should note that you should never (ever, ever, ever) use MsgBox for this technique because it can actually modify the way your application behaves. You should always use System.DebugLog when doing logical debugging since it won't affect the way your application runs.
Finally, you can use a software debugger (or just debugger for short) to find bugs in your code. This is usually the most user-friendly way to locate and remove bugs from your code. The purpose of a debugger is to show you the state of your entire application at any given time. It does this by allowing you to arbitrarily halt your program at any point and see the state of things like what method you're in, which method called it, which class instance, the me and self values, local variables, global variables, etc. Basically, any part of your program which is currently being executed is accessible to you in a visual way.
Before I go any further, I should warn you that debugging with a software debugger introduces a whole new world of vocabulary. I am going to try to define new words for you as I introduce the concepts, however, if you spot a word you've never heard before or don't understand -- don't hesitate to ask me about it. Here are some common terms and definitions that you'll need before we go any further:
- Breakpoint -- a breakpoint is a location in your code at which the debugger will stop when it gets there. You set breakpoints in the IDE by clicking on the little grey dashes (-) on the left-hand side of the code. When you click on one, it'll turn into a little red ball, which means the breakpoint is set. If you click on it again, the ball will go away and the breakpoint is cleared. Finally, if you click on it (to bring the ball back) and then delete the line of code, the ball turns white, which means there used to be a breakpoint there, but it's gone now.
- Break -- when your code "breaks" into the debugger, that's just another way of saying that the debugger has halted your program at a particular spot in the code and is now displaying the debug information. So, for example, when the debugger hits a breakpoint, you break into the debugger and are looking at the code at the breakpoint.
- Execution point -- is just a fancy term for where (in your code) the CPU is currently running (or executing).
- Stack -- Also known as the call stack or stack crawl. It's a chronological list of method and events which lead up to the current execution point. So if you're currently at Method_A, which was called from Event_Foo, which was called by ClassB.MethodC, then you'll have a stack crawl which tells you this information. In REALbasic, the item that's lowest on the list is the most recent method call, and the item on the top of the list is the original call.
- Step -- this is the action you take when you want to advance from the current execution point to the next one. There are three variations of this action: step into, which steps into things like method calls so that you can see how they execute, step over (which in REALbasic is actually just labelled "Step"), which will step over things like method calls so that you do not see how they execute, and step out which will take you out of the current location in the stack and bring you up one level to the method or event which called you. With these three commands, you're able to walk through your application's code in the debugger and see what happens as each line executes.
Ok, I think I've gone into enough definitions that you'll be able to follow along when I begin to describe how to debug applications in REALbasic 2005. But, we'll save that discussion for next time!
I would like to note that I will be out of town starting tomorrow (and returning on the 17th), so updates may be more sporadic than normal. However, I plan to continue this thread as time permits.
Nice start. One tip I hope you might come up with later in the series.
When I explore a new control, I need to trace which events fire in which circumstances.
I tend to end up putting a breakpoint into every single event (or System.DebugLog or ListBox99.AddRow or whatever.)
Are there any shortcuts to report back on all the events?
There's nothing automated, so I would suggest using System.DebugLogs in there. That's a good example of when logging works better than visual debugging since visual debugging takes time -- logging with DebugLog is instant and doesn't interrupt anything.
I wish I could just break into the app at any time, also I wish exceptions had backtraces on them. I'll look for feedback reports sometime.
-- SirG3
You can break in at any point in time -- hit the Stop button in the IDE. I'll discuss it further at a later time.
Hm, never noticed the Pause (not stop) button there, heh.
-- SirG3
Doesn't Control-C still break stop the code and show the debugger?
I've used MsgBox before without much difficulty. (Old habits die hard.) However, if you have a MsgBox in an Activate event, you're in for a world of hurt! LOL
Also, the "Break" command is good when you want to stop at a certain point in a loop. ie:
for x = 1 to 100
if x = 84 then break
next
Stupid question - once in the RB 2005 debugger, how do you view the stack trace?
@Christian & Michael -- getting to a lot of that stuff. :-)