home *** CD-ROM | disk | FTP | other *** search
- Debug.doc Written by Edmond Breen.
- 18 Hampshire Ave
- West Pymble 2073.
- N.S.W.
-
- Files:
- debug.doc
- debug.h
- debug.c
- driver.c
-
- This debugger was originally written by Thomas D. Webb (for reference
- see debug.c file) for IBM PC and clones. I have modified it somewhat for use
- in a CP/M environment. It is a Public Domain full C source code debugger,
- but small C users should have no problem changing it for their needs.
-
- Debug.c as is, is configured for a Microbee, but should not present any
- problems being reconfigured for other machines. The only values that you
- will need to change are SCREEN and maybe COLS and ROWS found in debug.c.
-
- To use the debugger, you simply code the macros defined in the header
- debug.h into your program. A macro statement is defined for each C data
- type: int, char, double, long, float, unsigned and string(see debug.h).
- For addresses of any data type simply use the unsigned data type macro.
- The macro execution statements will only be compiled into your program
- if you #define DEBUG. The start of a program you wish to debug should look
- something like this.
-
- #include <stdio.h>
- #define DEBUG
- #include "debug.h"
-
- The macro statements defined in debug.h also test the value of the variable
- trace_sw (trace_switch). If trace_sw is ON then each debug statement
- in your code is executed when met. If trace_sw is OFF then the debugger
- will not execute, which means that your program will run at normal speed.
- By default trace_sw is set to OFF, this means that you must turn trace_sw
- ON before using it. There are two ways you can turn the trace_sw ON and OFF,
- 1. simply code into your function or program you are debugging
- trace_sw = ON; or 2. use the function inkey() (see debug.c) to toggle this
- switch.
-
- Each macro statement takes two variables, the first is a text string
- of your choice and the second is a data type for a particular data type
- macro. For example you could use the trace string macro, TS(), to
- inform you of when you have entered or left a function as seen below:
-
- test()
- {
- char ch[] ="test character string";
-
- TS("enter test()","-------------");
- TS("char ch[] =",ch);
- TS("exit test()","^^^^^^^^^^^^^^^");
- }
- è
- The driver.c file illustrates how to code all the macros.
-
- Each debug macro is actually a call to a function for a particular data
- type. All the debug functions are found in debug.c. The TS() macro is a
- call to the t_s(text,data) function which is handed the text and data.
-
- Each data type function (see debug.c) formats a particular data type into
- a string called data so that it can be displayed on the screen and saved
- in the trace_table with its text string. Each function then calls the
- function display_trace(). The display_trace() function performs a number
- of functions:
-
- 1« i⌠á intialize≤á thσ trace_tablσ thσ firs⌠ timσ i⌠á i≤ ì
- executed.
- 2. it bumps the trace_table up 1 row (80 bytes).
- 3. it places your text and data into the bottom row of
- the trace_table.
- 4. it saves the current screen display into save_buf[].
- 5. it displays 24 rows of the trace_table on the screen.
- 6. it waits for you to view you data.
- 7. it then dumps save_buf back onto the screen.
- 8. and returns control to your program.
-
- The trace_table is formatted so that the text item is displayed in the first
- 40 characters of each row and that the data item is displayed in the
- next 40 characters, so that the trace_table screen display is divided into
- two 40 character columns.
-
- Each time you view the trace_table display you have the option to turn the
- debugger OFF. The top most row of the display is:
-
- Trace table ... Press any key to return ... Press ^Z to toggle off trace
-
- Pressing any other key other than the CONTROL Z pair will leave the
- debugger activated (trace_sw = ON). Pressing ^Z will force trace_sw = OFF
- and your program will run as normal.
-
- Afte≥áyo⌡ havσ debuggeΣ you≥ prograφ anΣáhavσ i⌠áfunctioninτ correctly
- delete the statement '#define DEBUG' from your program; your C preprocessor
- following the commands in debug.h will then remove all the debug macros from
- your source program before it is compiled.
-
- The way I use this debugger is to have the debug.c file assembled into
- relocatable object code which allows me to link it with any program I am
- debugging, it will eventually find its way into my C-function
- library file. But for now, this saves a lot of time since the debugger
- doesn't have to be compiled every time it is required.
-
- One deviation of Troutman's programming laws is
-
- NOT UNTIL A PROGRAM HAS BEEN UPLOADED
- TO A BULLETIN BOARD WILL THE MOST HARMFUL
- BUG BE DETECTED.
-
- èTo avoid this I have had this debugger running on my system for several
- months now and all seems okay.
-
- But before I end, here is a code fragment that contains a bug that
- plagued me for a few hours before I ended up pulling out the debugger
- to find its source.
-
- sample(s)
- char *s;
- {
- static unsigned spaces=0;
-
- ...
-
- if(!spaces)
- while(spaces--)
- *s++ = ' ';
-
- ...
- }
-
-
- The variable spaces had to remain static for reasons best known to me.
- Displayed like this the bug is not all that hard to see. But if you can't
- see it don't worry. Spaces should contain a value between 0 and 8. If
- spaces is greater than zero then the while statement will be executed until
- spaces = 0. But the test in while also includes the deincrement operator.
- So when spaces = 0 the while statement will not be executed but spaces
- will still be deincremented; So then 0 - 1 = -1, not so because spaces is
- an unsigned variable, which means next time this function is called
- spaces will equal 65535. You can imagine the havoc this caused.
-
-
- Good-luck Edmond...
-