Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Articles
Recherche: 

Using the Visual FoxPro Debugger
Hilmar Zonneveld, February 1, 2003
Introduction Any real-world application will sooner or later misbehave. It is important to be able to find those problems. Visual FoxPro's built-in debugger can help a lot to find out why your program doesn't work as you thought it would. Most of the material in this article applies to Visual...

Introduction

Any real-world application will sooner or later misbehave. It is important to be able to find those problems. Visual FoxPro's built-in debugger can help a lot to find out why your program doesn't work as you thought it would. Most of the material in this article applies to Visual FoxPro 5 and later. The debugger has been redesigned for this version; Visual FoxPro 3, and FoxPro 2.x, use a more primitive debugger.

Starting the debugger

There are several ways to start the debugger:

  • From the main menu, give the command "Tools | Debugger".
  • In a procedure, insert the command SET STEP ON before a suspect piece of code.
  • If you think that at a certain point in your program a certain condition should have been fulfilled (for instance, a variable is supposed to have a certain value), use the ASSERT command with a condition. If the condition isn't fulfilled, you get the option of opening the debugger.

A short sample

Here is an example of using ASSERT (which I saved as sample.prg):

set asserts on
x = 0
assert x = 1
wait window "This is the last line"

On reaching the line with ASSERT, you get the dialog "Assertion failed".

The debugger windows

In the example above, if you click on "Debug", you get the main debugger Window. The main window contains five windows; the screenshot shows the two you will use most of the time: Trace and Watch. The available windows are:

Window name Usage
Trace Shows the current program. Highlights the next program line that will be executed.
Watch Lets you to write a variable, or any expression for that matter, and see the result. One of the major improvements over the old debugger (used in FoxPro and VFP3) is that here you can expand arrays, to see its elements, and objects, to see its properties.
Call stack Shows what program called what other program, up to the currently running program.
Debug output If the relevant options are enabled, shows what events are executed. You can also send output to this window with the DEBUGOUT command.
Locals This window shows results similar to the Watch window, but you can't add or delete expressions. This window simply shows all locally visible variables.

Stepping through code

Two common and related tasks are stepping through code, and watching the values of expressions.

To step through code, one line at a time, you would click the "Step Into" button (or use the shortcut, F8). Here you can see how the program executes, one line at a time.

If a procedure calls another procedure, "Step Into" will show you the execution of the second procedure, line-by-line. If you want to avoid this (and only debug the original procedure), use the next button, "Step Over" (F6).

Note: Here, and in the remainder of this text, I will use the word "procedure" meaning "either a procedure, a function, a method, or an independent PRG".

The next button (Step Out, Shift-F7) is useful to quickly get out of the current procedure, and go to the next-higher level.

The next button (Run to Cursor, F7) can be used to run to a specific place in your code. You can also use breakpoints for this purpose.

In the case of objects, clicking on the "+" will show its properties and members. Each member object can again be opened, clicking on the "+".

One very useful object to debug is ThisForm, but this only works if the program is paused in the execution of a form method.

If Visual FoxPro is waiting for user input (usually with READ EVENTS), or executing some code outside the form (for instance, after clicking a toolbar button or selecting a menu item), ThisForm doesn't work. In this case, you can check properties of the form which is on top, with _vfp.ActiveForm.

Variables or properties whose value changed since you added them to the Watch window will appear in red.

One way to start debugging only at the desired point is to SET STEP ON (or use ASSERT) at the desired point. This doesn't require the debugger to be previously open.

Another way to start debugging at a specified point is to set breakpoints.

If you already see the desired procedure in the Trace window, you can double-click in the gray area to the left of a program statement. A red point will appear, indicating that program execution will pause at that point.

Once you set a breakpoint, you will usually want to press the "Resume" button (the first button on the debugger toolbar), or press F5, to run until a breakpoint is encountered.

You can also just type the name of the procedure or method in the Breakpoint window. Select "Tools | Breakpoints", leave "Type" as "Break at location", and under "Location", type the name of the procedure you want to debug.

This is very useful when you want to know what happens when a certain Visual FoxPro event occurs. For instance, you want to see what happens when you click a button.

Just set a breakpoint, on the location "Click".

You may also want to pause your program when the value of a certain expression changes. For instance, how come a certain control became disabled, when it is supposed to be enabled? Or how come it is ReadOnly? Or how come it isn't?

