Tuesday, October 31, 2006

Fewer Bugs and Better Bug Spray

Terrence Parr, a University of San Francisco Professor of Computer Science, suggests that there are six essential elements in the debugging process:

Reproduce the error. By finding a way to reproduce an error, you can often see the cause of the error. Parr says, "A bug that appears randomly is essentially unsolvable unless you have a leap of insight."

Reduce problems to their essence. Once you have discovered how to reproduce a problem, you should attempt to isolate an error to its smallest constituents. Parr suggest slicing data inputs, for example, to see which part of a file causes the problem.

Use your powers of deduction to find causality. This involves forming a hypothesis that can be tested. Follow the path of the data and watch for factors that can contribute to an error.

Test your hypothesis. Change various elements in the environment, the data and the logic to test your hypothesis.

Draw on experience. If you are an experienced developer, you will look for problems similar to those you have seen before in like situations. If you are a new developer, then you may want to consult another developer (Magic eDeveloper discussions are available on Yahoo! groups at magicu-l, for example.
Never give up. By taking a systematic approach, you will first test the hypotheses that seem most likely based on logic and past experience. Be patient, communicate with others and the solutions will become apparent.

Never give up. Parr sees tenacity as the final essential ingredient.Fortunately for users of eDeveloper V10, a new debugger has been introduced that makes extermination of bugs much easier than before.

Let's continue our review of Magic Software's 51 reasons to upgrade to eDeveloper V10. Reasons 36 through 41 all deal with enhancements to the debugger:

36. Visual Debugging Follow the exact logic definition within the studio as you progress step-by-step in debug mode.

This feature can help you pinpoint problems that you are having in an application by stepping through an application with pauses at pre-defined breakpoints.

When you are in Debug mode (you selected Debug Mode from the Debug menu), you can run a program in Runtime mode and the Debugger will "park" on the Studio read-only screen at the exact location of where you are in the program (when a breakpoint is reached).

37. Manageable Break Points Have full control on every break point defined in the application using the fully functional break points palette.

Obviously, breakpoints are a helpful tool for debugging. As Parr suggests in his point regarding the use of deduction, you need to follow the path of your data through an application in order to deduce any flaws in your logic. Breakpoints allow you to pause the logic at any point and determine exactly where things stand. Breakpoints let you halt execution of the program at a specific location in the Studio screen, so the debugger parallels the design of your program, which also gives you a clearer ability to see where problems may be introducuing themselves.

The how-to of breakpoints is quite straightforward, when you select Breakpoints from the View menu, the Breakpoint repository appears. You should remember that when you add a breakpoint to the Logic Editor, the default Condition is Always.

38. Conditional Break Points Reduce your debugging efforts by conditioning your set breakpoints for accurate and focus debugging.

Within the Debugger, you can define a conditional breakpoint if the Enable check box is selected. The condition will be evaluated each time the breakpoint is reached. If the condition evaluates to False, the breakpoint will be ignored.

The valid options for breakpoint conditions are Always, Count and Condition. With count, the breakpoint is only activated once the specified count has been reached. And of course, with a condition, the breakpoint will only be executed if the condition is True.

Condition: Execution will break only when the condition evaluates to True. This option is only enabled if the task in which the condition is defined is in focus. You can use variables from the current task tree.

39. Watch points Easily collect all variables that require your attention in the debugging process for efficient monitoring over the progress of your logic.

The watch points are very handy and make it easy to focus in on the variables that your experience suggests are most important. The Watch Variable list displays the variables currently being watched. This allows you to see how the value of the watched variable changes. You control which variables are displayed on the Watch variable list from the Variable list itself and the Variable declaration(s).

40. Modifiable Variables Manipulate the execution of a debugged execution by directly modifying the value of any variable.

The context menu gives you control over modification of variables in the debugging process. This is useful in pursuing various "what-if" scenarios as you test various hypotheses. The context menu allows you to add and delete variables from the watch list, go to the source for the variable, edit the current value of the data in the variable, set the variable value to NULL, and expand or collapse the index size of vector variables with a cell index >0.

41. Call Stack View Get clear information pertaining the exact stack of calls at any given time.

As you might expect, the Runtime Call Stack repository displays the state of the programs that are in the current runtime task tree and the handler (aka logic unit) that called the new program. You can get to this repository by selecting Call Stack from the View menu. Naturally, the tasks are displayed in the order in which they were executed. In other words, the Main Program of the host application will be the first task in the list and the current task will be the last one listed.

The information in the Runtime Call Stack repository is displayed in five columns.
The indicator column simply shows the current line. The module column will display the component name, if any. The task column shows the task name and the handler column show the Handler (logic unit) in that task. Finally, the line column shows the line number of the current operation.

Keep in mind that you can also view the flow of the logic within your eDeveloper application from the Activity Monitor. A whole article could be dedicated to this. It is also important to note that while you can only debug one context at a time, you can switch between contexts while debugging. You can also now dynamically change what information gets entered into the log with the dynamic logging function. You can change the logging filter on the fly, and this does not require a change to the magic.ini file. Sweet.

All in all, the new eDeveloper debugger is a huge improvement and benefit to the developer that just makes your life easier. Here again, it is worth the price of admission.

In the past, eDeveloper was known as an IDE that generally produced programs with fewer bugs and less need for debugging. But the debugging procedures available were weak in the past. With eDeveloper V10, you now have both advantages: fewer bugs and a faster way to isolate them and test your hypotheses.