Using the Debugger

Introduction

The source level debugger in ASIC's integrated programming environment helps you debug your programs by allowing you to "peek" inside them as they're running. You can single step through your programs, or select places in the program where you wish execution to pause by setting breakpoints. Then, while the program is paused, you can view or modify any of your program's variables, and also examine the screen output created by your program.

All of the debugger's commands can be selected from the run menu, and they are described in the "RUN MENU" Section of Chapter 3, "Integrated Editor/Compiler Environment". Many of the debugger commands may be selected outside the "Run" menu, by pressing a function key (e.g., <F5>,<F6>,etc.). A complete list of the function keys available is contained in Chapter 3, in the "KEYBOARD USAGE" Section.

This chapter explains how to use the debugger with a short tutorial which guides you through a sample debugging session. The tutorial is followed by a reference section which you should read after completing the tutorial.

Debugger Tutorial
The debugger tutorial follows the same format as the general tutorial in chapter 2. You should complete (or at least review) the general tutorial before taking the debugger tutorial.

This tutorial will use a program file provided with your ASIC compiler package called "DBGTUTOR.ASI". If you are running from a hard disk, make sure it is in the ASIC directory. If you are running from a two-floppy system, make sure it is on the diskette in drive b:, with the compiler in drive a:.

Note: Floppy disk users should verify that the ASIC compiler diskette is
in drive A: and the "DBGTUTOR.ASI" disk is in drive b: before proceeding.

Let's get started:

     FLOPPY TYPE-->      A: <enter>
                         ASIC B:DBGTUTOR <enter>

     HARD TYPE-->        C: <enter>
                         CD C:\ASIC <enter>
                         ASIC DBGTUTOR <enter>

You should be in ASIC now, and you should see a source program. The first few lines should contain:

                    dim scores(10)
                    data 55,33,877,99,44,101,21,88,105,1
                    rem DBGTUTOR.ASI
                         .
                         . (etc.)
                         .

This sample program will sort an array of 10 scores into ascending sequence. It uses a simple "bubble" sort algorithm. The "bubble" sort algorithm simply steps through each element of the array and compares it to its next higher neighbor. If its neighbor's value is less than its own, the two values are swapped. It is necessary to execute this process N-1 times where N= number of items to sort. Here's why. Let's say the lowest value to be sorted was "1" and it is in array element "10" (assume 10 numbers will be sorted). The first swapping pass will result in the "1" being swapped from element 10 to element 9 of the array. An additional 8 passes through the array are necessary to move the "1" to array element number 1. This algorithm gets its name, because the process of moving the elements has been compared to that of bubbles slowly rising to the surface.

This program has a list of ten scores to be sorted. Line 5 of the program will read the ten scores to an array called "Scores", and also print the original values (before the sort) to the screen. Then two loops will execute at statements 8 and 9 in the program to perform the bubble sort as described above. Finally, after the sort is complete, the sorted values will be displayed.

First, let's compile the program. When we plan to use the debugger, we must set the "Debugging code" option on. This is done on the Compile Menu. However, the default in the integrated environment is "Debugging code" on.
Let's take a look to be sure:

     TYPE-->        <Alt><c>

