Debugging in GFA-BASIC 32


At first sight (and maybe at second sight as well), the debugger implemented in GFA-BASIC 32 is a bit weird. The most annoying problem is the lack of support to start a program in single step mode or to break at a previously set breakpoint. However, through the use of the editor extensions these shortcomings can be resolved. First, let us look at the default implementation.

When you press F5 to start a program the IDE creates a debug thread, which is responsible for creating the GFABASIC trayicon and setting up a systemwide keyboardhook. When the program is closed the IDE does not remove the thread, it waits until the IDE is closing. The keyboardhook is removed though. The debugthread is responsible for handling both the popupmenu showing when you right click on the trayicon and the Break-key (through its keyboardhook). 

The popupmenu has the following entries:

  • Programname - Name of your program that is currently running. Note that you can have more then one IDE running next to each other, where each IDE has its own debugger. You can identify the name of the prgram by moving the mousecursor over the debug trayicon. 
  • End Program - This is the same as invoking the End command.
    Windows, file handles and other resources that are in use are should be closed after ending the program. Since GFABASIC keeps track of all resources opened using BASIC commands (Open, LoadForm, etc), the Cleanup Resources menu option can do the trick for you.  
  • Single Step - Sets the debugmode to single step. The debugarrow will be made visible in the code editor showing the code line that is currently executing. The actual process of single stepping through your code is accomplished by left clicking on the debug trayicon. 
  • Continue - Sets the debugmode to the initial setting. Continues executing without interrupting the program any longer. 
  • Pause - Sets the debugmode to pause. Holds the program. Any other selection will continue executing. (Seems to hold the system as well, the CPU is fully occupied when Pause is on). 
  • Follow - Sets the debugmode to follow. The debugarrow is shown for 0.33 seconds at each code line that is executing. This allows for easy tracking of the sequence of calling of event subs.
  • Show Debug - Shows the debug output window.

The next time you run the program the debugmode is reset to continue.

When running your program the debugger is able to respond to the following key combinations together with the Break-key.

  • Ctrl+Break - The same as End Program
  • Shift+Ctrl+Break - Sets the debugmode to Follow.
  • Alt+Ctrl+Break - Performs as crashsave.

The crashsave is useful when your program doesn't respond any longer and you would like to save your programcode. The code is saved to the C:\Documents and Settings\User\Local Settings\Temp directory with the crashsav.g32 name.

The only place or moment to start a debugging session through the use of the trayicon is during a DoEvents or Sleep loop. This could be in your main message loop or by invoking a simple message box. What matters is that you must give yourself an opportunity to enable single-step or follow mode.  When the message box is made visible the execution of the code is halted and you have that opportunity. A handy message box for that purpose is displayed by invoking the Stop command in your code.

The debugthread does not allow for inspecting variables, setting breakpoints and other features. It only allows to break and to step through your code.

The Debug object

GFA-BASIC 32 offers a range of statements to help in tracing errors in your program. One set of functions is provided by the Debug COM object. By using methods of the Debug object you can print to the output debug window, assert variables and trace variables:

Debug.Print sexp
Debug.Trace variable

You don't need to provide 'Print' explicitly because it is the default method, so Debug sexp suffices. There are shortcuts for the other two as well. GFA-BASIC allows to use both methods without naming the Debug object. Summarizing:

Debug sexp
Trace variable

Besides the inspecting methods, the Debug object provides the necessary properties to manage the output window, like positioning, clearing and hiding. (You can show the output window by selecting the appropriate option in the debug trayicon popupmenu.) You can manage the window from your code.