home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / beehive / program / c-no-bug.arc / DEBUG.DOC < prev    next >
Encoding:
Text File  |  1990-06-30  |  5.8 KB  |  144 lines

  1. Debug.doc        Written by Edmond Breen.
  2.                    18 Hampshire Ave
  3.                    West Pymble 2073.
  4.                    N.S.W.
  5.  
  6. Files:
  7.     debug.doc    
  8.     debug.h    
  9.     debug.c
  10.     driver.c
  11.  
  12. This debugger was originally written by Thomas D. Webb (for reference
  13. see debug.c file) for IBM PC and clones. I have modified it somewhat for use
  14. in a CP/M environment. It is a Public Domain full C source code debugger, 
  15. but small C users should have no problem changing it for their needs.
  16.  
  17. Debug.c as is, is configured for a Microbee, but should not present any
  18. problems being reconfigured for other machines. The only values that you
  19. will need to change are SCREEN and maybe COLS and ROWS found in debug.c.
  20.   
  21. To use the debugger, you simply code the macros defined in the header 
  22. debug.h into your program. A macro statement is defined for each C data 
  23. type: int, char, double, long, float, unsigned and string(see debug.h). 
  24. For addresses of any data type simply use the unsigned data type macro. 
  25. The macro execution statements will only be compiled into your program 
  26. if you #define DEBUG. The start of a program you wish to debug should look 
  27. something like this.
  28.     
  29.     #include <stdio.h>
  30.     #define  DEBUG
  31.     #include "debug.h" 
  32.  
  33. The macro statements defined in debug.h also test the value of the variable 
  34. trace_sw (trace_switch). If trace_sw is ON then each debug statement
  35. in your code is executed when met. If trace_sw is OFF then the debugger
  36. will not execute, which means that your program will run at normal speed.
  37. By default trace_sw is set to OFF, this means that you must turn trace_sw
  38. ON before using it. There are two ways you can turn the trace_sw ON and OFF,
  39. 1. simply code into your function or program you are debugging
  40. trace_sw = ON; or 2. use the function inkey() (see debug.c) to toggle this 
  41. switch. 
  42.  
  43. Each macro statement takes two variables, the first is a text string
  44. of your choice and the second is a data type for a particular data type
  45. macro. For example you could use the trace string macro, TS(), to 
  46. inform you of when you have entered or left a function as seen below:
  47.  
  48.     test()
  49.     {
  50.         char ch[] ="test character string";
  51.  
  52.         TS("enter test()","-------------");
  53.         TS("char ch[] =",ch);
  54.         TS("exit test()","^^^^^^^^^^^^^^^");   
  55.     }
  56. è
  57. The driver.c file illustrates how to code all the macros.
  58.  
  59. Each debug macro is actually a call to a function for a particular data
  60. type. All the debug functions are found in debug.c. The TS() macro is a
  61. call to the t_s(text,data) function which is handed the text and data.
  62.   
  63. Each data type function (see debug.c) formats a particular data type into
  64. a string called data so that it can be displayed on the screen and saved 
  65. in the trace_table with its text string. Each function then calls the 
  66. function display_trace(). The display_trace() function performs a number 
  67. of functions: 
  68.  
  69.     1« i⌠á intialize≤á thσ trace_tablσ thσ firs⌠ timσ i⌠á i≤ ì
  70.            executed.
  71.     2. it bumps the trace_table up 1 row (80 bytes). 
  72.     3. it places your text and data into the bottom row of 
  73.        the trace_table.
  74.     4. it saves the current screen display into save_buf[].
  75.     5. it displays 24 rows of the trace_table on the screen.
  76.     6. it waits for you to view you data.
  77.     7. it then dumps save_buf back onto the screen.
  78.     8. and returns control to your program. 
  79.  
  80. The trace_table is formatted so that the text item is displayed in the first
  81. 40 characters of each row and that the data item is displayed in the 
  82. next 40 characters, so that the trace_table screen display is divided into
  83. two 40 character columns. 
  84.  
  85. Each time you view the trace_table display you have the option to turn the 
  86. debugger OFF. The top most row of the display is:
  87.  
  88. Trace table ... Press any key to return ... Press ^Z to toggle off trace
  89.  
  90. Pressing any other key other than the CONTROL Z pair will leave the
  91. debugger activated (trace_sw = ON). Pressing ^Z will force trace_sw = OFF
  92. and your program will run as normal. 
  93.  
  94. Afte≥áyo⌡ havσ debuggeΣ you≥ prograφ anΣáhavσ i⌠áfunctioninτ correctly
  95. delete the statement '#define DEBUG' from your program; your C preprocessor 
  96. following the commands in debug.h will then remove all the debug macros from
  97. your source program before it is compiled.
  98.  
  99. The way I use this debugger is to have the debug.c file assembled into 
  100. relocatable object code which allows me to link it with any program I am 
  101. debugging, it will eventually find its way into my C-function
  102. library file. But for now, this saves a lot of time since the debugger 
  103. doesn't have to be compiled every time it is required.
  104.  
  105. One deviation of Troutman's programming laws is
  106.     
  107.     NOT UNTIL A PROGRAM HAS BEEN UPLOADED 
  108.     TO A BULLETIN BOARD WILL THE MOST HARMFUL
  109.     BUG BE DETECTED.
  110.  
  111. èTo avoid this I have had this debugger running on my system for several
  112. months now and all seems okay.
  113.  
  114. But before I end, here is a code fragment that contains a bug that 
  115. plagued me for a few hours before I ended up pulling out the debugger 
  116. to find its source. 
  117.  
  118.     sample(s)
  119.     char *s;
  120.     {
  121.         static unsigned spaces=0;
  122.  
  123.         ...
  124.         
  125.         if(!spaces)
  126.             while(spaces--)
  127.                 *s++ = ' ';
  128.  
  129.         ...
  130.     }
  131.  
  132.  
  133. The variable spaces had to remain static for reasons best known to me.
  134. Displayed like this the bug is not all that hard to see. But if you can't 
  135. see it don't worry. Spaces should contain a value between 0 and 8. If 
  136. spaces is greater than zero then the while statement will be executed until 
  137. spaces = 0. But the test in while also includes the deincrement operator.
  138. So when spaces = 0 the while statement will not be executed but spaces
  139. will still be deincremented; So then 0 - 1 = -1, not so because spaces is
  140. an unsigned variable, which means next time this function is called 
  141. spaces will equal 65535. You can imagine the havoc this caused.
  142.  
  143.  
  144. Good-luck Edmond...
  145.  
  146.