The compile menu should pop open, and you should see a check mark next to the "Debugging code" option. If you don't, press the letter "D", and a check mark should appear. Once you've verified that the option is on, we can compile the program. Notice that there is an <F10> next to the option.
Instead of opening this menu and selecting the "Compile" option, we could have pressed <F10>. Let's try it. First, let's close the menu (Function keys don't work inside a menu):

     TYPE-->        <ESC>

The menu should have closed. Now let's compile using the function key:

     TYPE-->        <F10>

You should see the compiler screen pop up, and compile the program. No errors should be detected. Now we're ready to test the program. First, let's set a breakpoint so we can easily view the screen output, Use the down arrow key to position the cursor on line 20 (the line number is displayed on the ASIC status line). Line 20 should contain an "END" statement. Let's open the run menu and set a breakpoint:

     TYPE-->        <Alt><r>
                    <b>

The "END" statement should now be displayed in reverse video. That tells us that a breakpoint has been set there. Did you notice that the breakpoint option on the menu also had a function key listed. We could set a breakpoint without opening a menu, by pressing <F9> instead. Now that we've set a breakpoint, let's run the program and see how it works:

     TYPE-->        <Alt><r>
                    <r>

Note that we could have pressed the short cut key of <F5> to run the program instead of selecting the option from the menu. At this point our program is running, but is paused at the breakpoint we set on line 20. When you reach a breakpoint, ASIC will position the breakpointed line on the second line of the edit window, highlighted in red (or underlined, if you have a monochrome system). ASIC has interrupted the program before it executed the line with the breakpoint, in this case "END". Let's take a look at the screen output of the program to see if it worked:

     TYPE-->        <Alt><r>
                    <s>

Note we could also select the "Swap" function by pressing <F4> without opening a menu. You should now see the output from the program on the screen. It should look something like:

Original Scores:
    55    33   877    99    44   101    21    88   105     1
Sorting...
Here are the sorted scores:
    33    55    99    44   101    21    88   105     1   877

Well, that doesn't look quite right. Maybe we can use the debugger to figure out what went wrong. First, let's allow the program to run to completion (remember, we're paused at a breakpoint on the "END" statement).
Swap back to the ASIC screen from the user screen by pressing any key:

     TYPE-->        <enter>

You should see the editor screen again. Now let's tell ASIC to resume program execution:

     TYPE-->        <Alt><r>
                    <r>

ASIC has executed the END statement, and our program has terminated. You should see the message "Program Terminated Normally (0)". (The "0" is the return code set by the program. You can set return codes in your programs using the END statement. Refer to Chapter 7 for details.). Now we'll set another breakpoint in the program. Move the cursor to line 7 (the status line should now say LINE: 7) using the arrow keys. The cursor should now be positioned on the statement which says: PRINT "Sorting...". Set a breakpoint here:

     TYPE-->        <F9>

The source statement should now appear in reverse video. We used the shortcut key <F9> to set the breakpoint this time, but you could have opened the Run Menu, and selected the Breakpoint option and done the same thing. Let's remove the breakpoint:

     TYPE-->        <F9>

Line 7 should no longer be highlighted. The same command is used to turn breakpoints on or off for a source line. ASIC just checks to see if a breakpoint is already set at that source line when you select the breakpoint command. If one is set, it "toggles" it off (i.e. removes it), otherwise, it "toggles" it on (i.e. sets a breakpoint). This exercise was just to show you how to remove a breakpoint, let's go ahead and set it again:

     TYPE-->        <F9>

Line 7 should be highlighted again (the breakpoint is set).
It might be nice to see what's in some of our program's variables, so let's "watch" some variables. Open the Run Menu, select the Watch command, and tell ASIC you want to watch variable "I".

     TYPE-->        <Alt><r>
                    <w>
                    i<enter>

ASIC should have opened a "Watch" window at the bottom of the screen. You should see the variable name "I" at the left, followed by a ":". Following the ":" is the current value of that variable. The number there now doesn't really mean anything, since our program is not running. But once the we start the program, this number should represent the actual value of the variable "I"

Let's watch a few more variables: j, j1, and scores(1). This time, we'll use the shortcut key for the watch command:

     TYPE-->        <F6>
                    j<enter>

Variable "J" should now be in the watch window.

     TYPE-->        <F6>
                    j1<enter>

Variable "J1" should now be in the watch window. When we watch "scores", we'll also have to tell ASIC which element we want to watch by entering a subscript, since "scores" is an array. First ASIC will prompt you for the variable name. Type it, without the subscript. ASIC will prompt you for the numeric subscript.

     TYPE-->        <F6>
                    scores<enter>
                    <1><enter>

Scores(1) should now be in the watch window. Now we're ready to run the program again:

     TYPE-->        <F5>

Again we selected the short cut key, you could have selected the "Run your program" option from the "Run" Menu. The second line of the edit screen should show the PRINT "Sorting..." statement (highlighted in red, or underlined if you have a monochrome monitor). The variables in the watch window should have the following values:

     I:    11
     J:     0
     J1:     0
     SCORES(1):    55

Let's execute the next statement by using the Trace command:

     TYPE-->        <Alt><r>
                    <t>

ASIC has executed the PRINT "Sorting..." statement and has paused execution on the "FOR I" statement on line 8 of the program. Since the PRINT statement did not modify any variables, the numbers in the watch window should remain unchanged. Let's Trace one more statement, this time, we'll use the short cut key:

     TYPE-->        <F8>

ASIC has executed the "FOR I" statement on line 8, and is now paused on statement "FOR J" on line 9 of the program. Something looks wrong though.
Even though we executed the first "FOR I" statement, the variable "I" still contains "11". It should contain "1". If you look at line 8, you'll see that the FOR statement was mistyped, it reads: "FOR I = I to 9", instead of "FOR I=1 to 9". Since the program also used variable "I" to READ the data into the array, "I" still contains the value "11". Since "11" is greater than the "TO" value of the "FOR" loop, the FOR loop on line 8 is executed only 1 time instead of 9 times. That's why the data is not being fully sorted. With the ASIC debugger, we can continue testing without recompiling, by modifying the value of "I" to "1", so we can see if the rest of our logic is correct. If changing "I" to "1" works, then we can go back and modify the "FOR" statement and recompile the program to correct the program permanently. Modify the value of "I" to "1":

     TYPE-->        <Alt><r>
                    <m>
                    i<enter>
                    <1><enter>

The watch window should now show the value of "I" as 1. We can resume program execution at this point by selecting the "Run your program" option.
We'll use the short cut key again:

     TYPE-->        <F5>

ASIC should pause the program at the next breakpoint, which is on line 20.
This statement contains the "END" command. Now let's see if the program worked, by swapping to the user screen:

     TYPE-->        <F4>

Again, we used the short cut key. You should see the following on your screen:

Original Scores:
    55    33   877    99    44   101    21    88   105     1
Sorting...
Here are the sorted scores:
     1    21    33    44    55    88    99   101   105   877

It looks like the program worked. Let's return to the editor screen.

     TYPE-->        <enter>

Now we could press <F5> to resume execution and in this case terminate, since the END statement is the next one to execute. But let's look at another way to terminate a program. While at a breakpoint, you can select the "Abort your program" option, which instructs ASIC to terminate your program immediately, without executing any more of your program. Let's try it:

     TYPE-->        <Alt><r>
                    <a>

ASIC should display the message "Program Terminated Normally (0)". At this point, we'll just exit from ASIC, but normally, you would fix the FOR statement using the editor, save the file, recompile the program, and retest it to make sure the "bug" is really fixed.

     TYPE-->        <Alt><f>
                    <x>

You should be back at the DOS prompt now. That concludes the brief introduction to the ASIC debugger. The rest of this chapter provides some additional reference material for the debugger. Chapter 3 provides additional information about each of the debugging commands.

Debugger Tips

  1. When you are done debugging your program, you should recompile with the "debugging code" option turned off. Although your program can run from the DOS command line with debugging code present, it will increase the program size and execution times. Recompiling with the "Debugging code" option off will insure your programs will be smaller and faster.
  2. Remember that the default option on the command line compiler is "Debugging code" off. The default option in the integrated environment is "Debugging code" on.
  3. Breakpoints/Watches are automatically cleared when you OPEN or COMPILE a file.
  4. If you change source lines in a program while a program is running, without recompiling, source statements will not match executable code. Abort the running program and recompile after making code changes.
  5. Breakpoints are set in the edit buffer relative to the beginning of the buffer. If you insert/delete lines in the buffer, the breakpoints will still be set at the same relative line number from the beginning of the buffer.
  6. ASIC takes over the INT 3 Interrupt vector for debugging purposes. It re-installs the default vector when you exit ASIC.
  7. You must compile with the "Debugging code" option to use source level debugging.
  8. If you wish to run a program from the beginning again while its already running, select the "Abort your program" option from the Run menu. Then, select the "Run your program" option.
  9. If you select the Abort option from the Run menu, your program's files will NOT be closed gracefully. That is, data in the buffers will not be flushed to disk.
  10. You may still run a program in the integrated environment that has been compiled without the Debugging code option. You just won't be able to use the debugging commands (e.g., Breakpoints/Watches).
  11. Toggling a breakpoint on/off will clear any block of text you had previously marked for editing (e.g., MOVE, COPY).
  12. When modifying array variables, make sure that the subscript you specify is valid. For example, if you "DIM A(10)", make sure the subscript you specify is in the range of 0 to 10. ASIC does not check the range of a subscript. If you specify a subscript that exceeds the valid range for that variable, your program may crash.
  13. You can pass arguments to programs using the "Arguments" option on the Run Menu. You may retrieve these options in your program with the COMMAND$ statement. Using the "Arguments" option is equivalent to specifying arguments following the program name, when you run your program from the DOS command line.
  14. The compiler allows variable names up to 80 characters in length. The debugger only uses the first 30 characters of a variable name. When the debugger finds two variables whose names are not unique within 30 characters, it will always select the first one it finds (this applies to the Watch/Unwatch/Modify Variables commands).
  15. ASIC will allow you to set a breakpoint on a "FOR" statement. However, you should be aware that the source statement containing the "FOR" is executed only once (to initialize the loop). When the "NEXT" statement executes, control transfers back to the line following the "FOR", instead of the "FOR". For example, in the following code fragment:
         FOR I = 1 TO 3 <---Executes 1 time to initialize loop
         PRINT I <---Executes 3 times
         A=A+1 <---Executes 3 times
         NEXT I <---Executes 3 times, loops back to
         "PRINT I", not to "FOR I= 1 TO 3"
  16. Because a single machine language instruction could span multiple CODE statements, ASIC does not allow breakpoints on CODE statements.