home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 038 / pmd110.zip / MANUAL.TXT < prev    next >
Text File  |  1994-11-14  |  58KB  |  1,761 lines

  1.  
  2.  
  3.                      **** W A R N I N G ****
  4.  
  5.     The documentation for this program is typesetted exactly like the
  6.     Borland manuals. When this documentation is converted to plain ascii
  7.     it doesn't look very pretty. Especially graphics are distorted,
  8.     don't see chapter 4.
  9.  
  10.     This manual is primarily intended to give you an idea of its
  11.     contents. Registered users receive a printed and bound manual.
  12.     Besides they receive the manual in postscript format on disk.
  13.  
  14.                             ****  ****
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.                                                        Borland Pascal Debug Kit
  32.   ─────────────────────────────────────────────────────────────────────────────
  33.  
  34.                                                               Programming Guide
  35.  
  36.  
  37.  
  38.  
  39.  
  40.                                                                    Version 1.10
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.                                                                       NederWare
  59.                                                                 Burgerstraat 22
  60.                                                                 5311 CX Gameren
  61.                                                                 The Netherlands
  62.                                                         compuserve: 100120,3121
  63.                                                     email: berend@beard.nest.nl
  64.                                                           fidonet: 2:281/527.23
  65.  
  66.  
  67. C           O          N           T         E         N          T           S
  68.  
  69. ───────────────────────────────────────────────────────────────────────────────
  70.  
  71.  
  72.  
  73. Introduction Program with less pain         1     Chapter 5 Assertions                     23
  74. Why this tool?........................      1    
  75. Features  .............................     1    
  76.                                                   Part 2   Reference Manual
  77. What's in this manual  .................    2    
  78. Typefaces used in this manual  ..........   2    
  79.                                                   Chapter 6  Pascal Debug kit
  80. How to contact NederWare   ............     3    
  81.                                                     Reference                              27
  82. Acknowledgements ...................        3    
  83.                                                   Sample procedure  ....................   27
  84.                                                   Archive constant......................   27
  85.                                                   Assert procedure   ..................... 28
  86. Part 1   User Manual
  87.                                                   Beep procedure.......................    28
  88. Chapter 1  Working with log files           7     BeepOff procedure....................    28
  89. How to create or open a log file .........  7     BeepOn procedure  ....................   28
  90. How can you write information in the              BrowserRecordSize variable............   29
  91. log file  ..............................    8     BrowsersOffset variable   ...............29
  92.                                                   ClassesOffset variable  .................29
  93. Chapter 2 Checking your memory              9     ClassRecordSize variable   ..............29
  94. What you must do before MemCheck                  CMPB function  .......................   29
  95. can work   ............................     9     CMPW function  ......................    30
  96.     Updating the standard library  ........ 9     ConvMemLimit variable...............     30
  97.     Recompiling the system unit  ......... 10     CorrelationRecordSize variable  .........30
  98. What MemCheck does  ................       10     CorrelationsOffset variable............. 30
  99. How to enable memory checking  .......     11     CPos function  ........................  30
  100. How MemCheck works  ...............        11     CR constant ..........................   30
  101. MemCheck and DPMI.................         12     CreateBAK procedure  .................   31
  102.                                                   DataOffset variable   ...................31
  103. Chapter 3 Post Mortem Debugger             13    
  104.                                                   DateTime type  .......................   31
  105. What the Post Mortem debugger does  ...    13    
  106.                                                   DebugHeader variable   ................  31
  107. Using the Post Mortem Debugger.......      14    
  108.                                                   DebugInfoStart variable  ............... 31
  109. The Post-Mortem-Debugger under
  110.                                                   Delay variable........................   32
  111. MS-Windows  ........................       16    
  112.                                                   dfXXXX constants  ....................   32
  113.     Extra features under Windows  .......  16    
  114.                                                   DirStr type...........................   32
  115.     GPF's under Windows  ..............    16    
  116.                                                   Discard procedure  ....................  32
  117. Chapter 4 TDInfo                           17     DisposeSLink procedure...............    33
  118. How TDInfo models Borland's Debug                 DonePMD procedure..................      33
  119. Information  ..........................    17     DoneStrings procedure  ................  33
  120. Changes between Open Architecture                 DosCopy procedure...................     33
  121. names and TDInfo names..............       19     DosDel procedure   ....................  34
  122. How to make use of TDInfo  ............    20     DosDelay procedure   ..................  34
  123.     Initializing the TDInfo unit...........20     DosMove procedure  ..................    34
  124.     Getting information from a debug              DosTouch procedure  ..................   35
  125.     symbol file.........................   20     DosWipe procedure  ...................   35
  126.     Getting line numbers..............     21     DStream variable  .....................  36
  127.     Getting procedures  ...............    21     DumpStack variable  ..................   36
  128.                                                   DumpStackProcedureType type   ........   36
  129.  
  130.  
  131.                                                                                             i
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. Empty function.......................      36     LoadStrings procedure  ................  46
  140. ExtractStr function  ....................  36     LogError procedure  ...................  46
  141. ExtStr type...........................     36     LowCase function   ....................  46
  142. FancyStr function  .....................   37     LowStr function  ......................  46
  143. FatalErrorText variable  ................  37     MaxConventionalMemoryBlock constant      46
  144. FCreate function......................     37     MaxMemPtrs constant.................     46
  145. FDefaultExtension function  ............   37     MaxWord constant....................     47
  146. ferr variable..........................    37     MemberRecordSize variable............    47
  147. FExpand function.....................      38     MembersOffset variable  ...............  47
  148. FF constant   ..........................   38     MemCheckReport procedure ...........     47
  149. FForceDir function....................     38     memfXXXX constants  .................    47
  150. FForceExtension function  ..............   38     Min function  .........................  48
  151. FileExist function  .....................  38     ModuleClassesOffset variable  .......... 48
  152. FileRec type..........................     38     ModuleClassRecordSize variable   ....... 48
  153. fmXXXX constants  ....................     39     ModuleRecordSize variable  ............  48
  154. FOpen function.......................      39     ModulesOffset variable................   48
  155. FormatStr procedure  ..................    39     NamesOffset variable   ................. 49
  156. FormFeed constant....................      39     NameStr type  ........................   49
  157. FTCopy function  .....................     40     NewSLink function  ...................   49
  158. GetAddrStr function  ..................    40     OverloadRecordSize variable...........   49
  159. GetDateStr function ...................    40     ParentRecordSize variable  ............. 49
  160. GetEnv function  ......................    40     ParentsOffset variable  .................49
  161. GetFileName function  .................    40     PathStr type..........................   50
  162. GetLogicalAddr function  ..............    40     PrintError variable  ....................50
  163. GetObjMemory function...............       41     PrintErrorType type...................   50
  164. GetStr function  .......................   41     prnXXXX constants  ...................   50
  165. GetTextFileName function  .............    41     PSLink type..........................    51
  166. GetTickCount function  ................    41     Registers type  ........................ 51
  167. GetTimeStr function...................     42     RepChar function.....................    51
  168. GetUniqueFileName function  ..........     42     ReplaceStr procedure..................   51
  169. HandleRunTimeError variable  .........     42     ReportFileName constant  ..............  51
  170.       HandleRunTimeErrorProcedureType type 42     RightJustify function  ..................52
  171. HexB function........................      42     rsGet function  ........................ 52
  172. HexStr function  ......................    42     rsGet1 function  ....................... 52
  173. InitBBError function  ..................   43     rsGet2 function  ....................... 52
  174. InitIntHandler procedure  ..............   43     ScanB function  .......................  53
  175. InitObjMemory procedure  .............     43     ScanW function  ......................   53
  176. InitPMD procedure  ...................     43     ScopeClassesOffset variable  ............53
  177. IsDirectory function...................    44     ScopeClassRecordSize variable  ......... 53
  178. IsFileOpen function  ...................   44     ScopeRecordSize variable  .............. 53
  179. IsValidPtr function....................    44     ScopesOffset variable  ................. 53
  180. LeadingZero function  .................    44     scXXXX constants.....................    53
  181. LeftJustify function   ................... 45     SearchRec type  .......................  54
  182. LF constant  ..........................    45     SegmentRecordSize variable   ........... 54
  183. LineNumberRecordSize variable........      45     SegmentsOffset variable  ............... 54
  184. LineNumbersOffset variable  ...........    45     SetHandleCount procedure  ............   54
  185.  
  186.  
  187.                                        ii
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195. SmallDebugHeaderSize constant  .......     55         Methods...........................   67
  196. SmallEndianI procedure  ...............    55     TObjMemory object  ...................   67
  197. SmallEndianL procedure  ..............     55         Fields  .............................67
  198. SmallEndianW procedure..............       55         Methods...........................   67
  199. SourceFileRecordSize variable  ..........  55     TOverload type.......................    68
  200. SourceFilesOffset variable  .............  55     TParent type  .........................  68
  201. Spc function  .........................    56     TResourceCollection object.............  69
  202. Spoiled function  ......................   56         Methods...........................   69
  203. StrB function  .........................   56     TResourceFile object   ..................69
  204. StrI function  .........................   56         Fields  .............................69
  205. Strings variable.......................    56         Methods...........................   69
  206. StripSpc function  .....................   56     TResourceItem type...................    70
  207. StrL function  .........................   57     TrimRight function....................   70
  208. StrR function.........................     57     TScope object  ........................  70
  209. StrResBufSize variable.................    57         Fields  .............................70
  210. StrS function  .........................   57         Methods...........................   71
  211. StrW function  ........................    57     TScopeClass type  .....................  71
  212. stXXXX constants  .....................    57     TSegment object  ......................  71
  213. SymbolRecordSize variable   ............   58         Fields  .............................71
  214. SymbolsOffset variable  ................   58         Methods...........................   72
  215. TBrowser object   ......................   58     TSLink type..........................    73
  216.     Fields  .............................  58     TSmartBufStream object  ...............  73
  217.     Methods...........................     59         Fields  .............................73
  218. TClass object  .........................   59         Methods...........................   73
  219.     Fields  .............................  59     TSourceFile object  .................... 73
  220.     Methods...........................     59         Fields  .............................74
  221. TCorrelation object....................    59         Methods...........................   74
  222.     Fields  .............................  60     TSymbol object  .......................  74
  223.     Methods...........................     60         Fields  .............................74
  224. TDebugHeader type   ..................     60         Methods...........................   74
  225. TDInfoPresent function................     62     TType object   ......................... 75
  226. TDriveStr type   .......................   62         Fields  .............................76
  227. TextPrintError procedure  ..............   62         Methods...........................   76
  228. TextRec type  .........................    63     TypeRecordSize variable...............   77
  229. tid voidXXXX constants  ...............    63     TypesOffset variable   ..................77
  230. TLineNumber object  ..................     63     UpStr function   ....................... 77
  231.     Fields  .............................  63     ValB function.........................   77
  232.     Methods...........................     63     valcode variable  ...................... 77
  233. TMember object  ......................     63     ValHex function  ......................  77
  234.     Fields  .............................  65     ValI function  ......................... 78
  235.     Methods...........................     65     ValL function.........................   78
  236. TModule object.......................      65     ValR function  ........................  78
  237.     Fields  .............................  65     ValW function........................    78
  238.     Methods...........................     66     Warning procedure   ...................  78
  239. TModuleClass type  ...................     66     ZeroRightJustify function  ..............79
  240. TObject object  ........................   67    
  241.  
  242.  
  243.                                        iii
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  Appendix A Errors and omissions
  252.              in Open Architecture
  253.              Handbook                      81    
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.                                        iv
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308. I     N       T     R      O       D      U      C       T     I      O       N
  309. ───────────────────────────────────────────────────────────────────────────────
  310.  
  311.  
  312.                                                          Program with less pain
  313.  
  314.  
  315. Why this tool?
  316. ───────────────────────────────────────────────────────────────────────────────
  317.   Once, I tracked down a bug that caused some strange and
  318.   unpredictable behaviour. After finally having located the problem,
  319.   it appeared that I had released a bigger block of memory than
  320.   what I had previously allocated. Borland Pascal, naturally, didn't
  321.   like this. Well, neither did I since, all in all, this bug took me 10
  322.   hours to find and fix.
  323.   Some time later, I encountered another bug that caused a
  324.   behaviour which I remembered but all too well. At that stage I
  325.   thought: let's put these 10 hours to some better use.
  326.  
  327.   That thought was the start of  MemCheck, a utility that tracks
  328.   memory allocations and deallocations. If you release too much
  329.   memory or too little,  MemCheck  aborts your application, writing
  330.   the address of the erroneous code to a log file.
  331.   MemCheck  has since been enhanced to write the name of the file
  332.   and the line of code using  TDInfo, a utility that accesses the Debug
  333.   information, if present, in an executable file.
  334.  
  335.   The above mentioned tools,  MemCheck,  TDInfo  and  PMD, together
  336.   with  Assertions, a unit which provides you with C like assertions,
  337.   form the Borland Pascal Debug Kit. It's my sincere hope that these
  338.   tools will prove useful to Pascal programmers all around the
  339.   world, helping them to develop bug-free programs easier and
  340.   faster.
  341.  
  342.  
  343. Features
  344. ───────────────────────────────────────────────────────────────────────────────
  345.   The Borland Pascal Debug Kit provides you with many things that
  346.   make debugging easier. If you use these tools properly, you can
  347.   even be sure that some bugs will not occur in your programs! For
  348.   example, releasing more or less memory than previously allocated
  349.   immediately halts your program and the offending line is written
  350.   to a log file.
  351.   In summary, the Borland Pascal Debug Kit gives you:
  352.  
  353.  
  354. Introduction                                                                  1
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.   ■ Allocation and deallocation tracking
  363.   ■ A report of not deallocated memory after your program
  364.     termination
  365.   ■ A full stack dump (procedure names and parameters) if a
  366.     run-time error occurs
  367.   ■ C-like assertions to `fortify your subsystems'
  368.  
  369.  
  370. What's in this manual
  371. ───────────────────────────────────────────────────────────────────────────────
  372.  
  373.   This manual explains how to use the Borland Pascal Debug Kit. It
  374.   doesn't tell you how to write Borland Pascal programs.
  375.  
  376.   The first part of this manual contains the following chapters:
  377.  
  378.   ■ Chapter 1, ``Using log files'', describes how to use log files to
  379.     make debugging easier, especially when your program is
  380.     running at a remote site.
  381.   ■ Chapter 2, ``Memory Checker'', introduces the memory
  382.     allocation and deallocation tracker and explains how to use it.
  383.   ■ Chapter 3, ``Post Mortem Debugger'', describes how to get
  384.     annotated stack dumps.
  385.   ■ Chapter 4, ``TDInfo'', explains a unit which gives access to
  386.     Borland's debug information.
  387.   ■ Chapter 5, ``Assertions'', introduces you to assertions and how
  388.     to use them in your programs.
  389.  
  390.   The second part of this manual is contains reference material for
  391.   the source code supplied with the Borland Pascal Debug Kit.
  392.  
  393.  
  394. Typefaces used in this manual
  395. ───────────────────────────────────────────────────────────────────────────────
  396.  
  397.   This manual was typeset using LATE X2ε, converted to postscript
  398.   using dvips, and printed on a HP Laserjet IV. All typefaces used in
  399.   this manual are standard Postscript fonts. Their uses are as
  400.   follows:
  401.  
  402.   The monospace typeface represents text as it appears on-screen or
  403.   in a program. It is also used for anything you must type (e.g. BP          to
  404.   start up the Borland Pascal IDE).
  405.  
  406.   The boldface typeface is used in text for command line options.
  407.  
  408.   Italics is used to indicate identifiers that appear in text. They can
  409.   represent terms that you can use as they are, or that you can think
  410.  
  411.  
  412. 2                                               Borland Pascal Debug Kit Manual
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.   up new names for (your choice, usually). They are also used to
  421.   emphasize certain words, such as new terms.
  422.  
  423.   This typeface indicates a key on your keyboard. For example,
  424.   ``Press  Esc  to exit this menu.''
  425.  
  426.   Key combinations produced by holding down one or more keys
  427.   simultaneously are represented as  Key1+Key2.
  428.  
  429.  
  430. How to contact NederWare
  431. ───────────────────────────────────────────────────────────────────────────────
  432.  
  433.   NederWare offers a variety of services to answer your questions
  434.   about the Borland Pascal Debug Kit. Of course, this is only true for
  435.   registered  users. If you haven't registered yet, support shareware
  436.   (and me and my family) by registering this Debug Kit today.
  437.   We've made it very easy for you. You can register by CompuServe,
  438.   fax, email or telephone. Please consult REGISTER.FRM for more
  439.   details.
  440.  
  441.   CompuServe
  442.  
  443.   Subscribers to CompuServe can reach NederWare at 100120,3121. 
  444.   The latest version of the Borland Pascal Debug Kit is available in
  445.   library 3 of the BPASCAL forum.
  446.  
  447.   Internet
  448.  
  449.   NederWare can be reached on the Internet through
  450.   NederWare@beard.nest.nl or berend@beard.nest.nl. For the latest 
  451.   Debug Kit version, check-out garbo.uwasa.fi:/pc/turbopas.
  452.  
  453.   Fidonet
  454.  
  455.   NederWare can be reached on Fidonet at 2:281/527.23. The latest
  456.   version of the Borland Pascal Debug Kit is also available at
  457.   2:281/527, Contrast BBS, The Netherlands. Its full international
  458.   telephone number is +31 70-3234903. From Holland dial
  459.   070-3234903.
  460.  
  461.  
  462. Acknowledgements
  463. ───────────────────────────────────────────────────────────────────────────────
  464.  
  465.   First and foremost, many thanks to Stephen Maguire, who in his
  466.   excellent book [Maguire93] showed us all that writing bug free
  467.   (well, almost) code is possible. If you are serious about writing
  468.   commercial software, read this book! It inspired me to put together
  469.   all the pieces I had accumulated over the years in this package.
  470.  
  471.  
  472. Introduction                                                                  3
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.   Many thanks also to Andy McFarland, author of TDI, a utility that
  481.   displays the contents of the debug information the the BP compiler
  482.   appends to an executable. Andy generously provided me with the
  483.   source of his utility, which gave me a jump start in developing my
  484.   TDInfo               unit. Andy can be reached at CompuServe as 71055,2743 or
  485.   by email as amcfarl@ndlc.occ.uky.edu.
  486.  
  487.   Last but not least thanks to Dag Hovden
  488.   (dhovden@runner.knoware.nl) for cleaning up this manual and
  489.   improving its english. All remaining faults are mine.
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529. 4                                               Borland Pascal Debug Kit Manual
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550. P                        A                         R                          T
  551. ───────────────────────────────────────────────────────────────────────────────
  552.  
  553.                                                                               1
  554.  
  555.  
  556.  
  557.                                                                     User Manual
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.                                                                               5
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640. 6                                               Borland Pascal Debug Kit Manual
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649. C            H            A            P            T            E            R
  650. ───────────────────────────────────────────────────────────────────────────────
  651.  
  652.                                                                               1
  653.  
  654.  
  655.  
  656.                                                          Working with log files
  657.  
  658.  
  659.   Log files form the basis of Post Mortem Debugging. Using log files
  660.   means no more scribbling down error codes and addresses on a
  661.   piece of paper when your program crashes because it's already all
  662.   there, in the log file. This feature becomes especially useful when
  663.   you use it in tandem with  PMD, the Post Mortem Debugger,
  664.   because  PMD  gives you a full symbolic stack dump. Try to write
  665.   that down as it scrolls past you on the screen!
  666.   Another benefit of using log files is that you know exactly what
  667.   your program was up to when it crashed running at a customer
  668.   site. No more long telephone conversations, simply ask the
  669.   customer to modem (or mail) you the log file.
  670.  
  671.  
  672. How to create or open a log file
  673. ───────────────────────────────────────────────────────────────────────────────
  674.   The unit  BBError  makes using log files easy. All you have to is to
  675.   call  InitBBError  with the name of the logfile and a Boolean
  676.   parameter saying to create or to open the log file if it already exists.
  677.   The following program demonstrates this:
  678.  
  679.      program Test;
  680.  
  681.      uses
  682.        BBError;
  683.  
  684.      begin
  685.        writeln('Installing log file writing');
  686.        InitBBError('TEST.LOG', TRUE);
  687.        writeln('Done!');
  688.      end.
  689.  
  690.   A call to the procedure  InitBBError  does two things:
  691.  
  692.   1. It creates the log file if it does not exists or if the second
  693.      parameter is FALSE. The file is opened in append mode if it
  694.      exists and the second parameter is TRUE.
  695.  
  696.  
  697. Chapter 1, Working with log files                                             7
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.   2. It installs an exit procedure which writes the error address and
  706.      exit code to the log file if an error occurs.
  707.      This exit procedure also dumps a stack trace to the log file with
  708.      the addresses of all the callers that lead up to the code that
  709.      caused the error.
  710.  
  711.  
  712. How can you write information in the log file
  713. ───────────────────────────────────────────────────────────────────────────────
  714.  
  715.   You can write your own data to the log file using the  ferr  text file
  716.   variable by adding  BBError  to the  USES  statement of any unit that
  717.   wants to write to the log file.
  718.  
  719.   Example:
  720.  
  721.      program WriteToferr;
  722.  
  723.      uses
  724.        BBError;
  725.  
  726.      begin
  727.        InitBBError('TEST.LOG', TRUE);
  728.        writeln(ferr, 'This goes to the log file.');
  729.      end.
  730.  
  731.   A second method is to call BBError's  LogError  procedure which
  732.   first writes the current date and time to the log file and next any
  733.   text you passed to it. Calling LogError is the preferred method.
  734.  
  735.   Example:
  736.  
  737.      program WriteToLogError;
  738.  
  739.      uses
  740.        BBError;
  741.  
  742.      begin
  743.        InitBBError('TEST.LOG', TRUE);
  744.        LogError('This goes to the log file.');
  745.      end.
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756. 8                                               Borland Pascal Debug Kit Manual
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765. C            H            A            P            T            E            R
  766. ───────────────────────────────────────────────────────────────────────────────
  767.  
  768.                                                                               2
  769.  
  770.  
  771.  
  772.                                                            Checking your memory
  773.  
  774.  
  775.   Use the  MemCheck  unit, if you want to check if your allocations
  776.   match your deallocations or if you want to check if you didn't
  777.   overwrite memory before or after an allocated memory block. This
  778.   chapter tells you how to use  MemCheck  and what  MemCheck  does.
  779.  
  780.  
  781. What you must do before MemCheck can work
  782. ───────────────────────────────────────────────────────────────────────────────
  783.  
  784.   Before you can use  MemCheck  you need to replace the standard
  785.   SYSTEM unit by the SYSTEM unit supplied with the Borland
  786.   Pascal Debug Kit. There are two cases:
  787.  
  788.   ■ If you always work with the Borland Pascal library TURBO.TPL,
  789.     TPP.TPL or TPW.TPL, you need to replace the SYSTEM unit
  790.     contained in the library by the supplied one. Below we will
  791.     explain how to do this.
  792.   ■ If you don't load the library at startup but instead link in the
  793.     units as separate files, simply copy the supplied SYSTEM.TPx to
  794.     the directory where you keep these units.
  795.   ─────────────────────────────────────────────────────────────────────────────
  796.              Updating the    
  797.   Replacing SYSTEM.TPx is quite easy. First remove the `old'
  798.          standard library    
  799.   SYSTEM.TPU from TURBO.TPL (or TPP.TPL or TPW.TPL, please
  800.   substitute as needed). You can do this with the following
  801.   command:
  802.  
  803.        tpumover turbo -system
  804.  
  805.   Next install the new SYSTEM.TPU by:
  806.  
  807.        tpumover turbo +system.tpu
  808.  
  809.   To install the new SYSTEM.TPW in the windows library type:
  810.  
  811.        tpumover tpw +system.tpw
  812.  
  813.   Note: don't forget tot type the correct extension after sytem, e.g.
  814.   .tpu, .tpp or .tpw!
  815.  
  816.  
  817. Chapter 2, Checking your memory                                                             9
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.   ─────────────────────────────────────────────────────────────────────────────
  825.           Recompiling the    
  826.   If you have the run-time library source, and if you want to
  827.               system unit    
  828.   recompile the SYSTEM unit with our changes incorporated, you
  829.   need to patch the original SYSTEM.PAS, HEAP.ASM and
  830.   WMEM.ASM with the diff (i.e. difference) files SYSTEM.DIF,
  831.   HEAP.DIF and WMEM.DIF. Please note: these files are new
  832.   structure diff files, created with the GNU diff utility.
  833.  
  834.   You can use the GNU patch utility (we use the one coming with
  835.   the DJGPP GNU C compiler port) to patch your run-time library
  836.   source. For example, execute
  837.  
  838.        patch system.dif c:/bp/rtl/sys/system.pas
  839.  
  840.   to update the SYSTEM.PAS file in the C:/BP/RTL/SYS directory.
  841.  
  842.  
  843. What MemCheck does
  844. ───────────────────────────────────────────────────────────────────────────────
  845.  
  846.   The  MemCheck  unit checks for the following three bugs:
  847.  
  848.   ■ Attempts to dispose a pointer, specifying a size other than the
  849.     value used when creating the pointer. This causes a program
  850.     halt.
  851.   ■ Allocating memory and never deallocating it (i.e. memory
  852.     leakage). By calling  MemCheckReport, you obtain a list of
  853.     pointers still allocated together with the addresses in your
  854.     program where these pointers were created.
  855.   ■ Writing to memory that lies outside an allocated block of
  856.     memory, i.e. before or after the block. This check is equivalent to
  857.     the Range check ({$R+}) option for normal arrays. This bug also
  858.     causes a program halt.
  859.  
  860.   The demo program TestMem demonstrates these three bugs.
  861.   Execute TestMem and select one of the three options presented to
  862.   you. Afterwards, see TESTMEM.LOG for choice 1 and 2, and
  863.   MEMCHECK.RPT for choice 3.
  864.  
  865.   If you have appended debug information to your executable and if
  866.   you have initialized the post mortem debugger,  MemCheck  will
  867.   also print the source file, line number and procedure name where
  868.   the error occured. This is also true for MEMCHECK.RPT. When
  869.   debug informaton is appended, you will find in MEMCHECK.RPT
  870.   the source file and line number file where the allocation occured
  871.   and on the next indented line the source file and line number of
  872.   the caller of that routine (if any).
  873.  
  874.  
  875.  
  876.  
  877. 10                                                            Borland Pascal Debug Kit Manual
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885. How to enable memory checking
  886. ───────────────────────────────────────────────────────────────────────────────
  887.  
  888.   You enable  MemCheck  by placing it in the USES clause of your
  889.   main program. No additional calls are needed. Please bear in
  890.   mind that using  MemCheck  will cost you an extra 32 bytes per
  891.   allocated memory block!
  892.  
  893.   Errors detected by MemCheck             are normally printed to the screen. A
  894.   much better alternative is to use  MemCheck  together with  BBError,
  895.   the log file unit. When you use  BBError  the errors will be written
  896.   to a log file instead.
  897.  
  898.  
  899. How MemCheck works
  900. ───────────────────────────────────────────────────────────────────────────────
  901.  
  902.   MemCheck  keeps track of every allocated pointer and the size
  903.   associated with it. For each allocated pointer, 16 bytes are needed
  904.   to store this information. The information itself is stored in a
  905.   collection which can hold a maximum of 16384 pointers. It is easy
  906.   to enlarge this but as yet, there has been no need for that. If you
  907.   should need more, please let me know and I'll enhance  MemCheck.
  908.  
  909.   If possible,  MemCheck  allocates 8 or 16 bytes more for every
  910.   memory block than what your program asked for. Because the
  911.   maximum memory block that can be allocated is 65536-8 bytes,
  912.   MemCheck  always checks if it is possible to allocate 8 or 16 bytes
  913.   more.
  914.  
  915.   ■ If it is possible to allocate 16 bytes more,  MemCheck  is able to
  916.     check for memory overwrites before and after your allocated
  917.     memory block.  MemCheck  does this by filling the first and last 8
  918.     bytes with the value 0CCh. When you dispose this memory
  919.     block,  MemCheck  checks if these values are still there. If not,
  920.     memory has been overwritten and  MemCheck  halts your
  921.     program.
  922.   ■ If it is possible to allocate only 8 bytes more,  MemCheck  only
  923.     checks for overwrites at the end of your memory block.
  924.  
  925.   To recap: every pointer needs 16 bytes to store information about
  926.   it plus an extra 16 (or 8) bytes to check for 'out of range' errors.
  927.   Together, this accounts for the 32 (or 24) bytes extra per allocated
  928.   block. Under protected mode or in Windows, this is not a serious
  929.   problem. Under real mode, however, this could well be a serious
  930.   obstacle in using  MemCheck, especially if your application uses
  931.   many, small memory blocks.
  932.  
  933.  
  934.  
  935. Chapter 2, Checking your memory                                              11
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943. MemCheck and DPMI
  944. ───────────────────────────────────────────────────────────────────────────────
  945.  
  946.   When running under protected mode, as some of you may know,
  947.   you can check for writing outside an allocated memory block by
  948.   setting  HeapLimit  to zero. This will enable the processor's built-in
  949.   segment checking. The problem with this approach is that you can
  950.   easily run out of selectors, especially if you use  MemCheck  at the
  951.   same time. As we've seen above,  MemCheck  allocates a 16 byte
  952.   memory block from the heap for every pointer (and uses that block
  953.   to store information about the pointer). With  HeapLimit  set to zero,
  954.   every allocation actually costs you  two  selectors!
  955.  
  956.  
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992. 12                                                            Borland Pascal Debug Kit Manual
  993.  
  994.  
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001. C            H            A            P            T            E            R
  1002. ───────────────────────────────────────────────────────────────────────────────
  1003.  
  1004.                                                                               3
  1005.  
  1006.  
  1007.  
  1008.                                                            Post Mortem Debugger
  1009.  
  1010.  
  1011.   The Post Mortem Debugger gives you the ability to print full
  1012.   symbolic stack dumps when an error condition occurs in your
  1013.   program. This is a feature you will not want to miss as soon as you
  1014.   have used it to develop programs.
  1015.  
  1016.  
  1017. What the Post Mortem debugger does
  1018. ───────────────────────────────────────────────────────────────────────────────
  1019.  
  1020.   Currently, the name debugger is a bit of a misnomer. The Post
  1021.   Mortem Debugger does nothing more than hooking into the exit
  1022.   procedure chain and dumping the stack, with all procedure names
  1023.   and parameter values, to the log file if an error occurs.
  1024.   If you have enabled the Post Mortem Debugger,  MemCheck  writes
  1025.   actual source file names and line numbers instead of hexadecimal
  1026.   addresses when it creates its report of not disposed memory.
  1027.  
  1028.   An example of the log entries created when a program exits with a
  1029.   fatal error is:
  1030.  
  1031.      ** Program started on 1994-02-26 at 19:07:38 **
  1032.      Post Mortem Debugger (PMD) installed.
  1033.      1994-02-26 19:07:38 Error 215 at 0001:0031
  1034.      1994-02-26 19:07:38 TESTPMD.PAS (26) procedure
  1035.   InSide(100,0,0);
  1036.      1994-02-26 19:07:38 *** Full stack dump ***
  1037.        TESTPMD.PAS (31) procedure
  1038.   TestError((Open,'TESTPMD.BAK'),test2);
  1039.        TESTPMD.PAS (44)
  1040.  
  1041.   This is the log file created if you run the TestPMD program.
  1042.  
  1043.   The advantage of a symbolic stack dump is great, perhaps far
  1044.   greater than you would expect. You find errors much faster due to
  1045.   the full stack trace created. Previously, you could only get such an
  1046.   overview when running inside the debugger. For a frequently
  1047.  
  1048.  
  1049. Chapter 3, Post Mortem Debugger                                              13
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.   called procedure, failing perhaps only every 100th time, it is not
  1058.   really easy (or much fun) to use breakpoints to wait for the correct
  1059.   moment to halt and view the stack.
  1060.  
  1061.   The Post-Mortem debugger has one flaw which shows up
  1062.   sometimes. If the stack trace consists of near calls,  PMD  may not
  1063.   always be able to find the address. As soon as a far call occurs in
  1064.   the stack frame, the stack dump is correct from that point on.
  1065.   Currently we do not know how to fix this. Luckily this case occurs
  1066.   seldom.
  1067.  
  1068.  
  1069. Using the Post Mortem Debugger
  1070. ───────────────────────────────────────────────────────────────────────────────
  1071.  
  1072.   To use the Post Mortem Debugger, you need to include three units
  1073.   in your USES clause. And you need three calls to initialize these
  1074.   three units. The order in which you call these routines is
  1075.   important. The order in which they appear in the USES clause is
  1076.   not important.
  1077.  
  1078.   The three units are  BBError,  ObjMemory  and  PMD. The
  1079.   initialization routines in their correct oder are  InitBBError,
  1080.   InitObjMemory  and  InitPMD.
  1081.  
  1082.   The program listed below, also available as TESTPMD.PAS on
  1083.   your distribution disk, demonstrates the Post Mortem Debugger.
  1084.  
  1085.      {$Q+}
  1086.      program TestPMD;
  1087.  
  1088.      uses
  1089.        BBError, BBUtil,
  1090.        Objects, ObjMemory,
  1091.        {$IFDEF Windows}
  1092.        WinCrt,
  1093.        {$ENDIF}
  1094.        PMD;
  1095.  
  1096.      type
  1097.        types = (test1, test2, test3);
  1098.  
  1099.  
  1100.      procedure  TestError(var  f : text; e : types);
  1101.  
  1102.        procedure  InSide(o : TObjMemory);
  1103.        var
  1104.          w : word;
  1105.          d : word;
  1106.        begin
  1107.          w := 0;
  1108.  
  1109.  
  1110. 14                                                            Borland Pascal Debug Kit Manual
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.          w := w - 1;
  1119.        end;
  1120.  
  1121.      begin
  1122.        InSide(GetObjMemory(100, 0, memfAll)^);
  1123.      end;
  1124.  
  1125.  
  1126.      var
  1127.        f : text;
  1128.      begin
  1129.        writeln(prnCR, 'Post Mortem Debugger tester.');
  1130.  
  1131.      (* initialize *)
  1132.        InitBBError('TESTPMD.LOG', TRUE);
  1133.        InitObjMemory;
  1134.        InitPMD(dfStandard);
  1135.  
  1136.      (* and show the error *)
  1137.        Assign(f, 'TESTPMD.PAS');
  1138.        Reset(f);
  1139.        TestError(f, test2);
  1140.      end.
  1141.  
  1142.   As you can see, there are three initialization routines that must be
  1143.   called before  PMD  can be used:  InitBBError  to open or create a log
  1144.   file,  InitObjMemory  to initialize the memory management routines
  1145.   that  PMD  uses, and (finally)  InitPMD  to initialize the Post Mortem
  1146.   Debugger itself. The  InitPMD  procedure accepts certain flags on
  1147.   which the Post Mortem Debugger bases its behaviour. The default
  1148.   is  dfStandard, you will get only a symbolic stack dump when an
  1149.   error occurs. If you specify the  dfDataSeg  flag as well
  1150.   (InitPMD(dfStandard + dfDataSeg)             ) the datasegment is also dumped
  1151.   to the log file.
  1152.  
  1153.   Compile the example program with full debug information
  1154.   enabled by typing
  1155.  
  1156.        tpc -m -l -v testpmd
  1157.  
  1158.   at the Dos command line prompt. The program contains a
  1159.   delibarate error, namely an overflow bug (therefore it has to be
  1160.   compiled with {$Q+}).. Run it, then look at the created log file
  1161.   TESTPMD.LOG.
  1162.  
  1163.   To use  PMD  you need quite some free memory. For large
  1164.   programs this can be as much as 100K or even more. Under real
  1165.   mode, the Post Mortem Debugger uses EMS or XMS memory if
  1166.   that's available.
  1167.  
  1168.  
  1169.  
  1170. Chapter 3, Post Mortem Debugger                                              15
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178. The Post-Mortem-Debugger under MS-Windows
  1179. ───────────────────────────────────────────────────────────────────────────────
  1180.  
  1181.   Under MS-Windows the Post-Mortem debugger has some extra
  1182.   capabilities including the ability to give a stack dump when a gpf
  1183.   occurs.
  1184.   ─────────────────────────────────────────────────────────────────────────────
  1185.            Extra features    
  1186.   When the  PMD  unit is included in a windows program, you get
  1187.             under Windows    
  1188.   the following extra features: MS-Windows:
  1189.  
  1190.   ■ Any text send to OutputDebugString is written to the log file
  1191.     also.
  1192.   ■ Any error Windows displays, is written to the log file also.
  1193.   ■ If you make a parameter error when calling a Windows
  1194.     function, this is logged. Almost no need for WinScope or
  1195.     BoundsChecker anymore!
  1196.   ─────────────────────────────────────────────────────────────────────────────
  1197.               GPF's under    
  1198.   GPF's are not caught under MS-Windows unlike under DPMI. If
  1199.                   Windows    
  1200.   your program crashes, Windows will still display the UAE dialog
  1201.   box. If you want a symbolic stack dump in this case, you need to
  1202.   call  InstallIntHandler  in the  PMD  unit.
  1203.  
  1204.   InstallIntHandler  is not called by default, because I couldn't get it
  1205.   work right when using the debugger. Without the debugger,
  1206.   everything runs fine. When I use the debugger to examine a
  1207.   program, leave the debugger to go back to the IDE, edit something
  1208.   and recompile, I'm bombed back to Dos, or Windows just hangs. I
  1209.   would be indebted, if anyone has a fix for this.
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230. 16                                                            Borland Pascal Debug Kit Manual
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239. C            H            A            P            T            E            R
  1240. ───────────────────────────────────────────────────────────────────────────────
  1241.  
  1242.                                                                               4
  1243.  
  1244.  
  1245.  
  1246.                                                                          TDInfo
  1247.  
  1248.  
  1249.   The  TDInfo  unit is used by  MemCheck  and  PMD  to provide access
  1250.   to the debug info stored in your executable. Information about this
  1251.   debug info can be found in [Borland92]. You probably need this
  1252.   book if you want to use  TDInfo  yourself.
  1253.   Because this books contains quite a few errors, I refer the reader to
  1254.   appendix A where I've listed OA.TXT, a file containing bugs and
  1255.   omissions to chapter 4 of Borland's "Open Architecture Handbook
  1256.   for Pascal".
  1257.  
  1258.  
  1259. How TDInfo models Borland's Debug Information
  1260. ───────────────────────────────────────────────────────────────────────────────
  1261.  
  1262.   Since the presented information in [Borland92] is less than clear,
  1263.   I've used semantic principles (see [Bekke92]) to make the
  1264.   information contained in the debug symbol tables and their
  1265.   mutual relationships clearer. I'll explain the semantic approach
  1266.   using the Turbo Debug Semantic Model presented in figure 4.1.
  1267.   Semantic data modeling has two notions: types and relationships.
  1268.   Types are basic data elements. Types are not stand-alone, but are
  1269.   related to each other. As can be seen in figure 4.1, types are drawn
  1270.   as rectangles. Relationships between types are drawn as lines.
  1271.   A type can be related to another type in two ways:
  1272.   ■ When a type consists of other types we talk about an aggregated
  1273.     type.
  1274.   ■ When a type is a special kind of another type, we talk about a
  1275.     specialized type.
  1276.   Aggregation can be seen in the Browser type, the uppermost
  1277.   rectangle. Somewhat simplified, aggregation can be said to be
  1278.   equal to the Pascal record type. A record type has a name and
  1279.   consists of various fields. So does the Browser. Each Browser
  1280.                                                               1 to a SourceFile
  1281.   record in the symbol table consists of a pointer
  1282.                          1The Symbol table actually does not store pointers, but record numbers
  1283.  
  1284.  
  1285. Chapter 4, TDInfo                                                            17
  1286.  
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.  
  1294.  
  1295.  
  1296.  
  1297.  
  1298.  
  1299.                Figure 4.1    
  1300.      Turbo Debug Semantic                           Browser
  1301.                     Model                                    
  1302.  
  1303.  
  1304.  
  1305.                                           LineNumber Correlation Symbol
  1306.                                                                      
  1307.                                                                oe───── 
  1308.  
  1309.  
  1310.                                                                            Type
  1311.                                                              Scope
  1312.                                                                                      
  1313.                                                                ───────    
  1314.  
  1315.  
  1316.                            SourceFile       Segment
  1317.                                                      
  1318.  
  1319.  
  1320.  
  1321.                                             Module
  1322.                                                      
  1323.  
  1324.  
  1325.  
  1326.                                              Name
  1327.                                                      
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343. 18                                                            Borland Pascal Debug Kit Manual
  1344.  
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350.  
  1351.   record, a LineNumber record and a Symbol record. The latter
  1352.   record is also an aggregated type. It consists of a pointer to a
  1353.   Module record, a Name record, a Scope record and a Type record.
  1354.   There is no example of specialization in this figure, but
  1355.   specialization can be compared to inheritance in Turbo Pascal.
  1356.  
  1357.   The way the types (records) are drawn is also important. Read
  1358.   from top to bottom, we always find  fixed  properties, i.e. a Browser
  1359.   always  contains a SourceFile. Read from bottom to top, we have
  1360.   optional  properties. Take for example the type Module. A Module
  1361.   can have zero or more Segments. In the same way, a Scope can
  1362.   have zero or more Symbols.
  1363.  
  1364.   The relationships expressed in figure 4.1 show the ways you can
  1365.   access information. If you have a certain line number, you first
  1366.   have to search the correct LineNumber record. If you now want to
  1367.   know in which source file this line appears, then you must first go
  1368.   to the LineNumber's Correlation record and from there to the
  1369.   SourceFile. If you want to know the name of the SourceFile you've
  1370.   found, you can go directly from the SourceFile record to the Name
  1371.   record.
  1372.  
  1373.   In the semantic query language Xplain, we would express this as:
  1374.  
  1375.                           get  LineNumber  its  Correlation  its  SourceFile  its  Name.
  1376.  
  1377.   Note that you can also get the name of the source file in which the
  1378.   line number appears in by going through Correlation  its  Segment
  1379.   its  Module and, finally,  its  Name.
  1380.  
  1381.  
  1382.                                               Changes between Open Architecture names and TD-
  1383. Info names
  1384. ───────────────────────────────────────────────────────────────────────────────
  1385.  
  1386.   The  TDInfo  unit tries to model the debug symbol information as
  1387.   semanticly correct as possible. Each type in TDInfo          is prefixed with
  1388.   a `T'. Note that I have changed some names so that they are not
  1389.   consistent with [Borland92] (which is fairly liberal with naming
  1390.   conventions to say the least).
  1391.  
  1392.   A list of Open Architecture names and TDInfo names is presented
  1393.   below. The TDInfo names refer to objects. The names in the Open
  1394.   Architecture book refer to records. The types are listed in the order
  1395.   they appear in the Open Architecture handbook.
  1396.   Note that almost all fields in TDInfo's object are different from their
  1397.   corresponding names in the Open Architecture Handbook too.
  1398.  
  1399.  
  1400. Chapter 4, TDInfo                                                            19
  1401.  
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407.                 Table 4.1    
  1408.                                TDInfo name            OA name
  1409. List of corresponding TDInfo    
  1410.        names and OA names      TSymbol                TSymbolRecord
  1411.                                TModule                TModuleHeader
  1412.                                TSourceFile            SourceFile
  1413.                                TLineNumber            Line number
  1414.                                TScope                 Scope
  1415.                                TSegment               Segment info
  1416.                                TCorrelation           Typedef
  1417.                                TType                  Type Rec
  1418.                                TMember                Struct offset rec
  1419.                                TClass                 TParent Table (?)
  1420.                                TParent                TParent Table
  1421.                                TOverload              Overload
  1422.                                TScopeClass            TClassTable
  1423.                                TModuleClass           LocalClass
  1424.                                TBrowser               TDefinitionRecord
  1425.  
  1426.  
  1427. How to make use of TDInfo
  1428. ───────────────────────────────────────────────────────────────────────────────
  1429.  
  1430.   In this section some information is given how you can make use of
  1431.   the  TDInfo  unit yourself. The information is this section is not yet
  1432.   complete. You should really take a look at the sources of the PMD
  1433.   unit and the AnnotateLog program (see ANNLOG.PAS, only in
  1434.   the registered version of this program).
  1435.   ─────────────────────────────────────────────────────────────────────────────
  1436.          Initializing the    
  1437.   Before you can make use of TDInfo, you need to initialize it by
  1438.               TDInfo unit    
  1439.   calling the function  TDInfoPresent. Pass  TDInfoPresent  a filename
  1440.   which contains debug information. This file may be a stand-alone
  1441.   symbol file created with TDStrip or an executable with debug
  1442.   information appended to it.  TDInfoPresent  returns TRUE when it
  1443.   has found debug information in the file. Only when it returns
  1444.   TRUE is it save to use the other objects of the  TDInfo  unit.
  1445.   ─────────────────────────────────────────────────────────────────────────────
  1446.                   Getting     information from     a debug symbol    
  1447.   You can almost always directly express a `semantic query' using
  1448.   TDInfo. To get the name of a module, you use TModule.ItsName.
  1449.   To get the scope of a symbol you say TSymbol.ItsScope. These
  1450.   ItsXXXX methods always return a pointer to the object that
  1451.                      file    
  1452.   corresponds with the name of the method.
  1453.  
  1454.   When you call an ItsXXXX method for the first time, a new object
  1455.   of that type is created. When you call the ItsXXXX method for the
  1456.   second time, this object is returned again, so an object is not
  1457.   created twice. You don't have to dispose these pointers, they are
  1458.   disposed by the provider when you dispose the provider, i.e. if
  1459.  
  1460.  
  1461. 20                                                            Borland Pascal Debug Kit Manual
  1462.  
  1463.  
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.   you have called TSymbol.ItsScope, TSymbol.Done disposes the
  1470.   allocated TScope object.
  1471.  
  1472.   Let's take a look at a basic example. Given an physical address,
  1473.              Getting line    
  1474.   how can we display its the source file and line number? The first
  1475.                   numbers    
  1476.   thing we need to do is to turn physical addresses into logical
  1477.   addresses. This is done by calling GetLogicalAddr. A physical
  1478.   address goes in, a logical address comes out. Using this logical
  1479.   address we can now proceed to find the source file and line
  1480.   number. One approach would be to look the logical address up in
  1481.   a .MAP file. Much easier is it to use the debug information
  1482.   appended to an executable.
  1483.   We get the LineNumber by calling the constructor
  1484.   TLineNumber.AtAddr. For example:
  1485.  
  1486.        LineNumber := New(PLineNumber, AtAddr(Addr));
  1487.  
  1488.   LineNumber will be nil if no line number could be found. Else it
  1489.   will contain a pointer to a TLineNumber object. To display the line
  1490.   number we can write LineNumber^.Value. To get the name of the
  1491.   source file, see also figure 4.1, we say
  1492.   LineNumber^.ItsCorrelation^.ItsSourceFile^.ItsName.
  1493.  
  1494.        Getting procedures    
  1495.   To get the procedure to which this line number belongs, we have
  1496.   to know that a procedure is a symbol. To find a symbol at a given
  1497.   address, we can use TSymbol.AtSegment. We need to pass it a
  1498.   PSegment and an address. Because we already have a line number
  1499.   (see the previous section), the segment is
  1500.   LineNumber^.ItsCorrelation^.ItsSegment. The address is simply
  1501.   the logical address. The AtSegment constructor does quite an
  1502.   amount of work. It searches all scope records belonging to a
  1503.   certain segment to find a scope which covers the given address. It
  1504.   does this by calling TSegment.FirstScopeThat. This repeatedly
  1505.   calls the passed function until this function returns true. If this
  1506.   function returns TRUE, TSegment.FirstScopeThat returns the
  1507.   scope record for which the function returned TRUE. Although this
  1508.   is not displayed in figure 4.1, there exists a certain specialization of
  1509.   Scope, which contains a pointer to a Symbol record.
  1510.   TSymbol.AtSegment checks if TSegment.FirstScopeThat has
  1511.   returned such a scope. If that's the case, TSymbol.AtSegment
  1512.   loads the correct symbol record from the debug symbol table and
  1513.   returns.
  1514.   With the Symbol we now have, we have the procedure or function
  1515.   to which this line number belongs. The name of the procedure or
  1516.  
  1517.  
  1518. Chapter 4, TDInfo                                                            21
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.   function is Symbol^.ItsName. To determine of we have a
  1527.   procedure or a function we look at the type of the symbol. If
  1528.   Symbol^.ItsType^.ReturnType = 1 we have a procedure , else we
  1529.   have a function.
  1530.  
  1531.   There is a lot more to say about TDInfo, but this should get you
  1532.   started. In the PMD.PAS, ANNLOG.PAS and MEMCHECK.PAS
  1533.   you find some other or more elaborated uses of TDInfo.
  1534.  
  1535.  
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.  
  1560.  
  1561.  
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567.  
  1568.  
  1569.  
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575. 22                                                            Borland Pascal Debug Kit Manual
  1576.  
  1577.  
  1578.  
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584. C            H            A            P            T            E            R
  1585. ───────────────────────────────────────────────────────────────────────────────
  1586.  
  1587.                                                                               5
  1588.  
  1589.  
  1590.  
  1591.                                                                      Assertions
  1592.  
  1593.  
  1594.   Once you have acquainted yourself with Assertions, you will not
  1595.   want to be without them! The Assertions unit provided here,
  1596.   makes it easy for Borland Pascal programmers to use them. Add
  1597.   Assertions  to the USES clause of any unit or program which wants
  1598.   to use assertions. In your code, simply call the procedure  Assert
  1599.   with a Boolean value and a string containing the message to be
  1600.   printed if the Boolean value evaluates to FALSE. After the message
  1601.   has been printed (which means that the assertion failed), your
  1602.   program halts.
  1603.  
  1604.   Example program:
  1605.  
  1606.      program Example
  1607.  
  1608.      uses
  1609.        BBError,
  1610.        Assertions;
  1611.  
  1612.      begin
  1613.        InitBBError('TEST.LOG', TRUE);
  1614.        Assert(TRUE, 'This assertion passes.');
  1615.        Assert(FALSE, 'This assertion fails.');
  1616.      end.
  1617.  
  1618.   If you call InitBBError     , the message is written to the log file as well.
  1619.   If you use the  PMD  unit (properly initialized!), Assert also prints a
  1620.   symbolic stack trace.
  1621.   You will probably want to use Assertions only in your test code,
  1622.   not in your production code. All Assertions take time and space,
  1623.   and some Assertions take quite a lot of time. That's no problem, or
  1624.   less of a problem, as long as you're working with test code, but
  1625.   your production code should be as fast as possible. Also, you
  1626.   shouldn't need assertions there.
  1627.   To conditionally include Assertions in your program, embrace
  1628.   calls to Assert within a pair of conditional defines. The example
  1629.   program then looks like this:
  1630.  
  1631.  
  1632. Chapter 5, Assertions                                                        23
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.      {$DEFINE Debug}
  1642.      program Example
  1643.  
  1644.      uses
  1645.        BBError
  1646.      {$IFDEF Debug}
  1647.        , Assertions
  1648.      {$ENDIF}
  1649.        ;
  1650.  
  1651.      begin
  1652.        InitBBError('TEST.LOG', TRUE);
  1653.      {$IFDEF Debug}
  1654.        Assert(TRUE, 'This assertion passes.');
  1655.        Assert(FALSE, 'This assertion fails.');
  1656.      {$ENDIF}
  1657.      end.
  1658.  
  1659.   If you enable the Debug directive, the Assertions are included. If
  1660.   you disable the Debug directive, they are not included.
  1661.  
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.  
  1689.  
  1690. 24                                                            Borland Pascal Debug Kit Manual
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711. P                        A                         R                          T
  1712. ───────────────────────────────────────────────────────────────────────────────
  1713.  
  1714.                                                                               2
  1715.  
  1716.  
  1717.  
  1718.                                                                Reference Manual
  1719.  
  1720.  
  1721.  
  1722.  
  1723.  
  1724.  
  1725.  
  1726.  
  1727.  
  1728.  
  1729.  
  1730.  
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744.  
  1745.                                                                                            25
  1746.  
  1747.  
  1748.                  ***************************************
  1749.                    E N D   O F   T H I S   M A N U A L
  1750.                  ***************************************
  1751.  
  1752.  
  1753.     The complete reference manual is distributed with the registered
  1754.     version only. Again, the reference manual looks exactly like to
  1755.     Borland reference manuals.
  1756.  
  1757.     The registered version manual also contains a list of bugs in the
  1758.     Borland Pascal Open Architecture Book, compiled by Andy McFarland.
  1759.  
  1760.  
  1761.