In the Debug window, you can set an expression on something like ThisForm.TxtSample.Enabled. When you double-click left of this expression (in the gray area), a breakpoint is automatically set. You can also set a breakpoint directly in the breakpoint window.

After this, you will want to click on "Resume", to continue program execution until the expression value changes.

General debugging strategy

The technical part, explained above, is the easy part. However, using the debugger to actually find the source of a problem requires experience, knowledge of Visual FoxPro commands, and quite often a bit of creativity. Often, it requires a lot of patience, too.

Sometimes it helps to work from the outside inwards: start debugging a procedure, debug line-by-line, and step over procedures, until you find that something weird happens - usually, a property or variable doesn't have the expected value.

If this happens right after running a procedure which you have "stepped over", repeat, but this time go into the procedure. You may have to repeat this several times, going deeper and deeper into procedures.

At other times, you need to go from the inside outwards: you start with a suspicious procedure, which you might have set as a breakpoint. Then, you notice that the error happened previously, so you repeat the debugging, this time stopping at a higher-level procedure.

Just setting a breakpoint for the case that a value changes (or reaches a certain value) can often quickly locate a problem.

Some events are very hard to debug. For instance, Activate and Deactivate fire when you change from one window to another - and this can happen if you simply change between the main Visual FoxPro window and the Debugger window.

MouseMove fires continuously while you move the mouse, InteractiveChange fires with every keystroke, and a Timer event can fire too often for comfortable debugging.

In cases like these, instead of using the built-in debugger, it sometimes helps to temporarily additional commands in the code.

One possibility is the ASSERT command, which only shows something if a condition is not fulfilled.

Another possibility is to show information on screen. For instance, WAIT WINDOW "Refresh" TIMEOUT 1 in a Refresh() Event can help you verify whether the Refresh() Event is reached at all, or not.

Or, you can send output to the corresponding debugger window with the DEBUGOUT command, or write information to a text file. This is easily done with FileToStr().

Conclusion

Sometimes just stepping through the code with the debugger will immediately highlight a problem. At other times, you will have to investigate for hours, sometimes days, until you find the cause of a problem. Whatever the case may be, it helps to know some debugging techniques.

