![]() |
![]() |
|
![]() |
Beyond Help: Breakpoints and the Debugger © 2002 Liz Woodhouse Paradox Help on Breakpoints and the Debugger breakpoint A flag you set in source code that is used in debugging to suspend execution. When code that is executing reaches a breakpoint, execution is suspended. Breakpoints allow you to inspect the values of selected variables and trace the code statements that have already executed. Debugger A component of the ObjectPAL Integrated Development Environment (IDE). The Debugger allows you to interactively find and correct errors in code by testing and tracing the execution of commands. You can use the Debugger to inspect the values of variables at the breakpoints in your code and to trace the execution of code. In the Paradox 8 ObjectPAL help, you can go to the help on the debug() procedure and click a link to a more detailed description of the "Debugger". (Due to the length it's not included here.) Beyond Help Overview There are several places in ObjectPAL help which make reference to using breakpoints and the debugger, but you'll have to use the "Find" tab to find most of them, and none is inclusive. Some of the more interesting points are that you set a breakpoint by double-clicking to the left of a line in a code editor window in order to toggle (add/remove) a breakpoint; that when debugging a library, you must set a breakpoint in the calling form and in the library; and that when a breakpoint is hit, code execution stops, the debugger is automatically opened and from there you can execute code one line at a time until you find the problem line. I recommend you go ahead and search for "breakpoint" in ObjectPAL help and read all the related topics and perhaps even those on the debugger. (In Paradox 8 ObjectPAL help, under the system type debug() method, there's a link on the word "Debugger" at the end of the first sentence. The topic this link takes you too is probably the most useful.) Introduction Breakpoints are one of the most useful tools available to the Paradox developer in figuring out why a block of code isn't executing as expected. It may also be the easiest tool to use, especially for beginners. The Tracer in Paradox allows you to select from the built-in event methods and then observe in the tracer window as the code executes and see which lines of code executed and the order in which events occur, but it doesn't allow you the flexibility and options available in the debugger. Therefore, for debugging code, using breakpoints and the Debug window, are, in my opinion, far more useful. Setting Breakpoints The first step in utilizing breakpoints and the debug window is to set the breakpoint. This is done by double-clicking the left mouse button at the far left side of a line of code in the code editor window. When you do this, a red 'breakpoint' marker highlights the selected line. (It should be noted that not all lines can have a breakpoint set on them. When this is the case, the breakpoint is set on the next allowable line.) You can set multiple breakpoints in your code (in multiple objects and multiple events). When you do this, you can opt, in the debug window, to let code run at normal speed, and it will stop again when the next breakpoint is encountered. ![]() What a breakpoint looks like in a code editor window If you want to step through code in a library, you must set a breakpoint both in the library and in the form that calls the library (this does not have to be the code that makes a call to the library, the breakpoint can come anywhere before the library call, so that you are stepping through code in the debugger when the library is called). You also have to call the LSL version of the library, as the delivered version doesn't allow stepping through code (since the code is compiled by that time). The tricky part of setting a breakpoint is deciding where to place the breakpoint. It's best to place the breakpoint as close to the problem code as you can so that you don't have to step through hundreds of lines of code just to get to the problem. The best way to determine where to place your breakpoint (from my experience) is to run the form and observe what object and action (pushing a button, leaving a field) seems to be causing the problem, then put the breakpoint as close to that as possible. (If the cause is so obscure that you can't identify an object, put the breakpoint in the form's init, an object's open or an object's arrive event. The debugger has features that allow you to move through blocks of code and even entire methods without having to execute each line manually.) Using the Debugger Once your breakpoints are set, you make use of them by running the form and triggering the suspect code. As soon as the breakpoint is hit, the debugger window is opened. ![]() What the debugger window looks like When the debug window first opens, the breakpoint it encountered will be highlighted blue. This line of code has not executed yet. It will execute when you tell it to by pushing either the Step Over ![]() ![]() ![]() After the libPC.open line succeeded, highlighting moved to the next available line of code. Note that the endIf was skipped as were the lines inside the if structure (which would only execute if the library failed to open). This is the basic operation of the debugger - you click the buttons (or use their keyboard equivalents) and execute one line of code at a time, observing what happens after each line executes until you come to the line of code that's causing the error. Debugger Options The debugger has all kinds of features to help you step through code and observe what's going on. First we'll review the toolbar buttons and then the menu options. ![]() The debug window's toolbar.
The Debug window's menu options are as follows:
One final nifty thing the debugger allows is checking the value of a variable at any point in code execution. There are two ways to check the value of a variable: inspecting and watching. To inspect a variable, right click on it in the debug window and choose Inspect from the popup menu. A view dialog will open showing you the value of the variable. You can change the value of the variable in the view dialog, click the OK button, and the variable in code will now have the value you entered. The other method of checking the value of a variable, "watching", is more passive. To "watch" a variable, right click on it in the debug window (or in the code editor while in design mode) and select Add Watch. This opens the Watches window where you can watch the value of the variable change as code executes. ![]() The Watches window. The Watches window displays the variable name, its value and its type. The window's right-click menu allows you to:
Not all variables can be watched or inspected (e.g. a tcursor will only show "N/A" when watched, but it can be inspected (shows the names and values of all fields in the current record)). I'm too lazy to test all variable types, so try it and see for yourself. Once you get used to using these tools, you'll find it helpful to assign values to variables in places where you might not otherwise (e.g. instead of assigning the value of one tcursor field to another tcursor's field, you might assign the value to a variable and then to the other tcursor so that you can watch the value in the debugger). You'll also find it helpful in understanding how loops work (e.g. when does the counter in a for loop get incremented, when are the conditions of a while loop evaluated, etc.). One Warning Note Sometimes using the debugger doesn't work because the delay in execution it causes also "cures" the error. This can happen with timing errors, in which case, you have to resort to logging, tracing or other methodology to track down the offending code. Conclusion Using breakpoints to invoke the debugger and then stepping though your code in the debugger is a quick and easy way to isolate the cause of errors or unexpected behavior. It's also a good way to see which events or what custom code causes other events to occur and exactly how various ObjectPAL methods and procedures work. Using the debugger can greatly reduce the time it takes to fix code that's not working as expected. Discussion of this article |
![]() Feedback | Paradox Day | Who Uses Paradox | I Use Paradox | Downloads ![]() |
|
![]() The information provided on this Web site is not in any way sponsored or endorsed by Corel Corporation. Paradox is a registered trademark of Corel Corporation. ![]() |
|
![]() Modified: 15 May 2003 Terms of Use / Legal Disclaimer ![]() |
![]() Copyright © 2001- 2003 Paradox Community. All rights reserved. Company and product names are trademarks or registered trademarks of their respective companies. Authors hold the copyrights to their own works. Please contact the author of any article for details. ![]() |
![]() |
|