home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume32 / dbmalloc / part05 < prev    next >
Encoding:
Text File  |  1992-09-03  |  55.1 KB  |  1,600 lines

  1. Newsgroups: comp.sources.misc
  2. From: cpcahil@vti.com (Conor P. Cahill)
  3. Subject:  v32i010:  dbmalloc - Debug Malloc Library PL14, Part05/10
  4. Message-ID: <1992Sep4.152142.13264@sparky.imd.sterling.com>
  5. X-Md4-Signature: 16ca4722707e9b9544c6ae8d9c6122dc
  6. Date: Fri, 4 Sep 1992 15:21:42 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: cpcahil@vti.com (Conor P. Cahill)
  10. Posting-number: Volume 32, Issue 10
  11. Archive-name: dbmalloc/part05
  12. Environment: C, UNIX
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 5 (of 10)."
  21. # Contents:  malloc.3 mallocin.h
  22. # Wrapped by cpcahil@virtech on Thu Sep  3 18:39:19 1992
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'malloc.3' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'malloc.3'\"
  26. else
  27. echo shar: Extracting \"'malloc.3'\" \(42916 characters\)
  28. sed "s/^X//" >'malloc.3' <<'END_OF_FILE'
  29. X.TH DEBUG_MALLOC 3 "VTI" "" "1.11"
  30. X.ds ]T 
  31. X'\"/*
  32. X'\" * (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com).
  33. X'\" *
  34. X'\" * This software may be distributed freely as long as the following
  35. X'\" * conditions are met:
  36. X'\" *
  37. X'\" *         * the distribution, or any derivative thereof, may not be
  38. X'\" *          included as part of a commercial product
  39. X'\" *        * full source code is provided including this copyright
  40. X'\" *        * there is no charge for the software itself (there may be
  41. X'\" *          a minimal charge for the copying or distribution effort)
  42. X'\" *        * this copyright notice is not modified or removed from any
  43. X'\" *          source file
  44. X'\" */
  45. X'\" 
  46. X'\" $Id: malloc.3,v 1.28 1992/08/22 16:27:13 cpcahil Exp $
  47. X'\" 
  48. X'\" eX macro -  this macro is used to set up code/picture examples.  It changes
  49. X'\"             the point size & type of font, indents the example 1/2 inch,
  50. X'\"        and turns off fill mode.  To use it just place a .eX before and
  51. X'\"        after your example
  52. X.de eX
  53. X.ie \\n(eX>0 \{\
  54. X.nr eX 0
  55. X.if t .ft
  56. X.fi
  57. X.vs
  58. X.ps
  59. X.in
  60. X.sp \}
  61. X.el \{\
  62. X.nr eX 1
  63. X.br
  64. X.ne 5
  65. X.sp
  66. X.ie \\n(.$>0 .in +\\$1
  67. X.el .in +.5i
  68. X.ie \\n(.$=2 .ps -\\$2
  69. X.el .ps -2
  70. X.ie \\n(.$=2 .vs -\\$2
  71. X.el .vs -2
  72. X.if t .ft CW
  73. X.nf \}
  74. X..
  75. X.nr eX 0
  76. X'\" 
  77. X'\" fake set of VL LI and LE macros for man pages.  This set does handle nested
  78. X'\" calls, but does absolutely NO error checking (so you better do it right).
  79. X'\" 
  80. X.de VL
  81. X.br
  82. X.ie t .nr VL 0\\$1
  83. X.el .nr VL 0\\$1*2
  84. X.ds VS \\$1 \\*(VS
  85. X.in +\\n(VL
  86. X.if t .in +.25i
  87. X..
  88. X.de LI
  89. X.br
  90. X.ti -\\n(VL
  91. X.nr Vw \\n(VLm-\w'\\$1'
  92. X.if \w'\\$1' \&\\$1\h'\\n(Vwu'\&\\c
  93. X..
  94. X.de LE
  95. X.br
  96. X.Le \\*(VS 
  97. X..
  98. X.de Le
  99. X.in -\\n(VL
  100. X.if t .in -.25i
  101. X.ie t .nr VL \\$2
  102. X.el .nr VL \\$2*2
  103. X.ds VS \\$2 \\$3 \\$4 \\$5 \\$6 \\$7
  104. X..
  105. X.ds VS
  106. X.nr VL 0
  107. X.de MP
  108. X.ie t .sp \\n(PDu
  109. X.el .sp
  110. X..
  111. X.de P
  112. X.br
  113. X.ne 4
  114. X.sp
  115. X..
  116. X.SH NAME
  117. Xdbmalloc \- debugging malloc library
  118. X.SH SYNOPSIS
  119. X.nf
  120. X\fB#include <malloc.h>
  121. X.MP
  122. Xint malloc_chain_check(flag);
  123. Xint flag;
  124. X.MP
  125. Xvoid malloc_dump(fd);
  126. Xint fd;
  127. X.MP
  128. Xvoid malloc_list(fd,histid1,histid2);
  129. Xint fd;
  130. Xunsigned long histid1, histid2;
  131. X.MP
  132. Xunsigned long malloc_inuse(histidptr);
  133. Xunsigned long * histidptr;
  134. X.MP
  135. Xvoid malloc_mark(ptr);
  136. Xchar    * ptr;
  137. X.MP
  138. Xint dbmallopt(cmd,val);
  139. Xint cmd; 
  140. Xunion dbmalloptarg val;
  141. X.MP
  142. Xvoid malloc_abort();
  143. X.MP
  144. Xvoid malloc_enter(func);
  145. Xchar * func;
  146. X.MP
  147. Xvoid malloc_leave(func);
  148. Xchar * func;\fP
  149. X.fi
  150. X.SH DESCRIPTION
  151. XThis malloc library is a replacement for the standard library to be used
  152. Xduring software development/debugging.  See the standard malloc(3) pages
  153. Xfor more information on the use of the following functions:
  154. X.MP
  155. X.nf
  156. X.in +.5i
  157. X\fBcalloc\fP(), \fBcfree\fP(), \fBfree\fP(), \fBmalloc\fP(), \fBrealloc\fP()
  158. X.in -.5i
  159. X.fi
  160. X.MP
  161. XThis library differs from the standard malloc library in the
  162. Xfollowing ways:
  163. X.P
  164. X1. Each malloc segment contains a magic number so that free can 
  165. Xverify that the pointer passed points to a valid malloc segment.
  166. X.P
  167. X2. Each malloc segment is filled with a non-zero pattern so that code that
  168. Xdepends upon malloc segments being null will fail.
  169. X.P
  170. X.ne 5
  171. X3. The size of each segment will be at least 1 byte larger than requested
  172. Xand the extra bytes will be filled with a non-zero pattern.  When free is
  173. Xcalled, it will verify that you did not go beyond the number of bytes 
  174. Xyou asked for.
  175. X.P
  176. X4. When a segment is freed, it will be filled with a different non-zero pattern
  177. Xto ensure that the program doesn't depend upon the use of already freed data.
  178. X.P
  179. X.ne 5
  180. X5. Whenever any of the string or memory functions (str*, b*, mem*) are 
  181. Xcalled with a pointer that is within the malloc arena,  the operation is
  182. Xchecked to verify that it does not overrun the malloced segment.  A failure
  183. Xof this check is considered a "warning level error" (described later) and
  184. Xis handled accordingly.
  185. X.P
  186. X6. Run time checking can include verification of the malloc chain at each
  187. Xand every call to one of the malloc functions or manually by calling the
  188. Xmalloc_chain_check function.
  189. X.P
  190. X7. Extensive support for tracking memory leaks is provided.
  191. X.P
  192. X.br
  193. X.ne 15
  194. XWhen a problem is found, the following error message is displayed:
  195. X.eX
  196. XMALLOC Warning from funcname() (called from filename.c line ###):
  197. XWarning message goes here
  198. X.eX
  199. X\fBfuncname\fP is the name of the function that has found the problem
  200. Xand will usually be an entry point into the library.  The information
  201. Xthat identifies where the function is called from will only be 
  202. Xavailable if the source module was compiled with the \fBmalloc.h\fP
  203. Xfile included.
  204. X.P
  205. XIf the error is caused by a problem in the malloc chain and the offending
  206. Xchain element can be identified, the following information is also
  207. Xdisplayed (NOTE: this is just a guess by the software, it may not
  208. Xbe the actual culprit):
  209. X.eX
  210. XThis error is *probably* associated with the following allocation:
  211. X
  212. X   A call to malloc for 33 bytes in program.c on line 834.
  213. X   This was the 172nd call to malloc.
  214. X.eX
  215. X.br
  216. X.ne 15
  217. XThis example assumes that \fBprogram.c\fP included the debugging 
  218. Xlibrary \fBmalloc.h\fP file.  If not, the identification information
  219. Xwill be as follows:
  220. X.eX
  221. XThis error is *probably* associated with the following allocation:
  222. X
  223. X   A call to malloc for 33 bytes in an unknown file.
  224. X   This was the 172nd call to malloc.
  225. X.eX
  226. XThe identification of which call to malloc is associated with the 
  227. Xproblem is helpful in that it gives you the information necessary
  228. Xto set the breakpoint on the allocation function for that particular
  229. Xinvocation (breakpoints usually can have counters associated with
  230. Xthem).  The counters for the three primary allocation entry points (malloc,
  231. Xcalloc, and realloc) are managed separately.
  232. X.P
  233. X.br
  234. X.ne 5
  235. XNOTE 1: if you want to set a breakpoint to capture this invocation
  236. Xof malloc, the actual function that is being called is \fBdebug_malloc\fP
  237. X(or \fBdebug_realloc\fP for \fBrealloc\fP and \fBdebug_calloc\fP for
  238. X\fBcalloc\fP) and that is where the breakpoint should be set.
  239. X.P
  240. X.br
  241. X.ne 19
  242. XNOTE 2: Since the software is guessing at the offending malloc
  243. Xchain segment, it is possible that one of the nearby segments 
  244. Xis actually the culprit.  If the environment variable \s-2MALLOC_SHOW_LINKS\s+2
  245. Xis set, both the segment preceding and the segment following the accused
  246. Xsegment will also be identified.  The following is a sample output:
  247. X.eX
  248. XThis error is *probably* associated with the following allocation:
  249. X
  250. X    A call to malloc for 33 bytes in an unknown file.
  251. X    This was the 172nd call to malloc.
  252. X
  253. X    The malloc chain element prior to the suspect allocation is from:
  254. X
  255. X    A call to calloc for 512 bytes in main.c line 16.
  256. X    This was the 4th call to calloc. 
  257. X    This block was freed on the 2nd call to free()
  258. X    in main.c on line 51.
  259. X    The malloc chain element following the suspect allocation is from: 
  260. X
  261. X    A call to realloc for 4096 bytes in func.c line 376.
  262. X    This was the 1st call to realloc.
  263. X.eX
  264. X.br
  265. X.ne 15
  266. XOnce the error message has been displayed, the software will then 
  267. Xdetermine how to handle the error.  This handling will be based upon
  268. Xthe type of error level (warning or fatal) and the error handling in effect
  269. Xfor that error level (as specified by calls to mallopt or via environment
  270. Xvariables).  The coding for the error handling is as follows:
  271. X.MP
  272. X.VL 3
  273. X.LI "\0\00"
  274. Xcontinue operations
  275. X.LI "\0\01"
  276. Xdrop core and exit
  277. X.LI "\0\02"
  278. Xjust exit
  279. X.LI "\0\03"
  280. Xdrop core, but continue executing.  Core files will
  281. Xbe placed into core.[PID].[counter] i.e: core.00123.001
  282. X.LI "128"
  283. Xdump malloc chain and continue
  284. X.LI "129"
  285. Xdump malloc chain, dump core, and exit
  286. X.LI "130"
  287. Xdump malloc chain, exit
  288. X.LI "131"
  289. Xdump malloc chain, dump core, continue processing
  290. X.LE
  291. X.P
  292. X\fBdbmallopt\fP() is used to set the malloc debugging options. The
  293. Xfollowing options can be set:
  294. X.MP
  295. X.VL 10
  296. X.LI "\s-2MALLOC_WARN\s+2"
  297. Xset the error handling for warning level errors.  \fBval.i\fP is
  298. Xan integer that can contain any one of the following values:
  299. X.MP
  300. X.VL 10
  301. X.LI "\s-2M_HANDLE_IGNORE\s+2"
  302. Xignore error (just display warning message and continue processing)
  303. X.LI "\s-2M_HANDLE_ABORT\s+2"
  304. Xdrop core and exit
  305. X.LI "\s-2M_HANDLE_EXIT\s+2"
  306. Xjust exit (no core drop)
  307. X.LI "\s-2M_HANDLE_CORE\s+2"
  308. Xdrop core, but keep on going
  309. X.LE
  310. X.MP
  311. XIn addition, \s-2M_HANDLE_DUMP\s+2 may be or'd in to cause a dump
  312. Xof the current malloc chain.
  313. X.MP
  314. XThe default action for \s-2MALLOC_WARN\s+2 is \s-2M_HANDLE_IGNORE\s+2.
  315. X.MP
  316. X.LI "\s-2MALLOC_FATAL\s+2"
  317. Xset the error handling for fatal level errors.  \fBval.i\fP is
  318. Xequivalent to \fBval.i\fP for \s-2MALLOC_WARN\s+2.
  319. X.MP
  320. XThe default action for \s-2MALLOC_FATAL\s+2 is \s-2M_HANDLE_ABORT\s+2.
  321. X.MP
  322. X.LI "\s-2MALLOC_ERRFILE\s+2"
  323. Xset the destination for malloc error messages.  \fBval.str\fP
  324. Xis a pointer to a character string containing the name of the file to be used
  325. Xfor error messages.  Note that error messages are \s-1APPENDED\s+1 to this
  326. Xfile, so existing error messages will not be removed.
  327. X.MP
  328. XIf \s-2MALLOC_ERRFILE\s+2 is not set, all error messages will be sent
  329. Xto \fBstderr\fP.
  330. X.MP
  331. X.ne 3
  332. X.LI "\s-2MALLOC_CKCHAIN\s+2"
  333. Xset the malloc chain checking flag.  If \fBval.i\fP is
  334. Xnon-zero, chain checking at every call to malloc is turned on. The 
  335. Xdefault behavior is to not check the chain at each call to malloc because
  336. Xof performance issues (the library is considerably slower when this 
  337. Xfunction is enabled).
  338. X.MP
  339. X.ne 10
  340. X.LI "\s-2MALLOC_FREEMARK\s+2"
  341. Xsets the behavior of freeing of marked areas.  By default, a free of a 
  342. Xmarked segment generates a warning.  If \fBval.i\fP is zero, warnings will
  343. Xnot be generated.
  344. X.MP
  345. X.ne 10
  346. X.LI "\s-2MALLOC_FILLAREA\s+2"
  347. Xset the malloc fill area flag.  \fBval.i\fP specifies the malloc filling
  348. Xmode to be used.   There are four modes: 0, 1, 2 and 3.  Mode 0 disables
  349. Xall filling and checking of filled areas (thereby reducing the effectiveness
  350. Xof the library).  Mode 1 enables the filling of boundary areas before and
  351. Xafter the allocation areas which are used to check for writing before
  352. Xor after the pointer.  Mode 2 includes mode 1 and adds the filling of
  353. Xmalloced regions with a specified fill pattern so that a program does not
  354. Xdepend upon malloced regions to be filled with zeros.  Mode 3 includes
  355. Xall of mode 2 and adds the filling of free'd regions so that an attempt
  356. Xto used a freed data area will result in an error.
  357. X.MP
  358. XAs far as performance is concerned, mode 0 will be the fastest mode, 
  359. Xwhile (somewhat unexpectedly) mode 3 is the next "fastest" mode 
  360. Xwith mode 1 bring up the tail end. 
  361. X.MP
  362. XThe default behavior for \s-2MALLOC_FILLAREA\s+2 is mode 3.
  363. X.MP
  364. X.LI "\s-2MALLOC_LOWFRAG\s+2"
  365. Xset the malloc allocation fragmentation handling level.  By default, malloc
  366. Xuses a first fit algorithm for new allocations.  Under certain allocation
  367. Xscenarios, this can lead to significant memory fragmentation because of
  368. Xthe fact that little allocations can break big blocks up.
  369. X.MP
  370. XIf \fBval.i\fP is non-zero, malloc uses a best fit algorithm which will reduce
  371. Xfragmentation.  This mechanism, while using less memory, is slower because
  372. Xthe entire free list is checked instead of just checking until we find a
  373. Xsegment that is at least big enough.  Normally you will not need to set
  374. Xthis variable.
  375. X.MP
  376. X.LI "\s-2MALLOC_CKDATA\s+2"
  377. Xenable/disable the checking of pointers passed to the memory (mem*,b*) and 
  378. Xstring (str*) functions.  This can be used to startup the code with
  379. Xchecking disabled (when you know the startup code is functioning correctly)
  380. Xand then turn it on later when you get into the area of the code that is 
  381. Xin question.
  382. X.MP
  383. Xif \fBval.i\fP is non-zero, pointer checking is enabled (which is the default
  384. Xmode).
  385. X.MP
  386. X.LI "\s-2MALLOC_REUSE\s+2"
  387. Xenable/disable the reuse of freed segments.  This option can be used to 
  388. Xhelp identify where a freed pointer is being re-used, or where it is being
  389. Xfreed a second time, since the location where it was freed is also kept.
  390. X.MP
  391. XIt should be noted that the memory requirements for a program will typically
  392. Xincrease significantly if this option is used.
  393. X.MP
  394. Xif \fBval.i\fP is zero, freed segments are not reused for subsequent
  395. Xallocations.   If non-zero, freed segments can be reused.  If freed segments
  396. Xare not re-used, you might want to disable filling of freed segments (see
  397. Xthe \s-2MALLOC_FILLAREA\s+2 discussions) so that you can see the data in the
  398. Xsegment - this would be fill mode 2 or below.
  399. X.LE
  400. X.MP
  401. X.ne 10
  402. XFor example, to set up the session to generate a core file for
  403. Xevery malloc warning, to drop core and exit on a malloc fatal, and 
  404. Xto log all messages to the file "malloc_log" do the following:
  405. X.eX
  406. X#include <malloc.h>
  407. Xunion dbmalloptarg  m;
  408. X
  409. Xm.i = M_HANDLE_CORE | M_HANDLE_DUMP;
  410. Xdbmallopt(MALLOC_WARN,m);
  411. X
  412. Xm.i = M_HANDLE_ABORT;
  413. Xdbmallopt(MALLOC_FATAL,m);
  414. X
  415. Xm.str = "malloc_log";
  416. Xdbmallopt(MALLOC_ERRFILE,m);
  417. X.eX
  418. X\fBdbmallopt\fP() can be used to set/alter the debugging options at any
  419. Xtime (i.e. you may want to turn on chain-checking after the program startup if
  420. Xthe program startup does a lot of allocations which are known to be OK).
  421. X.P
  422. X.ne 5
  423. X\fBmalloc_chain_check\fP() will check the status of the malloc arena.
  424. XIf \fBflag\fP is non-zero, an error found in the chain will cause a 
  425. Xfatal error.  \fBmalloc_chain_check\fP() returns zero when there are no
  426. Xproblems found in the malloc chain, non-zero otherwise.
  427. X.P
  428. X.ne 5
  429. X\fBmalloc_dump\fP() will dump a list of all in-use malloc segments 
  430. Xand the first few bytes of each segment.  If the environment variable
  431. X\s-1MALLOC_DETAIL\s+1 is set to a non-zero integer, all segments (including
  432. Xthose that have been freed) are listed and additional internal information
  433. Xis displayed.  \fBfd\fP is the file descriptor to write the data to.
  434. X.P
  435. X.ne 6
  436. X\fBmalloc_list\fP() will dump a list in the same format as \fBmalloc_dump\fP but
  437. Xonly the items that are still in use and which have been allocated within
  438. Xthe malloc history id range specified by \fBhistid1\fP and
  439. X\fBhistid2\fP, inclusive.  The \fBhistid\fPs are obtained from calls
  440. Xto \fBmalloc_inuse\fP(). This is especially useful in tracking down memory
  441. Xleaks.  \fBfd\fP is the file descriptor to write the data to.
  442. X.P
  443. X.ne 6
  444. X\fBmalloc_inuse\fP() returns the amount of malloc data that is currently
  445. Xin use (in bytes).  If \fBhistidptr\fP is not NULL, it is taken to be a pointer
  446. Xto a place to store the current malloc history id which can be used later
  447. Xwhen \fBmalloc_list\fP is called to list items that are still in use.
  448. X.P
  449. X.ne 10
  450. XThe following example shows the typical use of the \fBmalloc_inuse\fP and
  451. X\fBmalloc_list\fP functions in tracking down memory leaks:
  452. X.eX
  453. Xunsigned long    histid1, histid2, orig_size, current_size;
  454. X
  455. Xorig_size = malloc_inuse(&histid1);
  456. X
  457. X/* ..... go do lots of stuff ...... */
  458. X
  459. Xcurrent_size = malloc_inuse(&histid2);
  460. X
  461. Xif( current_size != orig_size )
  462. X{
  463. X    malloc_list(2,histid1,histid2);
  464. X}
  465. X.eX
  466. X\fBmalloc_mark\fP() marks a segment as a non-leak.  Segments that are marked
  467. Xare not counted or listed when dealing with memory leaks.  This is designed
  468. Xto be used on pointers that remain around forever and shouldn't be considered
  469. Xto be a leak (in order to decrease the amount of entries in the leak lists)
  470. X.P
  471. X\fBmalloc_abort\fP() causes the current program to drop core and exit.  This
  472. Xfunction simply calls \fBabort\fP() to do its dirty work and is here solely 
  473. Xfor the purpose of allowing the programmer to substitute thier own abort
  474. Xroutine to handle fatal errors.  If a substitute routine is used, it must not
  475. Xreturn to the caller or else the program will use the \fBabort\fP() system
  476. Xcall to cause the program to stop.
  477. X.P
  478. X\fBmalloc_enter\fP() and \fBmalloc_leave\fP() provide a rudimentary mechanism
  479. Xto track the calling stack that was in place when the allocation was made.
  480. XIn order to use this feature, the enter function should be called upon
  481. Xentry to a function, while the leave function is called when you exit
  482. Xfrom the function.  In order to be accurate, the two functions must be 
  483. Xused in conjunction with each other and a missing call will result in
  484. Xan error generated by the library (if it is detected).
  485. X.P
  486. XNOTE: the argument to either of these functions \fBmust\fP be a constant
  487. Xcharacter string or a static data area.  This is because the stack mechanism
  488. Xdoes not maintain it's own copy of these strings, it just records pointers
  489. Xto the strings and if the strings are on the stack, they will go away.
  490. XTypically the functions would be used with "funcname" as the argument and
  491. Xthis will avoid any problems.
  492. X.P
  493. XThe stack is listed on the dump and/or list reports and on an error 
  494. Xmessage for a segment that has already been freed.
  495. X.P
  496. XIf these functions have been used, error messages will include
  497. Xthe stack information when the identity of the error is 
  498. Xdisplayed.  For example:
  499. X.eX
  500. XThis error is *probably* associated with the following allocation:
  501. X
  502. X    A call to malloc for 1 bytes in teststack.c on line 75.
  503. X    This was the 13th call to malloc.
  504. X    Stack from where allocated:
  505. X     -> sub3() in teststack.c(73)
  506. X     -> sub2() in teststack.c(59)
  507. X     -> main() in teststack.c(23)
  508. X
  509. X.eX
  510. X.br
  511. X.br
  512. X.ne 20
  513. X.SH "USAGE"
  514. XThe library can be used in several modes, each increasingly intrusive (i.e. 
  515. Xrequiring changes to be made to the build process and/or source code).  However,
  516. Xthe extra cost of a little intrusiveness is repaid in much better problem
  517. Xidentification.  Each mode is built upon the previous modes and therefore
  518. Xrequires the changes and/or commands specified in the lower modes.
  519. X.P
  520. X.ne 10
  521. X\fBMODE 1 - library substitution\fP
  522. X.P
  523. XThe simplest use is to just link the object module with the \fBlibdbmalloc.a\fP.
  524. XBe sure to have this library before the C library (\fBlibc.a\fP) on the
  525. Xlink command (this is automatic if you use \fBcc\fP to link and specify the 
  526. Xdebug library without specifying the C library).
  527. X.P
  528. XThis mode links in all of the debug versions of the library modules and
  529. Xwill trap as many errors as it can (yes, there are errors that the malloc
  530. Xlibrary cannot catch).  Environment variables can be used to control the
  531. Xbehavior of the library.
  532. X.P
  533. X.ne 15
  534. X\fBMODE 2 - malloc.h inclusion\fP
  535. X.P
  536. XThis mode involves including the \fBmalloc.h\fP file included with the 
  537. Xdebugging library.  The malloc.h file includes macros that will identify
  538. Xthe source line and file name for each debugging function called.  This
  539. Xis how the library is able to tell you that it was the call to malloc
  540. Xon line 55 in file junk.c.
  541. X.P
  542. X.ne 8
  543. XTypically you should always include malloc.h in your source files and just
  544. Xuse the -I INCLUDEDIR directive for the compiler to point the compiler to
  545. Xthe debugging version of the header file instead of the normal file.  That
  546. Xway you don't have to change the source files when you want to turn off
  547. Xthe debugging library.
  548. X.P
  549. XNOTE: Once you compile code in this mode, you must recompile the code 
  550. Xwithout the debugging malloc.h include file in order to get the software
  551. Xto use the non-debugging functions.
  552. X.P
  553. X.ne 10
  554. X\fBMODE 3 - run-time specification of options\fP
  555. X.P
  556. XEnvironment variables can be used to control the behavior of the debugging
  557. Xlibrary to some extent.  However, this control is very coarse in that
  558. Xyou only have one setting available for the entire running of the program.
  559. X.P
  560. XThis can be a problem if you want to turn on malloc chain checking, but
  561. Xknow that the problem occurs between a relatively narrow portion of the
  562. Xcode and don't want to take the hit of having chain checking on for the
  563. Xentire program execution.  
  564. X.P
  565. X.ne 15
  566. XThe solution to this problem is to include calls to dbmallopt() with the
  567. Xdebugging options which set the appropriate modes when you want them set.
  568. XSince you don't want to have to change the code to remove and add these
  569. Xfunctions every time you decide to include malloc debugging or not, the 
  570. X\fBmalloc.h\fP file defines the preprocessor symbol \s-2_DEBUG_MALLOC_INC\s+2
  571. Xwhich can be used in your code as follows:
  572. X.eX
  573. X#ifdef _DEBUG_MALLOC_INC
  574. X    dbmallopt(.... );
  575. X#endif
  576. X.eX
  577. XIn addition to setting behavior options, you might want to make use of
  578. Xthe memory leak detection routines in this mode.  These calls should
  579. Xalso be surrounded by #ifdefs for the debug malloc symbol so that you
  580. Xcan leave them in the code and automatically get
  581. Xthe increased functionality whenever you compile with the debugging library.
  582. X.P
  583. X.ne 10
  584. X\fBMODE 4 - deeper inclusion of malloc calls\fP
  585. X.P
  586. XThis mode involves inserting calls to the special functions supported
  587. Xby the malloc library (like the leak detection or stack maintenance 
  588. Xroutines).  The effects of the inclusions depends upon the modules
  589. Xincluded and the amount to which they are used. 
  590. X.P
  591. XIt is strongly recommended that you setup your code with the following
  592. Xlines in a header file that is included by all modules, or just add the
  593. Xcode to the beginning of the modules themselves:
  594. X.eX
  595. X#ifndef _DEBUG_MALLOC_INC
  596. X#define malloc_enter(func)
  597. X#define malloc_leave(func)
  598. X#define malloc_chain_check()
  599. X#define malloc_dump(fd)
  600. X#define malloc_list(a,b,c)
  601. X#define malloc_inuse(hist)    (*(hist) = 0, 0)
  602. X#endif
  603. X.eX
  604. XThis will automatically disable the referenced functions when the malloc
  605. Xlibrary is not included (as should be the case when you make a production
  606. Xbuild).
  607. X.br
  608. X.ne 15
  609. X.SH "ENVIRONMENT VARIABLES"
  610. XEnvironment variables can be used to control error handling, error logging
  611. Xand malloc chain checking at run time.  Most of these environment variables
  612. Xcan be set via the \fBdbmallopt\fP() routine and are well described in 
  613. Xthat portion of the document.  Look for further information there.
  614. X.MP
  615. XThe following environment variables are used:
  616. X.P
  617. X.VL 10
  618. X.br
  619. X.ne 4
  620. X.LI "\s-2MALLOC_BOUNDSIZE\s+2"
  621. XThis specifies the minimum number of bytes that the allocation routines
  622. Xwill leave unused at the end of each segment.  This value may be
  623. Xany non-zero positive integer (although you must remember that the
  624. Xamount of memory used is directly related to this buffer area.
  625. X.MP
  626. XIt may be necessary to increase this value if you think you have a module
  627. Xthat is writing far enough beyond its malloc segment that it changes the
  628. Xnext segment (and therefore doesn't make a change that this library
  629. Xwould be able to detect.
  630. X.MP
  631. XThe default for this value is 1 (although because of memory alignment
  632. Xissues, you will usually have more than one byte of filler at the
  633. Xend of most segments).
  634. X.br
  635. X.ne 4
  636. X.LI "\s-2MALLOC_CKCHAIN\s+2"
  637. Xif 1, turns on malloc chain checking at every call to any
  638. Xof the malloc functions.
  639. X.br
  640. X.ne 4
  641. X.LI "\s-2MALLOC_DETAIL\s+2"
  642. Xif set to a non-zero integer, \fBmalloc_dump\fP shows some internal
  643. Xdetail for each 
  644. Xentry in the chain.  This info is probably only of use if you are debugging 
  645. Xthe malloc library itself.
  646. X.br
  647. X.ne 4
  648. X.LI "\s-2MALLOC_ERRFILE\s+2"
  649. Xspecifies the error log file for error messages.  Error messages generated
  650. Xby the library are \fBAPPENDED\fP to this file, so if you want a clean file,
  651. Xyou will have to remove or empty it yourself between runs.  If this option
  652. Xis used, no indication of an error will be sent to stdout or stderr (this 
  653. Xis purposefully done this way so that if you are running a full screen 
  654. Xprogram, it doesn't mess up the screen).
  655. X.br
  656. X.ne 4
  657. X.LI "\s-2MALLOC_FATAL\s+2"
  658. Xspecifies the error handling for fatal errors
  659. X.br
  660. X.ne 4
  661. X.LI "\s-2MALLOC_FILLAREA\s+2"
  662. Xspecifies the fill area flag setting.  If zero, malloc/free area filling 
  663. Xand checking is disabled (thereby increasing performance, while decreasing
  664. Xeffectiveness of the library).  See the discussion of the \fBdbmallopt\fP()
  665. Xarguments for more info on other settings.
  666. X.br
  667. X.ne 5
  668. X.LI "\s-2MALLOC_FILLBYTE\s+2"
  669. XThis specifies the integer value of the character to use when filling
  670. Xallocated areas.  This value defaults to 1 and must be within the range
  671. Xof 0 - 255. This capability is useful if you believe that you are 
  672. Xhaving a problem with code that is trashing its malloc region with
  673. Xa data pattern that matches the default fill pattern.
  674. X.MP
  675. XNOTE: if an attempt is made to use a value outside the specified
  676. Xrange, the new value is \fBsilently\fP ignored and the default is used.
  677. X.br
  678. X.ne 5
  679. X.LI "\s-2MALLOC_FREEBYTE\s+2"
  680. XThis specifies the integer value of the character to use when filling
  681. Xfreed areas.  This value defaults to 1 and must be within the range
  682. Xof 0 - 255. It should also be different from \s-2MALLOC_FILLBYTE\s+2, but
  683. Xthat is not enforced. 
  684. X.MP
  685. XNOTE: if an attempt is made to use a value outside the specified
  686. Xrange, the new value is \fBsilently\fP ignored and the default is used.
  687. X.br
  688. X.ne 4
  689. X.LI "\s-2MALLOC_LOWFRAG\s+2"
  690. Xif 1, turns on best fit allocation algorithm.  Otherwise, first fit algorithm
  691. Xis used for finding allocation segments (which can cause memory fragmentation).
  692. X.br
  693. X.ne 4
  694. X.LI "\s-2MALLOC_CKDATA\s+2"
  695. Xif 0, disables checking of pointers passed to string/memory functions for
  696. Xmalloc region overwrites.
  697. X.br
  698. X.ne 4
  699. X.LI "\s-2MALLOC_REUSE\s+2"
  700. Xif 0, disables reuse of freed memory segments and it does not fill free'd
  701. Xsegments with the fill pattern.  If 1, freed segments are filled and they can
  702. Xbe reused.  If 2, freed segments can be reused, but they are not filled when
  703. Xfreed.
  704. X.br
  705. X.ne 4
  706. X.LI "\s-2MALLOC_SHOW_LINKS\s+2"
  707. Xwhen an error is found, the suspected allocation is
  708. Xdisplayed.  However, since it is possible that the next or previous allocation
  709. Xin the malloc chain was the actual culprit these links may be of interest.
  710. XIf this variable is set to a non-zero integer (i.e. 1) the links will also
  711. Xbe shown.
  712. X.br
  713. X.ne 2
  714. X.LI "\s-2MALLOC_WARN\s+2"
  715. Xspecifies the error handling for warning errors
  716. X.LE
  717. X.P
  718. X.ne 5
  719. XAs an example, to set up the session to generate a core file for
  720. Xevery malloc warning, to drop core and exit on a malloc fatal, and 
  721. Xto log all messages to the file "malloc_log" do the following:
  722. X.eX
  723. XMALLOC_WARN=131
  724. XMALLOC_FATAL=1
  725. XMALLOC_ERRFILE=malloc_log
  726. X
  727. Xexport MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE
  728. X.eX
  729. X.br
  730. X.ne 15
  731. X.SH "ERROR MESSAGES"
  732. XThe following error messages are reported by the library:
  733. X.VL 15
  734. X.br
  735. X.MP
  736. X.ne 6
  737. X.LI "\s-2M_CODE_BAD_CONNECT\s+2"
  738. XPointers between this segment and adjoining segments are invalid.
  739. X.MP
  740. XThis error indicates that the malloc chain has been corrupted.
  741. XThis is most often caused by an overwrite of the malloc header
  742. Xby an access via the previous malloc segment.
  743. X.br
  744. X.MP
  745. X.ne 6
  746. X.LI "\s-2M_CODE_BAD_MAGIC\s+2"
  747. XMalloc region does not have a valid magic number in header.
  748. X.MP
  749. XThis error is caused by several mechanisms including \fBfree\fP()ing
  750. Xthe same pointer twice or a pointer that was not returned by \fBmalloc\fP(),
  751. Xor writing beyond the end of a segment.
  752. X.br
  753. X.MP
  754. X.ne 6
  755. X.LI "\s-2M_CODE_BAD_PTR\s+2"
  756. XPointer is not within malloc region.
  757. X.MP
  758. XThe pointer passed to \fBfree\fP or\fPrealloc\fP is not pointer 
  759. Xreturned by \fBmalloc\fP.  Another cause is corruption of the
  760. Xmalloc chain by writing beyond the end of a segment.
  761. X.br
  762. X.MP
  763. X.ne 6
  764. X.LI "\s-2M_CODE_CHAIN_BROKE\s+2"
  765. XMalloc chain is corrupted, pointers out of order.
  766. X.MP
  767. XCorruption has been detected in the malloc chain that is
  768. Xrelated to the relative positions of the malloc chain segments
  769. Xin memory.  This is an indication that someone has overwritten
  770. Xbeyond the amount they allocated.
  771. X.br
  772. X.MP
  773. X.ne 6
  774. X.LI "\s-2M_CODE_FREELIST_BAD\s+2"
  775. XMalloc segment in free list is in-use.
  776. X.MP
  777. XA segment that is in the free-list is flagged as in-use.  This is usually
  778. Xcaused by overwriting from the previous segment in the malloc chain.
  779. X.br
  780. X.MP
  781. X.ne 6
  782. X.LI "\s-2M_CODE_FREEMARK\s+2"
  783. XFree called to free a segment that has been marked.
  784. X.MP
  785. XMarking a segment is done because you believe that the segment will not be
  786. Xfree'd and therefore don't want it to appear in the list of possible leaks.
  787. XIf you then go on to free it, perhaps it shouldn't have been marked.  
  788. X.MP
  789. XThis error message can be disabled with the MALLOC_FREEMARK option on 
  790. Xthe \fBdbmallopt\fP() function.
  791. X.br
  792. X.MP
  793. X.ne 6
  794. X.LI "\s-2M_CODE_NOBOUND\s+2"
  795. XUnable to determine doubleword boundary
  796. X.MP
  797. XThe code was unable to figure out the boundary requirements for a doubleword.
  798. XThis error should never occur.
  799. X.br
  800. X.MP
  801. X.ne 6
  802. X.LI "\s-2M_CODE_NOMORE_MEM\s+2"
  803. XUnable to get additional memory from the system.
  804. X.MP
  805. XThe system call \fBsbrk\fP failed to obtain more memory
  806. Xfor the program.
  807. X.br
  808. X.MP
  809. X.ne 6
  810. X.LI "\s-2M_CODE_NOT_INUSE\s+2"
  811. XData is not in use (can't be freed or reallocated).
  812. X.MP
  813. XA pointer to a malloc segment has been passed to \fBfree\fP() or
  814. X\fBrealloc\fP(), but this segment has already been freed.
  815. X.br
  816. X.MP
  817. X.ne 6
  818. X.LI "\s-2M_CODE_NO_END\s+2"
  819. XMalloc chain is corrupted, end before end pointer.
  820. X.MP
  821. XYet another overwrite problem.   This error means that we got to 
  822. Xwhat we believe is the end of the chain, but it does not match
  823. Xthe recorded end of the chain.
  824. X.br
  825. X.MP
  826. X.ne 6
  827. X.LI "\s-2M_CODE_OUTOF_BOUNDS\s+2"
  828. XPointer within malloc region, but outside of malloc data bounds.
  829. X.MP
  830. XThis is caused by a call to one of the string/memory functions
  831. Xthat attempt to read/write bytes that are not included in
  832. Xthe allocation associated with that memory.  This is the
  833. Xmost typical error that you will see from the malloc library.
  834. X.br
  835. X.MP
  836. X.ne 6
  837. X.LI "\s-2M_CODE_OVERRUN\s+2"
  838. XData has overrun beyond requested number of bytes.
  839. X.MP
  840. XThis error is detected by \fBfree\fP() and indicates that the
  841. Xcurrent segment has written data beyond the number of bytes that
  842. Xit requested.  This only catches overwrites when they are within
  843. Xthe extra space allocated with each segment (this can range from
  844. Xone to eight bytes).  If the overwrite occurs further along it
  845. Xwill usually cause some corruption in the malloc chain.
  846. X.br
  847. X.MP
  848. X.ne 6
  849. X.LI "\s-2M_CODE_REUSE\s+2"
  850. XData in free'd area has been modified.
  851. X.MP
  852. XData in a freed segment has been modified.  This usually indicates
  853. Xthat the program is using a pointer after it called free, but it
  854. Xmay also be caused by an overwrite from a previous segment in 
  855. Xthe chain.
  856. X.br
  857. X.MP
  858. X.ne 6
  859. X.LI "\s-2M_CODE_STK_BADFUNC\s+2"
  860. XCurrent function name doesn't match name on stack.
  861. X.MP
  862. X\fBmalloc_leave\fP() was called with a function name that is not
  863. Xthe current function.  This is usually caused by a missing call
  864. Xto \fBmalloc_enter\fP() in the same function, or a missing call
  865. Xto \fBmalloc_leave\fP() in a sub-function.
  866. X.br
  867. X.MP
  868. X.ne 6
  869. X.LI "\s-2M_CODE_STK_NOCUR\s+2"
  870. XNo current function on stack, probably missing call to malloc_enter().
  871. X.MP
  872. X\fBmalloc_leave\fP() was called with a function name and there is 
  873. Xno current function (the stack is empty). This is usually caused
  874. Xby a missing call to \fBmalloc_enter\fP(), or an extra call to 
  875. X\fBmalloc_leave\fP() in the same function.
  876. X.br
  877. X.MP
  878. X.ne 6
  879. X.LI "\s-2M_CODE_UNDERRUN\s+2"
  880. XData has written before beginning of requested bytes.
  881. X.MP
  882. XThis error is detected by \fBfree\fP() and indicates that the current
  883. Xsegment has written data before the beginning of the requested block.
  884. XThis only catches overwrites when they are within the extra space
  885. Xallocated before each segment (this is usually four bytes).  If the
  886. Xoverwrite occurs further back it will usually cause some corruption in
  887. Xthe malloc chain.
  888. X.br
  889. X.MP
  890. X.ne 6
  891. X.LI "\s-2M_CODE_ZERO_ALLOC\s+2"
  892. XAn allocation routine was called to allocate zero bytes.
  893. X.MP
  894. XWhile ANSI C requires that allocations of zero bytes are permissible and
  895. Xshould be supported, the behavior of such an operation can be undefined on
  896. Xnon-ANSI systems.  This warning will alert you to the locations where these
  897. Xcalls are made.
  898. X.MP
  899. XThis error message can be disabled with the MALLOC_ZERO option on 
  900. Xthe \fBdbmallopt\fP() function.
  901. X.LE
  902. X.P
  903. X.br
  904. X.ne 15
  905. X.SH "DUMP OUTPUT"
  906. XSample dump/list output:
  907. X.eX
  908. X************************** Dump of Malloc Chain ****************************
  909. XPOINTER     FILE  WHERE         LINE      ALLOC        DATA     HEX DUMP   
  910. XTO DATA      ALLOCATED         NUMBER     FUNCT       LENGTH  OF BYTES 1-7 
  911. X-------- -------------------- ------- -------------- ------- --------------
  912. X0x403DB4 teststack.c               75 malloc(1)           40 01010101010101  
  913. X         -> sub3() in teststack.c(73)
  914. X         -> main() in teststack.c(23)
  915. X0x403E0C testerr.c                 16 realloc(1)          20 01010101010101  
  916. X.eX
  917. XThe info in each column is as follows:
  918. X.MP
  919. X.VL 10
  920. X.br
  921. X.ne 4
  922. X.LI "\s-2POINTER\s+2"
  923. Xthe pointer returned by the allocation function (the pointer
  924. Xthe the allocated data area).
  925. X.MP
  926. X.br
  927. X.ne 8
  928. X.LI "\s-2FILE\s+2"
  929. Xthe name of the file where the allocation function was called.  This
  930. Xinformation is only available if the source file includes the \fBmalloc.h\fP
  931. Xfile from this library (as opposed to the system include file).  If
  932. Xthe source file did not include this file, the file will be listed
  933. Xas unknown and the line number will be blank.
  934. XNote that any malloc calls from system libraries will probably not have been
  935. Xcompiled with the \fBmalloc.h\fP file included and will therefore
  936. Xappear as unknown.
  937. X.MP
  938. X.br
  939. X.ne 4
  940. X.LI "\s-2LINE NUM\s+2"
  941. XThe line number of the line that called the allocation function.  This 
  942. Xfield will be left blank if the \fBmalloc.h\fP from this library
  943. Xwas not included in the source file when it was compiled. 
  944. X.MP
  945. X.br
  946. X.ne 5
  947. X.LI "\s-2ALLOC FUNC\s+2"
  948. XThe allocation function called: \fBmalloc\fP, \fBrealloc\fP, or \fBcalloc\fP.
  949. XThe number in parenthesis following the function name is the call number
  950. Xfor that particular function.  For example: malloc(1) means that this
  951. Xallocation was the 1st call to malloc.
  952. X.MP
  953. X.br
  954. X.ne 2
  955. X.LI "\s-2DATA LEN\s+2"
  956. XThe number of bytes allocated.
  957. X.MP
  958. X.br
  959. X.ne 6
  960. X.LI "\s-2HEX DUMP\s+2"
  961. XA hexadecimal dump of the first seven bytes in the allocated data.  This example
  962. Xshows the bytes filled with 0x01s which happen to be the fill pattern used
  963. Xby the malloc library (to make sure that one doesn't depend upon the 
  964. Xfact that some calls to malloc result in NULL bytes).  So the
  965. Xallocations that are shown haven't stored any data in the area yet.
  966. X.LE
  967. X.MP
  968. XThe lines that begin with a "->" are stack dump lines which show the
  969. Xcalling environment that was present when the are was allocated.  The
  970. Xenvironment is managed via the use of the \fBmalloc_enter\fP() and 
  971. X\fBmalloc_leave\fP() routines.
  972. X.MP
  973. X.br
  974. X.ne 15
  975. XIf the environment variable \s-2MALLOC_DETAIL\s+2 is non-zero, the 
  976. Xfollowing additional information will be included:
  977. X.eX
  978. X************************************************************** Du... 
  979. X                             FREE     FREE                  ACTUAL SIZE    ...
  980. X  PTR      NEXT     PREV     NEXT     PREV      FLAGS       INT    HEX     ...
  981. X-------- -------- -------- -------- -------- ---------- -------- --------- ...
  982. X0x403C94 0x403CEC 0x40326C 0x000000 0x000000 0x03156111       48(0x000030) ...
  983. X0x403CEC 0x403D2C 0x403C94 0x000000 0x000000 0x03156121       24(0x000018) ...
  984. X0x403D2C 0x403D6C 0x403CEC 0x000000 0x403D6C 0x03156120       24(0x000018) ...
  985. X0x403D6C 0x000000 0x403D2C 0x403D2C 0x000000 0x03156120       24(0x000018) ...
  986. X
  987. XMalloc start:      0x40326C
  988. XMalloc end:        0x403D2C
  989. XMalloc data start: 0x403C94
  990. XMalloc data end:   0x405C94
  991. XMalloc free list:  0x403D6C
  992. X                -> 0x403D2C
  993. X.eX
  994. XNOTE that I cut off the example at the point where the normal output
  995. Xwould begin (hence the ...).
  996. X.MP
  997. XThe info in each column is as follows:
  998. X.MP
  999. X.VL 8
  1000. X.LI "\s-2PTR\s+2"
  1001. XThe malloc chain pointer for the segment (the address of the segment).
  1002. X.MP
  1003. X.LI "\s-2NEXT\s+2"
  1004. XThe pointer to the next segment in the chain.
  1005. X.MP
  1006. X.LI "\s-2PREV\s+2"
  1007. XThe pointer to the previous segment in the chain.
  1008. X.MP
  1009. X.LI "\s-2FREE NEXT\s+2"
  1010. XThe pointer to the next segment in the free list.
  1011. X.MP
  1012. X.LI "\s-2FREE PREV\s+2"
  1013. XThe pointer to the previous segment in the free list.
  1014. X.MP
  1015. X.ne 10
  1016. X.LI "\s-2FLAGS\s+2"
  1017. XThe flags associated with this segment.  This is a long
  1018. Xinteger which contains the following fields
  1019. X.MP
  1020. X.VL 6
  1021. X.LI "0xFFFFFF00"
  1022. Xthe magic number.  This should be 0x03156100 (probably 
  1023. Xsomeone's birthday).
  1024. X.MP
  1025. X.LI "0x00000070"
  1026. Xthe type of allocation function. Malloc (x010), realloc (0x20), or
  1027. Xcalloc (0x30) are the only valid values for this field).
  1028. X.MP
  1029. X.LI "0x00000001"
  1030. Xthe in-use flag.  if this value is non-zero, the indicated segment
  1031. Xis currently in use (not freed).
  1032. X.LE
  1033. X.MP
  1034. X.LI "\s-2ACTUAL SIZE\s+2"
  1035. XThe actual size reserved for the allocation in both decimal and
  1036. Xhex.  This will be at least one byte more than the requested size, and
  1037. Xas much as 8, so that we can check to see if the allocation has been
  1038. Xoverrun.
  1039. X.LE
  1040. X.MP
  1041. X.ne 4
  1042. XMalloc \fBstart\fP and \fBend\fP are pointers to the first and
  1043. Xlast malloc chain segment, respectively.
  1044. X.MP
  1045. X.ne 4
  1046. XMalloc \fBdata start\fP and \fBdata end\fP are the lowest and highest
  1047. Xdata bytes managed my the malloc sub-system.  These are only used as
  1048. Xa quick check to see if a pointer is in the malloc region before we
  1049. Xgo hunting down the chain trying to identify the segment it belongs to.
  1050. X.MP
  1051. X.ne 4
  1052. XMalloc \fBfree list\fP is a chain of the elements in the free list (so 
  1053. Xit is easier for the programmer to follow the free list if they choose 
  1054. Xto).  The address of each element in the list follows below the list head.
  1055. X.br
  1056. X.ne 15
  1057. X.SH "X PROGRAM DEBUGGING"
  1058. XThe malloc library includes a set of compatibility routines for the 
  1059. XXt toolkit allocation routines: \fBXtMalloc\fP(), \fBXtCalloc\fP(),
  1060. X\fBXtRealloc\fP(),and \fBXtFree\fP().   These routines provide the
  1061. Xsame level of malloc area integrity checking that is provided by
  1062. Xthe basic malloc functions while maintaining complete compatibility
  1063. Xwith the X11R5 functions.
  1064. X.P
  1065. XIf you link an X package with the debug library and you make a call
  1066. Xto any of the Xt allocation routines, the debug modules will automatically
  1067. Xbe included.  If you don't call them directly, but you still want to
  1068. Xinclude them in order to better debug their use, you can add a -u
  1069. Xlinker specification for XtRealloc.  For example:
  1070. X.eX
  1071. Xcc -o xapp -u XtRealloc xapp.o -ldbmalloc -lXt -lX....
  1072. X.eX
  1073. XNote that you may have to add an underscore before the XtRealloc if your
  1074. Xcompiler does this automatically.
  1075. X.P
  1076. XA second potential problem with X is caused by a difference between
  1077. XX11R4 and X11R5.  If you only have one of theses packages, then the
  1078. Xmalloc library will be automatically configured to handle that package.
  1079. XIf, however, you have both of them installed and you need to be able
  1080. Xto link with either system, you may have to add a -u _XtHeapInit to
  1081. Xthe link line on the X11R5 links.  This is because X11R5 defines both
  1082. Xthe heap management and malloc management routines in the same 
  1083. Xmodule, while X11R4 defines them in different modules.
  1084. X.P
  1085. XThe sign of this problem is a link error due to duplicate references
  1086. Xto the Xt allocation routines (XtMalloc, etc).
  1087. X.SH LINKING
  1088. XThe order in which you link your programs can have a significant effect
  1089. Xon the usefulness of the library and even on the ability to link itself.
  1090. XThe debug library should be placed as the first system library that you are
  1091. Xlinking to (assuming that you are calling at least one of the malloc, string,
  1092. Xor memory functions).
  1093. X.P
  1094. XFor example, if the following is your normal link command:
  1095. X.eX
  1096. Xcc -o app app.o supp.o else.o applib.a -lmath -lcurses
  1097. X.eX
  1098. XYou should add the malloc debug library in between applib.a and -lmath, 
  1099. Xwhich would result in the following:
  1100. X.eX
  1101. Xcc -o app app.o supp.o else.o applib.a -ldbmalloc -lmath -lcurses
  1102. X.eX
  1103. XThis will ensure that the debug malloc library overrides all of the allocation
  1104. Xroutines within the other libraries.  
  1105. X.P
  1106. XIf you have other problems compiling or linking with the library you should
  1107. Xlook at the \s-2PROBLEMS\s+2 file in the source directory.  This file 
  1108. Xcontains descriptions of common problems and the recommended solutions to
  1109. Xthe problems.
  1110. X.SH PERFORMANCE
  1111. XThis malloc library and its associated string and memory functions are
  1112. Xmuch less efficient than the standard functions due in part to the extra
  1113. Xerror checking.  You do not want to use this library when generating a
  1114. Xproduction (i.e. releasable) version of your software.  It should only
  1115. Xbe used during development and testing.
  1116. X.P
  1117. X.ne 10
  1118. XThe following environment variable settings will give you the best
  1119. Xperformance (at the expense of some additional error checking):
  1120. X.eX
  1121. XMALLOC_CKCHAIN=0
  1122. XMALLOC_CKDATA=0
  1123. XMALLOC_FILLAREA=0
  1124. XMALLOC_LOWFRAG=0
  1125. X.eX
  1126. XWe recommend against setting MALLOC_FILLAREA to zero because, while
  1127. Xit will increase the performance, it takes away the capability
  1128. Xto uncover small malloc overruns which don't overrite the pointers surrounding
  1129. Xthe malloc regions.  The same anti-recommendation applies to MALLOC_CKDATA.
  1130. X.P
  1131. X.ne 5
  1132. XAnyway, with these settings, the malloc library runs at about 1/2 the
  1133. Xspeed (things only take twice as long) as the standard library.  If you program
  1134. Xspends most of its time in malloc, it will still be slow (but perhaps this is
  1135. Xan indication that you need to consider changing the way you are using 
  1136. Xmalloc).
  1137. X.br
  1138. X.ne 15
  1139. X.SH WARNINGS
  1140. XThe include file for this library "malloc.h" should be included after
  1141. Xthe includes for any system related information.  This is because "malloc.h"
  1142. Xredefines several system functions including string and memory routines
  1143. Xand this will usually cause compilation errors if malloc.h is processed
  1144. Xfirst (of course, the compile errors will talk about errors in the other
  1145. Xsystem include files like string.h).
  1146. X.P
  1147. XThis goes hand in hand with the fact that if you have local definitions of
  1148. Xthe return types of standard functions like strcmp() or malloc(), 
  1149. Xthese lines will cause compile errors due to the #defines in the
  1150. Xmalloc.h header file.  Therefore, it is suggested that you remove
  1151. Xall such definitions from your code and rely on the system header
  1152. Xfiles to define these functions, or you surround the definitions 
  1153. Xwith #ifdef \s-2DEBUG_MALLOC_INC\s+2.
  1154. X.P
  1155. XThere is a possibility that the use of \fBsbrk\fP() by other modules
  1156. Xwill cause this library to get confused and possibly report 
  1157. Xsome pointers as bad when the really aren't part of the malloc chain
  1158. Xitself.  Therefore the direct use of \fBsbrk\fP() is strongly discouraged.
  1159. X.P
  1160. XThis library attempts to trap errors and exit/handle them gracefully.  
  1161. XHowever, the nature of the problems may be such that it causes the 
  1162. Xcode in the library itself to crash.  There is no way to avoid this,
  1163. Xbut if it does occur,  turn on chain checking to narrow the place where
  1164. Xit will occur.
  1165. X.P
  1166. XThe functions in this library will often conflict with duplicate functions
  1167. Xin shared library versions of libc.a.  This is usually due to the 
  1168. Xfact that some shared library modules have explicit references to shared
  1169. Xlibrary versions of the debug functions.  The only way around this is
  1170. Xto not use the shared library when linking.
  1171. X.P
  1172. XThis malloc library, like most malloc libraries, is not re-entrant 
  1173. Xand therefore should not be called from interrupt handlers because of the
  1174. Xpotential for receiving an interrupt in the middle of a call to malloc
  1175. Xwhich would really mess things up.
  1176. X.SH SEE ALSO
  1177. Xmalloc(3), string(3), memory(3)
  1178. X.br
  1179. X.ne 10
  1180. X.SH COPYRIGHT
  1181. X.nf
  1182. X (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
  1183. X
  1184. X This software may be distributed freely as long as the following conditions
  1185. X are met:
  1186. X        * the distribution, or any derivative thereof, may not be
  1187. X          included as part of a commercial product
  1188. X        * full source code is provided including this copyright
  1189. X        * there is no charge for the software itself (there may be
  1190. X          a minimal charge for the copying or distribution effort)
  1191. X        * this copyright notice is not modified or removed from any
  1192. X             source file
  1193. X
  1194. X.fi
  1195. X.br
  1196. X.ne 10
  1197. X.SH AUTHOR
  1198. X.nf
  1199. XConor P. Cahill
  1200. XVirtual Technologies Incorporated
  1201. X46030 Manekin Plaza, Suite 160
  1202. XSterling VA 22170
  1203. X703-430-9247
  1204. X.MP
  1205. Xcpcahil@virtech.vti.com
  1206. Xuunet!virtech!cpcahil
  1207. END_OF_FILE
  1208. if test 42916 -ne `wc -c <'malloc.3'`; then
  1209.     echo shar: \"'malloc.3'\" unpacked with wrong size!
  1210. fi
  1211. # end of 'malloc.3'
  1212. fi
  1213. if test -f 'mallocin.h' -a "${1}" != "-c" ; then 
  1214.   echo shar: Will not clobber existing file \"'mallocin.h'\"
  1215. else
  1216. echo shar: Extracting \"'mallocin.h'\" \(9557 characters\)
  1217. sed "s/^X//" >'mallocin.h' <<'END_OF_FILE'
  1218. X/*
  1219. X * (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
  1220. X *
  1221. X * This software may be distributed freely as long as the following conditions
  1222. X * are met:
  1223. X *         * the distribution, or any derivative thereof, may not be
  1224. X *          included as part of a commercial product
  1225. X *        * full source code is provided including this copyright
  1226. X *        * there is no charge for the software itself (there may be
  1227. X *          a minimal charge for the copying or distribution effort)
  1228. X *        * this copyright notice is not modified or removed from any
  1229. X *          source file
  1230. X */
  1231. X/*
  1232. X * $Id: mallocin.h,v 1.27 1992/09/03 22:24:33 cpcahil Exp $
  1233. X */
  1234. X#ifndef _MALLOCIN_H
  1235. X#define _MALLOCIN_H 1
  1236. X
  1237. X/*
  1238. X * this file contains macros that are internal to the malloc library
  1239. X * and therefore, are not needed in malloc.h.
  1240. X */
  1241. X
  1242. X#if POSIX_HEADERS
  1243. X#include <unistd.h>
  1244. X#endif
  1245. X#if ANSI_HEADERS
  1246. X#include <stdlib.h>
  1247. X#endif
  1248. X
  1249. X#ifndef SYS_TYPES_H_INCLUDED
  1250. X#include <sys/types.h>
  1251. X#endif
  1252. X
  1253. X#define IN_MALLOC_CODE    1
  1254. X#include "sysdefs.h"
  1255. X#include "malloc.h"
  1256. X
  1257. X#define IDTYPE unsigned long
  1258. X#define ULONG  unsigned long
  1259. X
  1260. X/*
  1261. X * Data structures used by stack mechanism
  1262. X */
  1263. Xstruct stack
  1264. X{
  1265. X    struct stack    * beside;
  1266. X    struct stack    * below;
  1267. X    struct stack     * above;
  1268. X    CONST char    * func;
  1269. X    CONST char    * file;
  1270. X    int          line;
  1271. X};
  1272. X
  1273. X/*
  1274. X * minimum round up to get to a doubleword boundry, assuming it is the
  1275. X * strictest alignment requirement on the system.  If not, the union s
  1276. X * in struct mlist will also have to be changed.  Note that this must be
  1277. X * a power of two because of how it is used throughout the code.
  1278. X */
  1279. X#define M_RND        0x08
  1280. X#define M_YOFFSET       (sizeof(SIZETYPE))
  1281. X
  1282. X#define LONGFILL 2
  1283. X
  1284. Xstruct mlist
  1285. X{
  1286. X    struct mlist    * next;            /* next entry in chain    */
  1287. X    struct mlist    * prev;            /* prev entry in chain    */
  1288. X    struct mlist    * freenext;        /* next ent in free chn */
  1289. X    struct mlist    * freeprev;        /* prev ent in free chn */
  1290. X    struct stack    * stack;        /* current stack level    */
  1291. X    struct stack    * freestack;        /* free stack level    */
  1292. X    long           flag;            /* inuse flag        */
  1293. X    CONST char    * file;            /* file where called fm    */
  1294. X    int          line;            /* line where called fm    */
  1295. X    CONST char    * ffile;        /* file where freed     */
  1296. X    int          fline;        /* line where freed     */
  1297. X    IDTYPE          fid;            /* free call number    */
  1298. X    IDTYPE          hist_id;        /* historical id    */
  1299. X    IDTYPE          id;            /* malloc call number    */
  1300. X    SIZETYPE      r_size;        /* requested size    */
  1301. X    union
  1302. X    {
  1303. X        SIZETYPE      size;        /* actual size        */
  1304. X        SIZETYPE      filler[LONGFILL];
  1305. X        double          unused_just_for_alignment;
  1306. X    } s;
  1307. X    char          data[M_RND];
  1308. X};
  1309. X
  1310. X/*
  1311. X * pre-filler size
  1312. X */
  1313. X#define FILLSIZE    (sizeof(mlist.s) - sizeof(mlist.s.filler[0]))
  1314. X
  1315. X/*
  1316. X * kludge to get offsetof the data element for the mlist structure
  1317. X */
  1318. X#define M_SIZE        ((SIZETYPE)(char *)((struct mlist *)0)->data)
  1319. X#define M_FLAGOFF    ((SIZETYPE)(char *)&((struct mlist *)0)->flag)
  1320. X
  1321. X#define M_INUSE     0x01
  1322. X#define M_FILLED     0x02
  1323. X#define M_MARKED    0x04
  1324. X#define M_DFILLED    0x08
  1325. X#define M_MAGIC     0x31561000
  1326. X#define M_MAGIC_BITS    0xfffff000
  1327. X
  1328. X#define M_BLOCKSIZE    (1024*8)
  1329. X
  1330. X#define EOS            '\0'
  1331. X#define M_DFLT_FILL        '\01'
  1332. X#define M_DFLT_FREE_FILL    '\02'
  1333. X#define M_DFLT_BSIZE        1
  1334. X#define M_FILL            ((char)malloc_fillbyte)
  1335. X#define M_FREE_FILL        ((char)malloc_freebyte)
  1336. X#define M_BSIZE            (malloc_boundsize)
  1337. X
  1338. X#define MALLOC_INIT()    if( malloc_data_start == (DATATYPE *)0 ) malloc_init()
  1339. X
  1340. X/* 
  1341. X * malloc internal options
  1342. X */
  1343. X#define MOPT_MFILL    0x0001        /* fill malloc'd segments    */
  1344. X#define MOPT_FFILL    0x0002        /* fill free'd segments        */
  1345. X#define MOPT_REUSE    0x0004        /* reuse free segments?        */
  1346. X#define MOPT_LOWFRAG    0x0008        /* low fragmentation        */
  1347. X#define MOPT_CKCHAIN    0x0010        /* enable chain checking    */
  1348. X#define MOPT_CKDATA    0x0020        /* enable data checking        */
  1349. X#define MOPT_DFILL    0x0040        /* fill over/underflow areas    */
  1350. X#define MOPT_SLINKS     0x0080        /* turn off/on adjacent link disp */
  1351. X#define MOPT_DETAIL     0x0100        /* turn off/on detailed output  */
  1352. X#define MOPT_FREEMARK   0x0200        /* warning when freeing marked    */
  1353. X#define MOPT_ZERO       0x0400        /* warning about zero length allocs */
  1354. X
  1355. X/*
  1356. X * malloc_freeseg() operation arguments
  1357. X */
  1358. X#define M_FREE_REMOVE    1
  1359. X#define M_FREE_ADD    2
  1360. X/*
  1361. X * Malloc types
  1362. X */
  1363. X#define M_T_MALLOC    0x010
  1364. X#define M_T_REALLOC    0x020
  1365. X#define M_T_CALLOC    0x030
  1366. X#define M_T_SPLIT    0x040
  1367. X#define M_T_STACK    0x050
  1368. X#define M_T_XTMALLOC    0x060
  1369. X#define M_T_XTREALLOC    0x070
  1370. X#define M_T_XTCALLOC    0x080
  1371. X#define M_T_ALIGNED    0x090
  1372. X#define M_T_BITS    0x0F0
  1373. X
  1374. X#define GETTYPE(_ptr)        (_ptr->flag & M_T_BITS)
  1375. X#define SETTYPE(_ptr,_type)     (_ptr->flag = ((_ptr->flag & ~M_T_BITS)|_type))
  1376. X
  1377. X#define DATATOMLIST(_ptr) ((struct mlist *) (((char *)_ptr) - M_SIZE))
  1378. X
  1379. X/*
  1380. X * Free types
  1381. X */
  1382. X#define F_T_FREE    0x100
  1383. X#define F_T_CFREE    0x200
  1384. X#define F_T_XTFREE    0x300
  1385. X#define F_T_REALLOC    0x400
  1386. X#define F_T_BITS    0xF00
  1387. X
  1388. X#define GETFTYPE(_ptr)        (_ptr->flag & F_T_BITS)
  1389. X#define SETFTYPE(_ptr,_type)     (_ptr->flag = ((_ptr->flag & ~F_T_BITS)|_type))
  1390. X
  1391. X/*
  1392. X * Fill types
  1393. X */
  1394. X#define FILL_MALLOC    1
  1395. X#define FILL_REALLOC    2
  1396. X#define FILL_CALLOC    3
  1397. X#define FILL_FREE    4
  1398. X#define FILL_SPLIT    5
  1399. X#define FILL_JOIN    6
  1400. X
  1401. X#define FILLCHECK(a,b,c,d,e) ( malloc_fill ? FillCheck(a,b,c,d,e) : 0 )
  1402. X#define FILLDATA(a,b,c,d)     if( malloc_fill ) FillData(a,b,c,d)
  1403. X
  1404. X/*
  1405. X * malloc_chain_check flags
  1406. X */
  1407. X#define SHOWERRORS    1
  1408. X#define DONTSHOWERRS    0
  1409. X
  1410. X/*
  1411. X * DBFmalloc fill flags
  1412. X */
  1413. X#define DOFILL        1
  1414. X#define DONTFILL    0
  1415. X
  1416. X/*
  1417. X * malloc join flags
  1418. X */
  1419. X#define NOTINUSE    0    /* don't join inuse segments        */
  1420. X#define INUSEOK        1    /* ok to join if current seg is in use    */
  1421. X#define NEXTPTR_INUSEOK    2
  1422. X#define ANY_INUSEOK    3
  1423. X
  1424. X/*
  1425. X * number of longwords to search for magic number before we give up and 
  1426. X * search the entire malloc list.
  1427. X */
  1428. X#define MAX_KLUDGE_CHECKS    100
  1429. X/*
  1430. X * Misc stuff..
  1431. X */
  1432. X#define M_ROUNDUP(size)    {\
  1433. X                if( size & (M_RND-1) ) \
  1434. X                { \
  1435. X                    size += (M_RND-1); \
  1436. X                    size &= ~(M_RND-1); \
  1437. X                } \
  1438. X            }
  1439. X
  1440. XEXITTYPE      exit __STDCARGS((int));
  1441. Xchar        * getenv __STDCARGS((CONST char *));
  1442. XDATATYPE    * sbrk __STDCARGS((int));
  1443. X
  1444. X/*
  1445. X * stuff for X compatibility routines (needed here so that the prototypes 
  1446. X * don't fail
  1447. X */
  1448. Xtypedef struct {
  1449. X    char*       start;
  1450. X    char*       current;
  1451. X    int         bytes_remaining;
  1452. X} Heap;
  1453. X
  1454. X#ifndef _XtIntrinsic_h
  1455. Xtypedef unsigned int Cardinal;
  1456. Xtypedef char * String;
  1457. X#endif
  1458. X
  1459. X#include "prototypes.h"
  1460. X
  1461. X/*
  1462. X * global variables
  1463. X */
  1464. Xextern int          in_malloc_code;
  1465. Xextern SIZETYPE          malloc_align;
  1466. Xextern int          malloc_boundsize;
  1467. Xextern DATATYPE        * malloc_data_start;
  1468. Xextern DATATYPE        * malloc_data_end;
  1469. Xextern struct mlist     * malloc_end;
  1470. Xextern int          malloc_errfd;
  1471. Xextern int          malloc_errno;
  1472. Xextern CONST char    * malloc_err_strings[];
  1473. Xextern int          malloc_fatal_level;
  1474. Xextern int          malloc_fill;
  1475. Xextern int          malloc_fillbyte;
  1476. Xextern int          malloc_freebyte;
  1477. Xextern struct mlist    * malloc_freelist;
  1478. Xextern long          malloc_hist_id;
  1479. Xextern int          malloc_opts;
  1480. Xextern int          malloc_round;
  1481. Xextern struct mlist      malloc_start;
  1482. Xextern int          malloc_warn_level;
  1483. X
  1484. X#endif /* _MALLOCIN_H */
  1485. X
  1486. X/*
  1487. X * $Log: mallocin.h,v $
  1488. X * Revision 1.27  1992/09/03  22:24:33  cpcahil
  1489. X * final changes for PL14
  1490. X *
  1491. X * Revision 1.26  1992/08/22  16:27:13  cpcahil
  1492. X * final changes for pl14
  1493. X *
  1494. X * Revision 1.25  1992/07/12  15:30:58  cpcahil
  1495. X * Merged in Jonathan I Kamens' changes
  1496. X *
  1497. X * Revision 1.24  1992/07/03  00:03:25  cpcahil
  1498. X * more fixes for pl13, several suggestons from Rich Salz.
  1499. X *
  1500. X * Revision 1.23  1992/07/02  13:49:54  cpcahil
  1501. X * added support for new malloc_size function and additional tests to testerr
  1502. X *
  1503. X * Revision 1.22  1992/06/30  13:06:39  cpcahil
  1504. X * added support for aligned allocations
  1505. X *
  1506. X * Revision 1.21  1992/06/22  23:40:10  cpcahil
  1507. X * many fixes for working on small int systems
  1508. X *
  1509. X * Revision 1.20  1992/05/09  00:16:16  cpcahil
  1510. X * port to hpux and lots of fixes
  1511. X *
  1512. X * Revision 1.19  1992/05/08  02:30:35  cpcahil
  1513. X * minor cleanups from minix/atari port
  1514. X *
  1515. X * Revision 1.18  1992/05/08  01:44:11  cpcahil
  1516. X * more performance enhancements
  1517. X *
  1518. X * Revision 1.17  1992/05/06  05:37:44  cpcahil
  1519. X * added overriding of fill characters and boundary size
  1520. X *
  1521. X * Revision 1.16  1992/05/06  04:53:29  cpcahil
  1522. X * performance enhancments
  1523. X *
  1524. X * Revision 1.15  1992/04/24  12:09:13  cpcahil
  1525. X * (hopefully) final cleanup for patch 10
  1526. X *
  1527. X * Revision 1.14  1992/04/24  11:18:52  cpcahil
  1528. X * Fixes from Denny Page and Better integration of Xt alloc hooks
  1529. X *
  1530. X * Revision 1.13  1992/04/22  18:17:32  cpcahil
  1531. X * added support for Xt Alloc functions, linted code
  1532. X *
  1533. X * Revision 1.12  1992/04/20  22:29:14  cpcahil
  1534. X * changes to fix problems introduced by insertion of size_t
  1535. X *
  1536. X * Revision 1.11  1992/04/13  18:26:30  cpcahil
  1537. X * changed sbrk arg to int which it should be on all systems.
  1538. X *
  1539. X * Revision 1.10  1992/04/13  14:16:11  cpcahil
  1540. X * ansi changes corresponding to changes made in stack.c
  1541. X *
  1542. X * Revision 1.9  1992/04/13  03:06:33  cpcahil
  1543. X * Added Stack support, marking of non-leaks, auto-config, auto-testing
  1544. X *
  1545. X * Revision 1.8  1992/03/01  12:42:38  cpcahil
  1546. X * added support for managing freed areas and fixed doublword bndr problems
  1547. X *
  1548. X * Revision 1.7  1991/12/31  21:31:26  cpcahil
  1549. X * changes for patch 6.  See CHANGES file for more info
  1550. X *
  1551. X * Revision 1.6  1991/12/06  08:54:18  cpcahil
  1552. X * cleanup of __STDC__ usage and addition of CHANGES file
  1553. X *
  1554. X * Revision 1.5  91/12/04  18:01:22  cpcahil
  1555. X * cleand up some aditional warnings from gcc -Wall
  1556. X * 
  1557. X * Revision 1.4  91/12/04  09:23:42  cpcahil
  1558. X * several performance enhancements including addition of free list
  1559. X * 
  1560. X * Revision 1.3  91/12/02  19:10:12  cpcahil
  1561. X * changes for patch release 5
  1562. X * 
  1563. X * Revision 1.2  91/11/25  14:42:02  cpcahil
  1564. X * Final changes in preparation for patch 4 release
  1565. X * 
  1566. X * Revision 1.1  91/11/24  00:49:30  cpcahil
  1567. X * first cut at patch 4
  1568. X * 
  1569. X */
  1570. END_OF_FILE
  1571. if test 9557 -ne `wc -c <'mallocin.h'`; then
  1572.     echo shar: \"'mallocin.h'\" unpacked with wrong size!
  1573. fi
  1574. # end of 'mallocin.h'
  1575. fi
  1576. echo shar: End of archive 5 \(of 10\).
  1577. cp /dev/null ark5isdone
  1578. MISSING=""
  1579. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  1580.     if test ! -f ark${I}isdone ; then
  1581.     MISSING="${MISSING} ${I}"
  1582.     fi
  1583. done
  1584. if test "${MISSING}" = "" ; then
  1585.     echo You have unpacked all 10 archives.
  1586.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1587. else
  1588.     echo You still need to unpack the following archives:
  1589.     echo "        " ${MISSING}
  1590. fi
  1591. ##  End of shell archive.
  1592. exit 0
  1593. *** SENTINEL(tm) The ultimate Debugging Environment - email for more info ***
  1594.  
  1595. Conor P. Cahill              (703)430-9247            cpcahil@virtech.vti.com
  1596. Virtual Technologies, Inc.  46030 Manekin Plaza          Dulles, VA 21066 
  1597.  
  1598. exit 0 # Just in case...
  1599.