Hilmar Zonneveld, Independent Consultant
Hilmar Zonneveld works in programming since 1986, using dBASE, FoxPro and Visual FoxPro. He is available as an independent consultant. He currently works as a programmer at Bata Shoe Organization; also as an instructor at Cisco Networking Academy. You can contact him through the Universal Thread, or, via e-mail, at hilmarz@yahoo.com. Personal Web page (mainly in Spanish): www.geocities.com/hilmarz.
More articles from this author
Hilmar Zonneveld, May 1, 2003
An audit-trail is a record of who did what changes, and when. In Visual FoxPro, this can easily be accomplished through triggers. I hinted at the possibility of doing an audit-trail, in my article on triggers - now, as a reaction to questions in the Universal Thread, I want to present a sample...
Hilmar Zonneveld, December 6, 2001
(The latest update contains minor edits only.) Five easy and fun ways to get yourself into trouble with inheritance. A frequent source of problems in OOP is called "breaking inheritance". This document briefly describes what inheritance is, how it applies to properties and methods, and how it ...
Hilmar Zonneveld, July 1, 2002
Introduction Buffering is a feature in Visual FoxPro that allows us to give the user "undo" and "save" capabilities. In the old FoxPro 2.x days, programmers either didn't provide this capability, or edited memory variables, and copied information between these variables and the table fiel...
Hilmar Zonneveld, October 6, 2005
Due to a recent Windows security fix, users can no longer access a CHM file on a server. The table of contents appears, but the individual pages are replaced by error messages. Access to CHM files in specific folders can be explicitly allowed through special registry settings.
Hilmar Zonneveld, July 20, 2001
(The last update contains minor edits only.) The idea is to have several controls on a form controlled with an array. Thus, you can quickly go through all the controls on the form, managing the array. The sample code included will help you get started quickly. You can easily adapt it to manage...
Hilmar Zonneveld, September 1, 2002
With Automation, you can control all aspects of Excel, Word, or other programs that provide this feature, from Visual FoxPro. In this article, I will concentrate on Excel. Its purpose is to provide a starting point, especially for people new to automation. Introduction With automation, you bas...
Hilmar Zonneveld, March 1, 2003
Introduction One common task in programming is to keep track of what problems are pending. For this purpose, I use a "hierarchical to-do list": a list of items, each of which can have sub-items. All you need is Microsoft Word. Alternatives are available as freeware or shareware, but in t...
Hilmar Zonneveld, October 7, 2005
This is a step-by-step tutorial to show inheritance, specifically in Visual FoxPro forms, as a guidance for people who are not familiar with inheritance in general, or who don’t know how to implement it in Visual FoxPro. The basic idea of inheritance is that all your forms, or several of your for...
Hilmar Zonneveld, May 30, 2004
The code shows how to quickly obtain the greatest common factor, and the least common multiple. Both functions are used when manipulating fractions, among others. Several methods are possible; the method usually taught in school involves prime numbers, but this code will execute much faster (and it ...
Hilmar Zonneveld, November 1, 2006
A standard requirement in a production system, or in systems for cost calculation, is to add up all the raw materials for a number of finished articles, to get the total cost, or simply to purchase the materials. In this article, Hilmar outlines how to do this with multiple levels of intermediate ar...
Hilmar Zonneveld, August 1, 2002
Overview The purpose of this article is to give an overview of normalization. Basically, normalization refers to having an efficient table structure. I will not discuss the famous "first to fifth normal forms" - if you want that information, enough texts exist about it in other places (search sit...
Hilmar Zonneveld, November 8, 2001
The following function will open any document, with its default association (the same application that will be called when you double-click on the file, in Windows Explorer). Use it to open a text-file, a Word or Excel document, an image, etc., with an external application.
Hilmar Zonneveld, May 1, 2002
Introduction This document explains the meaning of primary key, foreign key and candidate index in Visual FoxPro. A discussion of natural and surrogate keys (keys visible, or not visible, to the end-user) is included, including the advantages of each approach, as well as different methods for o...
Hilmar Zonneveld, January 1, 2003
Continuing my series of introductory articles, this article presents an introduction of a simple yet powerful programming concept: recursion. Introduction "To understand recursion, you must first understand recursion." "To make yogurt, you need milk and yogurt." If you are not accustomed...
Hilmar Zonneveld, December 1, 2002
Introduction This article presents an introduction to coding shortcuts in Visual FoxPro - when to use them, and when not to. Notes on coding in general This article is about coding shortcuts; however, I should first emphasize that making the code as small as possible is usually not the number...
Hilmar Zonneveld, July 20, 2001
Rushmore Optimization can help make queries much faster. However, "Full Rushmore Optimization" is not always a desirable goal. "Partial Optimization" is sometimes much faster. It is often believed that to speed things up, you need to have as many indices as possible. This article explains that so...
Hilmar Zonneveld, June 7, 2002
If you need to check elapsed time with seconds() or a datetime value, this function allows you to display the elapsed time in a human-readable format, that is, hours:minutes:seconds, instead of the total number of seconds. Just pass a number of seconds as a parameter.
Hilmar Zonneveld, April 1, 2002
SQL is a standard language used to manipulate databases. Several of the SQL commands are integrated into the Visual FoxPro language. Select This is a very flexible command, used to select data from a table, or from several tables. This command has options to get totals from several record...
Hilmar Zonneveld, August 1, 2003
In this article, I will show several ways to manipulate text-files. Knowledge of these methods is often important to import and export specific formats. Some of the techniques can also be used to work with files of any content; however, this article will concentrate on text-files. When ...
Hilmar Zonneveld, June 1, 2002
The purpose of this article is to show how to use some aspects provided by the Visual FoxPro database engine, to control our data. Indices Perhaps most readers already know indices; anyway, I find it convenient to include a brief summary of the topic, since this is a requisite to understan...
Hilmar Zonneveld, November 1, 2002
A help file can be used either for interactive help, or as an online manual. In this article, I will give an overview over creating help files in the new help format (CHM), for Visual FoxPro 6 and later. This article is introductory and assumes no prior knowledge of the Help Compiler, or of HTML cod...
Hilmar Zonneveld, May 1, 2006
This article is an introduction to VisioModeler. This is a free CASE tool, that can help you design your database, in the process sharing the information with the client in a visual, easy-to-understand, format.