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

  1. Newsgroups: comp.sources.misc
  2. From: cpcahil@vti.com (Conor P. Cahill)
  3. Subject:  v32i012:  dbmalloc - Debug Malloc Library PL14, Part07/10
  4. Message-ID: <1992Sep4.152300.13414@sparky.imd.sterling.com>
  5. X-Md4-Signature: 1d5e96179641aecee129427d453e2930
  6. Date: Fri, 4 Sep 1992 15:23:00 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: cpcahil@vti.com (Conor P. Cahill)
  10. Posting-number: Volume 32, Issue 12
  11. Archive-name: dbmalloc/part07
  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 7 (of 10)."
  21. # Contents:  malloc.man size.c testerr.c
  22. # Wrapped by cpcahil@virtech on Thu Sep  3 18:39:20 1992
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'malloc.man' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'malloc.man'\"
  26. else
  27. echo shar: Extracting \"'malloc.man'\" \(45140 characters\)
  28. sed "s/^X//" >'malloc.man' <<'END_OF_FILE'
  29. X
  30. X
  31. X
  32. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  33. X
  34. X
  35. X
  36. X     NAME
  37. X      dbmalloc - debugging malloc library
  38. X
  39. X     SYNOPSIS
  40. X      #include <malloc.h>
  41. X
  42. X      int malloc_chain_check(flag);
  43. X      int flag;
  44. X
  45. X      void malloc_dump(fd);
  46. X      int fd;
  47. X
  48. X      void malloc_list(fd,histid1,histid2);
  49. X      int fd;
  50. X      unsigned long    histid1, histid2;
  51. X
  52. X      unsigned long    malloc_inuse(histidptr);
  53. X      unsigned long    * histidptr;
  54. X
  55. X      void malloc_mark(ptr);
  56. X      char * ptr;
  57. X
  58. X      int dbmallopt(cmd,val);
  59. X      int cmd;
  60. X      union    dbmalloptarg val;
  61. X
  62. X      void malloc_abort();
  63. X
  64. X      void malloc_enter(func);
  65. X      char * func;
  66. X
  67. X      void malloc_leave(func);
  68. X      char * func;
  69. X
  70. X     DESCRIPTION
  71. X      This malloc library is a replacement for the standard
  72. X      library to be    used during software development/debugging.
  73. X      See the standard malloc(3) pages for more information    on the
  74. X      use of the following functions:
  75. X
  76. X           calloc(), cfree(), free(), malloc(), realloc()
  77. X
  78. X      This library differs from the    standard malloc    library    in the
  79. X      following ways:
  80. X
  81. X      1. Each malloc segment contains a magic number so that free
  82. X      can verify that the pointer passed points to a valid malloc
  83. X      segment.
  84. X
  85. X      2. Each malloc segment is filled with    a non-zero pattern so
  86. X      that code that depends upon malloc segments being null will
  87. X      fail.
  88. X
  89. X
  90. X
  91. X     Page 1               1.11
  92. X
  93. X
  94. X
  95. X
  96. X
  97. X
  98. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  99. X
  100. X
  101. X
  102. X      3. The size of each segment will be at least 1 byte larger
  103. X      than requested and the extra bytes will be filled with a
  104. X      non-zero pattern.  When free is called, it will verify that
  105. X      you did not go beyond    the number of bytes you    asked for.
  106. X
  107. X      4. When a segment is freed, it will be filled    with a
  108. X      different non-zero pattern to    ensure that the    program
  109. X      doesn't depend upon the use of already freed data.
  110. X
  111. X      5. Whenever any of the string    or memory functions (str*, b*,
  112. X      mem*)    are called with    a pointer that is within the malloc
  113. X      arena,  the operation    is checked to verify that it does not
  114. X      overrun the malloced segment.     A failure of this check is
  115. X      considered a "warning    level error" (described    later) and is
  116. X      handled accordingly.
  117. X
  118. X      6. Run time checking can include verification    of the malloc
  119. X      chain    at each    and every call to one of the malloc functions
  120. X      or manually by calling the malloc_chain_check    function.
  121. X
  122. X      7. Extensive support for tracking memory leaks is provided.
  123. X
  124. X      When a problem is found, the following error message is
  125. X      displayed:
  126. X
  127. X           MALLOC Warning from funcname() (called from filename.c line ###):
  128. X           Warning message goes here
  129. X
  130. X      funcname is the name of the function that has    found the
  131. X      problem and will usually be an entry point into the library.
  132. X      The information that identifies where    the function is    called
  133. X      from will only be available if the source module was
  134. X      compiled with    the malloc.h file included.
  135. X
  136. X      If the error is caused by a problem in the malloc chain and
  137. X      the offending    chain element can be identified, the following
  138. X      information is also displayed    (NOTE: this is just a guess by
  139. X      the software,    it may not be the actual culprit):
  140. X
  141. X           This error is *probably*    associated with    the following allocation:
  142. X
  143. X          A call to malloc for 33 bytes    in program.c on    line 834.
  144. X          This was the 172nd call to malloc.
  145. X
  146. X
  147. X
  148. X
  149. X
  150. X
  151. X
  152. X
  153. X
  154. X
  155. X
  156. X
  157. X     Page 2               1.11
  158. X
  159. X
  160. X
  161. X
  162. X
  163. X
  164. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  165. X
  166. X
  167. X
  168. X      This example assumes that program.c included the debugging
  169. X      library malloc.h file.  If not, the identification
  170. X      information will be as follows:
  171. X
  172. X           This error is *probably*    associated with    the following allocation:
  173. X
  174. X          A call to malloc for 33 bytes    in an unknown file.
  175. X          This was the 172nd call to malloc.
  176. X
  177. X      The identification of    which call to malloc is    associated
  178. X      with the problem is helpful in that it gives you the
  179. X      information necessary    to set the breakpoint on the
  180. X      allocation function for that particular invocation
  181. X      (breakpoints usually can have    counters associated with
  182. X      them).  The counters for the three primary allocation    entry
  183. X      points (malloc, calloc, and realloc) are managed separately.
  184. X
  185. X      NOTE 1: if you want to set a breakpoint to capture this
  186. X      invocation of    malloc,    the actual function that is being
  187. X      called is debug_malloc (or debug_realloc for realloc and
  188. X      debug_calloc for calloc) and that is where the breakpoint
  189. X      should be set.
  190. X
  191. X      NOTE 2: Since    the software is    guessing at the    offending
  192. X      malloc chain segment,    it is possible that one    of the nearby
  193. X      segments is actually the culprit.  If    the environment
  194. X      variable MALLOC_SHOW_LINKS is    set, both the segment
  195. X      preceding and    the segment following the accused segment will
  196. X      also be identified.  The following is    a sample output:
  197. X
  198. X           This error is *probably*    associated with    the following allocation:
  199. X
  200. X           A call to malloc for    33 bytes in an unknown file.
  201. X           This    was the    172nd call to malloc.
  202. X
  203. X           The malloc chain element prior to the suspect allocation is from:
  204. X
  205. X           A call to calloc for    512 bytes in main.c line 16.
  206. X           This    was the    4th call to calloc.
  207. X           This    block was freed    on the 2nd call    to free()
  208. X           in main.c on    line 51.
  209. X
  210. X           The malloc chain element following the suspect allocation is    from:
  211. X
  212. X           A call to realloc for 4096 bytes in func.c line 376.
  213. X           This    was the    1st call to realloc.
  214. X
  215. X
  216. X
  217. X
  218. X
  219. X
  220. X
  221. X
  222. X
  223. X     Page 3               1.11
  224. X
  225. X
  226. X
  227. X
  228. X
  229. X
  230. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  231. X
  232. X
  233. X
  234. X      Once the error message has been displayed, the software will
  235. X      then determine how to    handle the error.  This    handling will
  236. X      be based upon    the type of error level    (warning or fatal) and
  237. X      the error handling in    effect for that    error level (as
  238. X      specified by calls to    mallopt    or via environment variables).
  239. X      The coding for the error handling is as follows:
  240. X
  241. X        0    continue operations
  242. X        1    drop core and exit
  243. X        2    just exit
  244. X        3    drop core, but continue    executing.  Core files will be
  245. X        placed into core.[PID].[counter] i.e: core.00123.001
  246. X      128    dump malloc chain and continue
  247. X      129    dump malloc chain, dump    core, and exit
  248. X      130    dump malloc chain, exit
  249. X      131    dump malloc chain, dump    core, continue processing
  250. X
  251. X      dbmallopt() is used to set the malloc    debugging options. The
  252. X      following options can    be set:
  253. X
  254. X      MALLOC_WARN          set the error handling for warning level
  255. X                  errors.  val.i is    an integer that    can
  256. X                  contain any one of the following values:
  257. X
  258. X                  M_HANDLE_IGNORE      ignore error (just
  259. X                          display warning
  260. X                          message and continue
  261. X                          processing)
  262. X                  M_HANDLE_ABORT      drop core and    exit
  263. X                  M_HANDLE_EXIT      just exit (no    core
  264. X                          drop)
  265. X                  M_HANDLE_CORE      drop core, but keep
  266. X                          on going
  267. X
  268. X                  In addition, M_HANDLE_DUMP may be    or'd
  269. X                  in to cause a dump of the    current    malloc
  270. X                  chain.
  271. X
  272. X                  The default action for MALLOC_WARN is
  273. X                  M_HANDLE_IGNORE.
  274. X
  275. X      MALLOC_FATAL          set the error handling for fatal level
  276. X                  errors.  val.i is    equivalent to val.i
  277. X                  for MALLOC_WARN.
  278. X
  279. X                  The default action for MALLOC_FATAL is
  280. X                  M_HANDLE_ABORT.
  281. X
  282. X      MALLOC_ERRFILE      set the destination for malloc error
  283. X                  messages.     val.str is a pointer to a
  284. X                  character    string containing the name of
  285. X                  the file to be used for error messages.
  286. X
  287. X
  288. X
  289. X     Page 4               1.11
  290. X
  291. X
  292. X
  293. X
  294. X
  295. X
  296. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  297. X
  298. X
  299. X
  300. X                  Note that    error messages are APPENDED to
  301. X                  this file, so existing error messages
  302. X                  will not be removed.
  303. X
  304. X                  If MALLOC_ERRFILE    is not set, all    error
  305. X                  messages will be sent to stderr.
  306. X
  307. X      MALLOC_CKCHAIN      set the malloc chain checking flag.  If
  308. X                  val.i is non-zero, chain checking    at
  309. X                  every call to malloc is turned on. The
  310. X                  default behavior is to not check the
  311. X                  chain at each call to malloc because of
  312. X                  performance issues (the library is
  313. X                  considerably slower when this function
  314. X                  is enabled).
  315. X
  316. X      MALLOC_FREEMARK     sets the behavior    of freeing of marked
  317. X                  areas.  By default, a free of a marked
  318. X                  segment generates    a warning.  If val.i
  319. X                  is zero, warnings    will not be generated.
  320. X
  321. X      MALLOC_FILLAREA     set the malloc fill area flag.  val.i
  322. X                  specifies    the malloc filling mode    to be
  323. X                  used.   There are    four modes: 0, 1, 2
  324. X                  and 3.  Mode 0 disables all filling and
  325. X                  checking of filled areas (thereby
  326. X                  reducing the effectiveness of the
  327. X                  library).     Mode 1    enables    the filling of
  328. X                  boundary areas before and    after the
  329. X                  allocation areas which are used to check
  330. X                  for writing before or after the pointer.
  331. X                  Mode 2 includes mode 1 and adds the
  332. X                  filling of malloced regions with a
  333. X                  specified    fill pattern so    that a program
  334. X                  does not depend upon malloced regions to
  335. X                  be filled    with zeros.  Mode 3 includes
  336. X                  all of mode 2 and    adds the filling of
  337. X                  free'd regions so    that an    attempt    to
  338. X                  used a freed data    area will result in an
  339. X                  error.
  340. X
  341. X                  As far as    performance is concerned, mode
  342. X                  0    will be    the fastest mode, while
  343. X                  (somewhat    unexpectedly) mode 3 is    the
  344. X                  next "fastest" mode with mode 1 bring up
  345. X                  the tail end.
  346. X
  347. X                  The default behavior for MALLOC_FILLAREA
  348. X                  is mode 3.
  349. X
  350. X      MALLOC_LOWFRAG      set the malloc allocation    fragmentation
  351. X                  handling level.  By default, malloc uses
  352. X
  353. X
  354. X
  355. X     Page 5               1.11
  356. X
  357. X
  358. X
  359. X
  360. X
  361. X
  362. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  363. X
  364. X
  365. X
  366. X                  a    first fit algorithm for    new
  367. X                  allocations.  Under certain allocation
  368. X                  scenarios, this can lead to significant
  369. X                  memory fragmentation because of the fact
  370. X                  that little allocations can break    big
  371. X                  blocks up.
  372. X
  373. X                  If val.i is non-zero, malloc uses    a best
  374. X                  fit algorithm which will reduce
  375. X                  fragmentation.  This mechanism, while
  376. X                  using less memory, is slower because the
  377. X                  entire free list is checked instead of
  378. X                  just checking until we find a segment
  379. X                  that is at least big enough.  Normally
  380. X                  you will not need    to set this variable.
  381. X
  382. X      MALLOC_CKDATA          enable/disable the checking of pointers
  383. X                  passed to    the memory (mem*,b*) and
  384. X                  string (str*) functions.    This can be
  385. X                  used to startup the code with checking
  386. X                  disabled (when you know the startup code
  387. X                  is functioning correctly)    and then turn
  388. X                  it on later when you get into the    area
  389. X                  of the code that is in question.
  390. X
  391. X                  if val.i is non-zero, pointer checking
  392. X                  is enabled (which    is the default mode).
  393. X
  394. X      MALLOC_REUSE          enable/disable the reuse of freed
  395. X                  segments.     This option can be used to
  396. X                  help identify where a freed pointer is
  397. X                  being re-used, or    where it is being
  398. X                  freed a second time, since the location
  399. X                  where it was freed is also kept.
  400. X
  401. X                  It should    be noted that the memory
  402. X                  requirements for a program will
  403. X                  typically    increase significantly if this
  404. X                  option is    used.
  405. X
  406. X                  if val.i is zero,    freed segments are not
  407. X                  reused for subsequent allocations.   If
  408. X                  non-zero,    freed segments can be reused.
  409. X                  If freed segments    are not    re-used, you
  410. X                  might want to disable filling of freed
  411. X                  segments (see the    MALLOC_FILLAREA
  412. X                  discussions) so that you can see the
  413. X                  data in the segment - this would be fill
  414. X                  mode 2 or    below.
  415. X
  416. X
  417. X
  418. X
  419. X
  420. X
  421. X     Page 6               1.11
  422. X
  423. X
  424. X
  425. X
  426. X
  427. X
  428. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  429. X
  430. X
  431. X
  432. X      For example, to set up the session to    generate a core    file
  433. X      for every malloc warning, to drop core and exit on a malloc
  434. X      fatal, and to    log all    messages to the    file "malloc_log" do
  435. X      the following:
  436. X
  437. X           #include    <malloc.h>
  438. X           union dbmalloptarg  m;
  439. X
  440. X           m.i = M_HANDLE_CORE | M_HANDLE_DUMP;
  441. X           dbmallopt(MALLOC_WARN,m);
  442. X
  443. X           m.i = M_HANDLE_ABORT;
  444. X           dbmallopt(MALLOC_FATAL,m);
  445. X
  446. X           m.str = "malloc_log";
  447. X           dbmallopt(MALLOC_ERRFILE,m);
  448. X
  449. X      dbmallopt() can be used to set/alter the debugging options
  450. X      at any time (i.e. you    may want to turn on chain-checking
  451. X      after    the program startup if the program startup does    a lot
  452. X      of allocations which are known to be OK).
  453. X
  454. X      malloc_chain_check() will check the status of    the malloc
  455. X      arena.  If flag is non-zero, an error    found in the chain
  456. X      will cause a fatal error.  malloc_chain_check() returns zero
  457. X      when there are no problems found in the malloc chain,    non-
  458. X      zero otherwise.
  459. X
  460. X      malloc_dump()    will dump a list of all    in-use malloc segments
  461. X      and the first    few bytes of each segment.  If the environment
  462. X      variable MALLOC_DETAIL is set    to a non-zero integer, all
  463. X      segments (including those that have been freed) are listed
  464. X      and additional internal information is displayed.  fd    is the
  465. X      file descriptor to write the data to.
  466. X
  467. X      malloc_list()    will dump a list in the    same format as
  468. X      malloc_dump but only the items that are still    in use and
  469. X      which    have been allocated within the malloc history id range
  470. X      specified by histid1 and histid2, inclusive.    The histids
  471. X      are obtained from calls to malloc_inuse(). This is
  472. X      especially useful in tracking    down memory leaks.  fd is the
  473. X      file descriptor to write the data to.
  474. X
  475. X      malloc_inuse() returns the amount of malloc data that    is
  476. X      currently in use (in bytes).    If histidptr is    not NULL, it
  477. X      is taken to be a pointer to a    place to store the current
  478. X      malloc history id which can be used later when malloc_list
  479. X      is called to list items that are still in use.
  480. X
  481. X
  482. X
  483. X
  484. X
  485. X
  486. X
  487. X     Page 7               1.11
  488. X
  489. X
  490. X
  491. X
  492. X
  493. X
  494. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  495. X
  496. X
  497. X
  498. X      The following    example    shows the typical use of the
  499. X      malloc_inuse and malloc_list functions in tracking down
  500. X      memory leaks:
  501. X
  502. X           unsigned    long  histid1, histid2,    orig_size, current_size;
  503. X
  504. X           orig_size = malloc_inuse(&histid1);
  505. X
  506. X           /* .....    go do lots of stuff ...... */
  507. X
  508. X           current_size = malloc_inuse(&histid2);
  509. X
  510. X           if( current_size    != orig_size )
  511. X           {
  512. X            malloc_list(2,histid1,histid2);
  513. X           }
  514. X
  515. X      malloc_mark()    marks a    segment    as a non-leak.    Segments that
  516. X      are marked are not counted or    listed when dealing with
  517. X      memory leaks.     This is designed to be    used on    pointers that
  518. X      remain around    forever    and shouldn't be considered to be a
  519. X      leak (in order to decrease the amount    of entries in the leak
  520. X      lists)
  521. X
  522. X      malloc_abort() causes    the current program to drop core and
  523. X      exit.     This function simply calls abort() to do its dirty
  524. X      work and is here solely for the purpose of allowing the
  525. X      programmer to    substitute thier own abort routine to handle
  526. X      fatal    errors.     If a substitute routine is used, it must not
  527. X      return to the    caller or else the program will    use the
  528. X      abort() system call to cause the program to stop.
  529. X
  530. X      malloc_enter() and malloc_leave() provide a rudimentary
  531. X      mechanism to track the calling stack that was    in place when
  532. X      the allocation was made.  In order to    use this feature, the
  533. X      enter    function should    be called upon entry to    a function,
  534. X      while    the leave function is called when you exit from    the
  535. X      function.  In    order to be accurate, the two functions    must
  536. X      be used in conjunction with each other and a missing call
  537. X      will result in an error generated by the library (if it is
  538. X      detected).
  539. X
  540. X      NOTE:    the argument to    either of these    functions must be a
  541. X      constant character string or a static    data area.  This is
  542. X      because the stack mechanism does not maintain    it's own copy
  543. X      of these strings, it just records pointers to    the strings
  544. X      and if the strings are on the    stack, they will go away.
  545. X      Typically the    functions would    be used    with "funcname"    as the
  546. X      argument and this will avoid any problems.
  547. X
  548. X
  549. X
  550. X
  551. X
  552. X
  553. X     Page 8               1.11
  554. X
  555. X
  556. X
  557. X
  558. X
  559. X
  560. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  561. X
  562. X
  563. X
  564. X      The stack is listed on the dump and/or list reports and on
  565. X      an error message for a segment that has already been freed.
  566. X
  567. X      If these functions have been used, error messages will
  568. X      include the stack information    when the identity of the error
  569. X      is displayed.     For example:
  570. X
  571. X           This error is *probably*    associated with    the following allocation:
  572. X
  573. X           A call to malloc for    1 bytes    in teststack.c on line 75.
  574. X           This    was the    13th call to malloc.
  575. X           Stack from where allocated:
  576. X            -> sub3() in teststack.c(73)
  577. X            -> sub2() in teststack.c(59)
  578. X            -> main() in teststack.c(23)
  579. X
  580. X
  581. X
  582. X     USAGE
  583. X      The library can be used in several modes, each increasingly
  584. X      intrusive (i.e. requiring changes to be made to the build
  585. X      process and/or source    code).    However, the extra cost    of a
  586. X      little intrusiveness is repaid in much better    problem
  587. X      identification.  Each    mode is    built upon the previous    modes
  588. X      and therefore    requires the changes and/or commands specified
  589. X      in the lower modes.
  590. X
  591. X      MODE 1 - library substitution
  592. X
  593. X      The simplest use is to just link the object module with the
  594. X      libdbmalloc.a.  Be sure to have this library before the C
  595. X      library (libc.a) on the link command (this is    automatic if
  596. X      you use cc to    link and specify the debug library without
  597. X      specifying the C library).
  598. X
  599. X      This mode links in all of the    debug versions of the library
  600. X      modules and will trap    as many    errors as it can (yes, there
  601. X      are errors that the malloc library cannot catch).
  602. X      Environment variables    can be used to control the behavior of
  603. X      the library.
  604. X
  605. X
  606. X
  607. X
  608. X
  609. X
  610. X
  611. X
  612. X
  613. X
  614. X
  615. X
  616. X
  617. X
  618. X
  619. X     Page 9               1.11
  620. X
  621. X
  622. X
  623. X
  624. X
  625. X
  626. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  627. X
  628. X
  629. X
  630. X      MODE 2 - malloc.h inclusion
  631. X
  632. X      This mode involves including the malloc.h file included with
  633. X      the debugging    library.  The malloc.h file includes macros
  634. X      that will identify the source    line and file name for each
  635. X      debugging function called.  This is how the library is able
  636. X      to tell you that it was the call to malloc on    line 55    in
  637. X      file junk.c.
  638. X
  639. X      Typically you    should always include malloc.h in your source
  640. X      files    and just use the -I INCLUDEDIR directive for the
  641. X      compiler to point the    compiler to the    debugging version of
  642. X      the header file instead of the normal    file.  That way    you
  643. X      don't    have to    change the source files    when you want to turn
  644. X      off the debugging library.
  645. X
  646. X      NOTE:    Once you compile code in this mode, you    must recompile
  647. X      the code without the debugging malloc.h include file in
  648. X      order    to get the software to use the non-debugging
  649. X      functions.
  650. X
  651. X      MODE 3 - run-time specification of options
  652. X
  653. X      Environment variables    can be used to control the behavior of
  654. X      the debugging    library    to some    extent.     However, this control
  655. X      is very coarse in that you only have one setting available
  656. X      for the entire running of the    program.
  657. X
  658. X      This can be a    problem    if you want to turn on malloc chain
  659. X      checking, but    know that the problem occurs between a
  660. X      relatively narrow portion of the code    and don't want to take
  661. X      the hit of having chain checking on for the entire program
  662. X      execution.
  663. X
  664. X      The solution to this problem is to include calls to
  665. X      dbmallopt() with the debugging options which set the
  666. X      appropriate modes when you want them set.  Since you don't
  667. X      want to have to change the code to remove and    add these
  668. X      functions every time you decide to include malloc debugging
  669. X      or not, the malloc.h file defines the    preprocessor symbol
  670. X      _DEBUG_MALLOC_INC which can be used in your code as follows:
  671. X
  672. X           #ifdef _DEBUG_MALLOC_INC
  673. X            dbmallopt(.... );
  674. X           #endif
  675. X
  676. X      In addition to setting behavior options, you might want to
  677. X      make use of the memory leak detection    routines in this mode.
  678. X      These    calls should also be surrounded    by #ifdefs for the
  679. X      debug    malloc symbol so that you can leave them in the    code
  680. X      and automatically get    the increased functionality whenever
  681. X      you compile with the debugging library.
  682. X
  683. X
  684. X
  685. X     Page 10               1.11
  686. X
  687. X
  688. X
  689. X
  690. X
  691. X
  692. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  693. X
  694. X
  695. X
  696. X      MODE 4 - deeper inclusion of malloc calls
  697. X
  698. X      This mode involves inserting calls to    the special functions
  699. X      supported by the malloc library (like    the leak detection or
  700. X      stack    maintenance routines).    The effects of the inclusions
  701. X      depends upon the modules included and    the amount to which
  702. X      they are used.
  703. X
  704. X      It is    strongly recommended that you setup your code with the
  705. X      following lines in a header file that    is included by all
  706. X      modules, or just add the code    to the beginning of the
  707. X      modules themselves:
  708. X
  709. X           #ifndef _DEBUG_MALLOC_INC
  710. X           #define malloc_enter(func)
  711. X           #define malloc_leave(func)
  712. X           #define malloc_chain_check()
  713. X           #define malloc_dump(fd)
  714. X           #define malloc_list(a,b,c)
  715. X           #define malloc_inuse(hist)    (*(hist) =    0, 0)
  716. X           #endif
  717. X
  718. X      This will automatically disable the referenced functions
  719. X      when the malloc library is not included (as should be    the
  720. X      case when you    make a production build).
  721. X
  722. X     ENVIRONMENT VARIABLES
  723. X      Environment variables    can be used to control error handling,
  724. X      error    logging    and malloc chain checking at run time.    Most
  725. X      of these environment variables can be    set via    the
  726. X      dbmallopt() routine and are well described in    that portion
  727. X      of the document.  Look for further information there.
  728. X
  729. X      The following    environment variables are used:
  730. X
  731. X      MALLOC_BOUNDSIZE    This specifies the minimum number    of
  732. X                  bytes that the allocation    routines will
  733. X                  leave unused at the end of each segment.
  734. X                  This value may be    any non-zero positive
  735. X                  integer (although    you must remember that
  736. X                  the amount of memory used    is directly
  737. X                  related to this buffer area.
  738. X
  739. X                  It may be    necessary to increase this
  740. X                  value if you think you have a module
  741. X                  that is writing far enough beyond    its
  742. X                  malloc segment that it changes the next
  743. X                  segment (and therefore doesn't make a
  744. X                  change that this library would be    able
  745. X                  to detect.
  746. X
  747. X                  The default for this value is 1
  748. X
  749. X
  750. X
  751. X     Page 11               1.11
  752. X
  753. X
  754. X
  755. X
  756. X
  757. X
  758. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  759. X
  760. X
  761. X
  762. X                  (although    because    of memory alignment
  763. X                  issues, you will usually have more than
  764. X                  one byte of filler at the    end of most
  765. X                  segments).
  766. X      MALLOC_CKCHAIN      if 1, turns on malloc chain checking at
  767. X                  every call to any    of the malloc
  768. X                  functions.
  769. X      MALLOC_DETAIL          if set to    a non-zero integer,
  770. X                  malloc_dump shows    some internal detail
  771. X                  for each entry in    the chain.  This info
  772. X                  is probably only of use if you are
  773. X                  debugging    the malloc library itself.
  774. X      MALLOC_ERRFILE      specifies    the error log file for error
  775. X                  messages.     Error messages    generated by
  776. X                  the library are APPENDED to this file,
  777. X                  so if you    want a clean file, you will
  778. X                  have to remove or    empty it yourself
  779. X                  between runs.  If    this option is used,
  780. X                  no indication of an error    will be    sent
  781. X                  to stdout    or stderr (this    is
  782. X                  purposefully done    this way so that if
  783. X                  you are running a    full screen program,
  784. X                  it doesn't mess up the screen).
  785. X      MALLOC_FATAL          specifies    the error handling for fatal
  786. X                  errors
  787. X      MALLOC_FILLAREA     specifies    the fill area flag setting.
  788. X                  If zero, malloc/free area    filling    and
  789. X                  checking is disabled (thereby increasing
  790. X                  performance, while decreasing
  791. X                  effectiveness of the library).  See the
  792. X                  discussion of the    dbmallopt() arguments
  793. X                  for more info on other settings.
  794. X      MALLOC_FILLBYTE     This specifies the integer value of the
  795. X                  character    to use when filling allocated
  796. X                  areas.  This value defaults to 1 and
  797. X                  must be within the range of 0 - 255.
  798. X                  This capability is useful    if you believe
  799. X                  that you are having a problem with code
  800. X                  that is trashing its malloc region with
  801. X                  a    data pattern that matches the default
  802. X                  fill pattern.
  803. X
  804. X                  NOTE: if an attempt is made to use a
  805. X                  value outside the    specified range, the
  806. X                  new value    is silently ignored and    the
  807. X                  default is used.
  808. X      MALLOC_FREEBYTE     This specifies the integer value of the
  809. X                  character    to use when filling freed
  810. X                  areas.  This value defaults to 1 and
  811. X                  must be within the range of 0 - 255. It
  812. X                  should also be different from
  813. X                  MALLOC_FILLBYTE, but that    is not
  814. X
  815. X
  816. X
  817. X     Page 12               1.11
  818. X
  819. X
  820. X
  821. X
  822. X
  823. X
  824. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  825. X
  826. X
  827. X
  828. X                  enforced.
  829. X
  830. X                  NOTE: if an attempt is made to use a
  831. X                  value outside the    specified range, the
  832. X                  new value    is silently ignored and    the
  833. X                  default is used.
  834. X      MALLOC_LOWFRAG      if 1, turns on best fit allocation
  835. X                  algorithm.  Otherwise, first fit
  836. X                  algorithm    is used    for finding allocation
  837. X                  segments (which can cause    memory
  838. X                  fragmentation).
  839. X      MALLOC_CKDATA          if 0, disables checking of pointers
  840. X                  passed to    string/memory functions    for
  841. X                  malloc region overwrites.
  842. X      MALLOC_REUSE          if 0, disables reuse of freed memory
  843. X                  segments and it does not fill free'd
  844. X                  segments with the    fill pattern.  If 1,
  845. X                  freed segments are filled    and they can
  846. X                  be reused.  If 2,    freed segments can be
  847. X                  reused, but they are not filled when
  848. X                  freed.
  849. X      MALLOC_SHOW_LINKS   when an error is found, the suspected
  850. X                  allocation is displayed.    However, since
  851. X                  it is possible that the next or previous
  852. X                  allocation in the    malloc chain was the
  853. X                  actual culprit these links may be    of
  854. X                  interest.     If this variable is set to a
  855. X                  non-zero integer (i.e. 1)    the links will
  856. X                  also be shown.
  857. X      MALLOC_WARN          specifies    the error handling for warning
  858. X                  errors
  859. X
  860. X      As an    example, to set    up the session to generate a core file
  861. X      for every malloc warning, to drop core and exit on a malloc
  862. X      fatal, and to    log all    messages to the    file "malloc_log" do
  863. X      the following:
  864. X
  865. X           MALLOC_WARN=131
  866. X           MALLOC_FATAL=1
  867. X           MALLOC_ERRFILE=malloc_log
  868. X
  869. X           export MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE
  870. X
  871. X
  872. X
  873. X
  874. X
  875. X
  876. X
  877. X
  878. X
  879. X
  880. X
  881. X
  882. X
  883. X     Page 13               1.11
  884. X
  885. X
  886. X
  887. X
  888. X
  889. X
  890. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  891. X
  892. X
  893. X
  894. X     ERROR MESSAGES
  895. X      The following    error messages are reported by the library:
  896. X
  897. X      M_CODE_BAD_CONNECT        Pointers between this segment
  898. X                    and adjoining segments are
  899. X                    invalid.
  900. X
  901. X                    This error indicates that the
  902. X                    malloc chain has been
  903. X                    corrupted.  This is most often
  904. X                    caused by an overwrite of the
  905. X                    malloc header by an access via
  906. X                    the previous malloc segment.
  907. X
  908. X      M_CODE_BAD_MAGIC        Malloc region does not have a
  909. X                    valid magic number in header.
  910. X
  911. X                    This error is caused by
  912. X                    several    mechanisms including
  913. X                    free()ing the same pointer
  914. X                    twice or a pointer that    was
  915. X                    not returned by    malloc(), or
  916. X                    writing    beyond the end of a
  917. X                    segment.
  918. X
  919. X      M_CODE_BAD_PTR        Pointer    is not within malloc
  920. X                    region.
  921. X
  922. X                    The pointer passed to free
  923. X                    orrealloc is not pointer
  924. X                    returned by malloc.  Another
  925. X                    cause is corruption of the
  926. X                    malloc chain by    writing    beyond
  927. X                    the end    of a segment.
  928. X
  929. X      M_CODE_CHAIN_BROKE        Malloc chain is    corrupted,
  930. X                    pointers out of    order.
  931. X
  932. X                    Corruption has been detected
  933. X                    in the malloc chain that is
  934. X                    related    to the relative
  935. X                    positions of the malloc    chain
  936. X                    segments in memory.  This is
  937. X                    an indication that someone has
  938. X                    overwritten beyond the amount
  939. X                    they allocated.
  940. X
  941. X
  942. X
  943. X
  944. X
  945. X
  946. X
  947. X
  948. X
  949. X     Page 14               1.11
  950. X
  951. X
  952. X
  953. X
  954. X
  955. X
  956. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  957. X
  958. X
  959. X
  960. X      M_CODE_FREELIST_BAD        Malloc segment in free list is
  961. X                    in-use.
  962. X
  963. X                    A segment that is in the
  964. X                    free-list is flagged as    in-
  965. X                    use.  This is usually caused
  966. X                    by overwriting from the
  967. X                    previous segment in the    malloc
  968. X                    chain.
  969. X
  970. X      M_CODE_FREEMARK        Free called to free a segment
  971. X                    that has been marked.
  972. X
  973. X                    Marking    a segment is done
  974. X                    because    you believe that the
  975. X                    segment    will not be free'd and
  976. X                    therefore don't    want it    to
  977. X                    appear in the list of possible
  978. X                    leaks.    If you then go on to
  979. X                    free it, perhaps it shouldn't
  980. X                    have been marked.
  981. X
  982. X                    This error message can be
  983. X                    disabled with the
  984. X                    MALLOC_FREEMARK    option on the
  985. X                    dbmallopt() function.
  986. X
  987. X      M_CODE_NOBOUND        Unable to determine doubleword
  988. X                    boundary
  989. X
  990. X                    The code was unable to figure
  991. X                    out the    boundary requirements
  992. X                    for a doubleword.  This    error
  993. X                    should never occur.
  994. X
  995. X      M_CODE_NOMORE_MEM        Unable to get additional
  996. X                    memory from the    system.
  997. X
  998. X                    The system call    sbrk failed to
  999. X                    obtain more memory for the
  1000. X                    program.
  1001. X
  1002. X      M_CODE_NOT_INUSE        Data is    not in use (can't be
  1003. X                    freed or reallocated).
  1004. X
  1005. X                    A pointer to a malloc segment
  1006. X                    has been passed    to free() or
  1007. X                    realloc(), but this segment
  1008. X                    has already been freed.
  1009. X
  1010. X
  1011. X
  1012. X
  1013. X
  1014. X
  1015. X     Page 15               1.11
  1016. X
  1017. X
  1018. X
  1019. X
  1020. X
  1021. X
  1022. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  1023. X
  1024. X
  1025. X
  1026. X      M_CODE_NO_END            Malloc chain is    corrupted, end
  1027. X                    before end pointer.
  1028. X
  1029. X                    Yet another overwrite problem.
  1030. X                    This error means that we got
  1031. X                    to what    we believe is the end
  1032. X                    of the chain, but it does not
  1033. X                    match the recorded end of the
  1034. X                    chain.
  1035. X
  1036. X      M_CODE_OUTOF_BOUNDS        Pointer    within malloc region,
  1037. X                    but outside of malloc data
  1038. X                    bounds.
  1039. X
  1040. X                    This is    caused by a call to
  1041. X                    one of the string/memory
  1042. X                    functions that attempt to
  1043. X                    read/write bytes that are not
  1044. X                    included in the    allocation
  1045. X                    associated with    that memory.
  1046. X                    This is    the most typical error
  1047. X                    that you will see from the
  1048. X                    malloc library.
  1049. X
  1050. X      M_CODE_OVERRUN        Data has overrun beyond
  1051. X                    requested number of bytes.
  1052. X
  1053. X                    This error is detected by
  1054. X                    free() and indicates that the
  1055. X                    current    segment    has written
  1056. X                    data beyond the    number of
  1057. X                    bytes that it requested.  This
  1058. X                    only catches overwrites    when
  1059. X                    they are within    the extra
  1060. X                    space allocated    with each
  1061. X                    segment    (this can range    from
  1062. X                    one to eight bytes).  If the
  1063. X                    overwrite occurs further along
  1064. X                    it will    usually    cause some
  1065. X                    corruption in the malloc
  1066. X                    chain.
  1067. X
  1068. X      M_CODE_REUSE            Data in    free'd area has    been
  1069. X                    modified.
  1070. X
  1071. X                    Data in    a freed    segment    has
  1072. X                    been modified.    This usually
  1073. X                    indicates that the program is
  1074. X                    using a    pointer    after it
  1075. X                    called free, but it may    also
  1076. X                    be caused by an    overwrite from
  1077. X                    a previous segment in the
  1078. X
  1079. X
  1080. X
  1081. X     Page 16               1.11
  1082. X
  1083. X
  1084. X
  1085. X
  1086. X
  1087. X
  1088. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  1089. X
  1090. X
  1091. X
  1092. X                    chain.
  1093. X
  1094. X      M_CODE_STK_BADFUNC        Current    function name doesn't
  1095. X                    match name on stack.
  1096. X
  1097. X                    malloc_leave() was called with
  1098. X                    a function name    that is    not
  1099. X                    the current function.  This is
  1100. X                    usually    caused by a missing
  1101. X                    call to    malloc_enter() in the
  1102. X                    same function, or a missing
  1103. X                    call to    malloc_leave() in a
  1104. X                    sub-function.
  1105. X
  1106. X      M_CODE_STK_NOCUR        No current function on stack,
  1107. X                    probably missing call to
  1108. X                    malloc_enter().
  1109. X
  1110. X                    malloc_leave() was called with
  1111. X                    a function name    and there is
  1112. X                    no current function (the stack
  1113. X                    is empty). This    is usually
  1114. X                    caused by a missing call to
  1115. X                    malloc_enter(),    or an extra
  1116. X                    call to    malloc_leave() in the
  1117. X                    same function.
  1118. X
  1119. X      M_CODE_UNDERRUN        Data has written before
  1120. X                    beginning of requested bytes.
  1121. X
  1122. X                    This error is detected by
  1123. X                    free() and indicates that the
  1124. X                    current    segment    has written
  1125. X                    data before the    beginning of
  1126. X                    the requested block.  This
  1127. X                    only catches overwrites    when
  1128. X                    they are within    the extra
  1129. X                    space allocated    before each
  1130. X                    segment    (this is usually four
  1131. X                    bytes).     If the    overwrite
  1132. X                    occurs further back it will
  1133. X                    usually    cause some corruption
  1134. X                    in the malloc chain.
  1135. X
  1136. X      M_CODE_ZERO_ALLOC        An allocation routine was
  1137. X                    called to allocate zero    bytes.
  1138. X
  1139. X                    While ANSI C requires that
  1140. X                    allocations of zero bytes are
  1141. X                    permissible and    should be
  1142. X                    supported, the behavior    of
  1143. X                    such an    operation can be
  1144. X
  1145. X
  1146. X
  1147. X     Page 17               1.11
  1148. X
  1149. X
  1150. X
  1151. X
  1152. X
  1153. X
  1154. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  1155. X
  1156. X
  1157. X
  1158. X                    undefined on non-ANSI systems.
  1159. X                    This warning will alert    you to
  1160. X                    the locations where these
  1161. X                    calls are made.
  1162. X
  1163. X                    This error message can be
  1164. X                    disabled with the MALLOC_ZERO
  1165. X                    option on the dbmallopt()
  1166. X                    function.
  1167. X
  1168. X
  1169. X     DUMP OUTPUT
  1170. X      Sample dump/list output:
  1171. X
  1172. X           ************************** Dump of Malloc Chain ****************************
  1173. X           POINTER       FILE     WHERE           LINE     ALLOC          DATA     HEX DUMP
  1174. X           TO DATA        ALLOCATED          NUMBER     FUNCT         LENGTH  OF    BYTES 1-7
  1175. X           --------    -------------------- ------- -------------- ------- --------------
  1176. X           0x403DB4    teststack.c          75 malloc(1)         40 01010101010101
  1177. X            -> sub3() in teststack.c(73)
  1178. X            -> main() in teststack.c(23)
  1179. X           0x403E0C    testerr.c          16 realloc(1)         20 01010101010101
  1180. X
  1181. X      The info in each column is as    follows:
  1182. X
  1183. X      POINTER          the pointer returned by the allocation
  1184. X                  function (the pointer the    the allocated
  1185. X                  data area).
  1186. X
  1187. X      FILE              the name of the file where the
  1188. X                  allocation function was called.  This
  1189. X                  information is only available if the
  1190. X                  source file includes the malloc.h    file
  1191. X                  from this    library    (as opposed to the
  1192. X                  system include file).  If    the source
  1193. X                  file did not include this    file, the file
  1194. X                  will be listed as    unknown    and the    line
  1195. X                  number will be blank.  Note that any
  1196. X                  malloc calls from    system libraries will
  1197. X                  probably not have    been compiled with the
  1198. X                  malloc.h file included and will
  1199. X                  therefore    appear as unknown.
  1200. X
  1201. X      LINE NUM          The line number of the line that called
  1202. X                  the allocation function.    This field
  1203. X                  will be left blank if the    malloc.h from
  1204. X                  this library was not included in the
  1205. X                  source file when it was compiled.
  1206. X
  1207. X
  1208. X
  1209. X
  1210. X
  1211. X
  1212. X
  1213. X     Page 18               1.11
  1214. X
  1215. X
  1216. X
  1217. X
  1218. X
  1219. X
  1220. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  1221. X
  1222. X
  1223. X
  1224. X      ALLOC    FUNC          The allocation function called: malloc,
  1225. X                  realloc, or calloc.  The number in
  1226. X                  parenthesis following the    function name
  1227. X                  is the call number for that particular
  1228. X                  function.     For example: malloc(1)    means
  1229. X                  that this    allocation was the 1st call to
  1230. X                  malloc.
  1231. X
  1232. X      DATA LEN          The number of bytes allocated.
  1233. X
  1234. X      HEX DUMP          A    hexadecimal dump of the    first seven
  1235. X                  bytes in the allocated data.  This
  1236. X                  example shows the    bytes filled with
  1237. X                  0x01s which happen to be the fill
  1238. X                  pattern used by the malloc library (to
  1239. X                  make sure    that one doesn't depend    upon
  1240. X                  the fact that some calls to malloc
  1241. X                  result in    NULL bytes).  So the
  1242. X                  allocations that are shown haven't
  1243. X                  stored any data in the area yet.
  1244. X
  1245. X      The lines that begin with a "->" are stack dump lines    which
  1246. X      show the calling environment that was    present    when the are
  1247. X      was allocated.  The environment is managed via the use of
  1248. X      the malloc_enter() and malloc_leave()    routines.
  1249. X
  1250. X      If the environment variable MALLOC_DETAIL is non-zero, the
  1251. X      following additional information will    be included:
  1252. X
  1253. X           ************************************************************** Du...
  1254. X                        FREE     FREE           ACTUAL SIZE      ...
  1255. X         PTR      NEXT       PREV        NEXT     PREV      FLAGS       INT      HEX      ...
  1256. X           --------    -------- -------- -------- -------- ---------- --------    --------- ...
  1257. X           0x403C94    0x403CEC 0x40326C 0x000000 0x000000 0x03156111         48(0x000030) ...
  1258. X           0x403CEC    0x403D2C 0x403C94 0x000000 0x000000 0x03156121         24(0x000018) ...
  1259. X           0x403D2C    0x403D6C 0x403CEC 0x000000 0x403D6C 0x03156120         24(0x000018) ...
  1260. X           0x403D6C    0x000000 0x403D2C 0x403D2C 0x000000 0x03156120         24(0x000018) ...
  1261. X
  1262. X           Malloc start:      0x40326C
  1263. X           Malloc end:      0x403D2C
  1264. X           Malloc data start: 0x403C94
  1265. X           Malloc data end:      0x405C94
  1266. X           Malloc free list:  0x403D6C
  1267. X                   -> 0x403D2C
  1268. X
  1269. X      NOTE that I cut off the example at the point where the
  1270. X      normal output    would begin (hence the ...).
  1271. X
  1272. X      The info in each column is as    follows:
  1273. X
  1274. X      PTR          The malloc chain pointer for the segment
  1275. X              (the address of the segment).
  1276. X
  1277. X
  1278. X
  1279. X     Page 19               1.11
  1280. X
  1281. X
  1282. X
  1283. X
  1284. X
  1285. X
  1286. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  1287. X
  1288. X
  1289. X
  1290. X      NEXT          The pointer to the next segment in the
  1291. X              chain.
  1292. X
  1293. X      PREV          The pointer to the previous segment in the
  1294. X              chain.
  1295. X
  1296. X      FREE NEXT      The pointer to the next segment in the free
  1297. X              list.
  1298. X
  1299. X      FREE PREV      The pointer to the previous segment in the
  1300. X              free list.
  1301. X
  1302. X      FLAGS          The flags associated with this segment.
  1303. X              This is a long integer which contains    the
  1304. X              following fields
  1305. X
  1306. X              0xFFFFFF00  the magic    number.     This should
  1307. X                      be 0x03156100 (probably
  1308. X                      someone's    birthday).
  1309. X
  1310. X              0x00000070  the type of allocation function.
  1311. X                      Malloc (x010), realloc (0x20),
  1312. X                      or calloc    (0x30) are the only
  1313. X                      valid values for this field).
  1314. X
  1315. X              0x00000001  the in-use flag.    if this    value
  1316. X                      is non-zero, the indicated
  1317. X                      segment is currently in use (not
  1318. X                      freed).
  1319. X
  1320. X      ACTUAL SIZE      The actual size reserved for the allocation
  1321. X              in both decimal and hex.  This will be at
  1322. X              least    one byte more than the requested size,
  1323. X              and as much as 8, so that we can check to
  1324. X              see if the allocation    has been overrun.
  1325. X
  1326. X      Malloc start and end are pointers to the first and last
  1327. X      malloc chain segment,    respectively.
  1328. X
  1329. X      Malloc data start and    data end are the lowest    and highest
  1330. X      data bytes managed my    the malloc sub-system.    These are only
  1331. X      used as a quick check    to see if a pointer is in the malloc
  1332. X      region before    we go hunting down the chain trying to
  1333. X      identify the segment it belongs to.
  1334. X
  1335. X      Malloc free list is a    chain of the elements in the free list
  1336. X      (so it is easier for the programmer to follow    the free list
  1337. X      if they choose to).  The address of each element in the list
  1338. X      follows below    the list head.
  1339. X
  1340. X
  1341. X
  1342. X
  1343. X
  1344. X
  1345. X     Page 20               1.11
  1346. X
  1347. X
  1348. X
  1349. X
  1350. X
  1351. X
  1352. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  1353. X
  1354. X
  1355. X
  1356. X     X PROGRAM DEBUGGING
  1357. X      The malloc library includes a    set of compatibility routines
  1358. X      for the Xt toolkit allocation    routines: XtMalloc(),
  1359. X      XtCalloc(), XtRealloc(),and XtFree().      These    routines
  1360. X      provide the same level of malloc area    integrity checking
  1361. X      that is provided by the basic    malloc functions while
  1362. X      maintaining complete compatibility with the X11R5 functions.
  1363. X
  1364. X      If you link an X package with    the debug library and you make
  1365. X      a call to any    of the Xt allocation routines, the debug
  1366. X      modules will automatically be    included.  If you don't    call
  1367. X      them directly, but you still want to include them in order
  1368. X      to better debug their    use, you can add a -u linker
  1369. X      specification    for XtRealloc.    For example:
  1370. X
  1371. X           cc -o xapp -u XtRealloc xapp.o -ldbmalloc -lXt -lX....
  1372. X
  1373. X      Note that you    may have to add    an underscore before the
  1374. X      XtRealloc if your compiler does this automatically.
  1375. X
  1376. X      A second potential problem with X is caused by a difference
  1377. X      between X11R4    and X11R5.  If you only    have one of theses
  1378. X      packages, then the malloc library will be automatically
  1379. X      configured to    handle that package.  If, however, you have
  1380. X      both of them installed and you need to be able to link with
  1381. X      either system, you may have to add a -u _XtHeapInit to the
  1382. X      link line on the X11R5 links.     This is because X11R5 defines
  1383. X      both the heap    management and malloc management routines in
  1384. X      the same module, while X11R4 defines them in different
  1385. X      modules.
  1386. X
  1387. X      The sign of this problem is a    link error due to duplicate
  1388. X      references to    the Xt allocation routines (XtMalloc, etc).
  1389. X
  1390. X     LINKING
  1391. X      The order in which you link your programs can    have a
  1392. X      significant effect on    the usefulness of the library and even
  1393. X      on the ability to link itself.  The debug library should be
  1394. X      placed as the    first system library that you are linking to
  1395. X      (assuming that you are calling at least one of the malloc,
  1396. X      string, or memory functions).
  1397. X
  1398. X      For example, if the following    is your    normal link command:
  1399. X
  1400. X           cc -o app app.o supp.o else.o applib.a -lmath -lcurses
  1401. X
  1402. X      You should add the malloc debug library in between applib.a
  1403. X      and -lmath, which would result in the    following:
  1404. X
  1405. X
  1406. X
  1407. X
  1408. X
  1409. X
  1410. X
  1411. X     Page 21               1.11
  1412. X
  1413. X
  1414. X
  1415. X
  1416. X
  1417. X
  1418. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  1419. X
  1420. X
  1421. X
  1422. X           cc -o app app.o supp.o else.o applib.a -ldbmalloc -lmath    -lcurses
  1423. X
  1424. X      This will ensure that    the debug malloc library overrides all
  1425. X      of the allocation routines within the    other libraries.
  1426. X
  1427. X      If you have other problems compiling or linking with the
  1428. X      library you should look at the PROBLEMS file in the source
  1429. X      directory.  This file    contains descriptions of common
  1430. X      problems and the recommended solutions to the    problems.
  1431. X
  1432. X     PERFORMANCE
  1433. X      This malloc library and its associated string    and memory
  1434. X      functions are    much less efficient than the standard
  1435. X      functions due    in part    to the extra error checking.  You do
  1436. X      not want to use this library when generating a production
  1437. X      (i.e.    releasable) version of your software.  It should only
  1438. X      be used during development and testing.
  1439. X
  1440. X      The following    environment variable settings will give    you
  1441. X      the best performance (at the expense of some additional
  1442. X      error    checking):
  1443. X
  1444. X           MALLOC_CKCHAIN=0
  1445. X           MALLOC_CKDATA=0
  1446. X           MALLOC_FILLAREA=0
  1447. X           MALLOC_LOWFRAG=0
  1448. X
  1449. X      We recommend against setting MALLOC_FILLAREA to zero
  1450. X      because, while it will increase the performance, it takes
  1451. X      away the capability to uncover small malloc overruns which
  1452. X      don't    overrite the pointers surrounding the malloc regions.
  1453. X      The same anti-recommendation applies to MALLOC_CKDATA.
  1454. X
  1455. X      Anyway, with these settings, the malloc library runs at
  1456. X      about    1/2 the    speed (things only take    twice as long) as the
  1457. X      standard library.  If    you program spends most    of its time in
  1458. X      malloc, it will still    be slow    (but perhaps this is an
  1459. X      indication that you need to consider changing    the way    you
  1460. X      are using malloc).
  1461. X
  1462. X
  1463. X
  1464. X
  1465. X
  1466. X
  1467. X
  1468. X
  1469. X
  1470. X
  1471. X
  1472. X
  1473. X
  1474. X
  1475. X
  1476. X
  1477. X     Page 22               1.11
  1478. X
  1479. X
  1480. X
  1481. X
  1482. X
  1483. X
  1484. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  1485. X
  1486. X
  1487. X
  1488. X     WARNINGS
  1489. X      The include file for this library "malloc.h" should be
  1490. X      included after the includes for any system related
  1491. X      information.    This is    because    "malloc.h" redefines several
  1492. X      system functions including string and    memory routines    and
  1493. X      this will usually cause compilation errors if    malloc.h is
  1494. X      processed first (of course, the compile errors will talk
  1495. X      about    errors in the other system include files like
  1496. X      string.h).
  1497. X
  1498. X      This goes hand in hand with the fact that if you have    local
  1499. X      definitions of the return types of standard functions    like
  1500. X      strcmp() or malloc(),    these lines will cause compile errors
  1501. X      due to the #defines in the malloc.h header file.  Therefore,
  1502. X      it is    suggested that you remove all such definitions from
  1503. X      your code and    rely on    the system header files    to define
  1504. X      these    functions, or you surround the definitions with    #ifdef
  1505. X      DEBUG_MALLOC_INC.
  1506. X
  1507. X      There    is a possibility that the use of sbrk()    by other
  1508. X      modules will cause this library to get confused and possibly
  1509. X      report some pointers as bad when the really aren't part of
  1510. X      the malloc chain itself.  Therefore the direct use of    sbrk()
  1511. X      is strongly discouraged.
  1512. X
  1513. X      This library attempts    to trap    errors and exit/handle them
  1514. X      gracefully. However, the nature of the problems may be such
  1515. X      that it causes the code in the library itself    to crash.
  1516. X      There    is no way to avoid this, but if    it does    occur,    turn
  1517. X      on chain checking to narrow the place    where it will occur.
  1518. X
  1519. X      The functions    in this    library    will often conflict with
  1520. X      duplicate functions in shared    library    versions of libc.a.
  1521. X      This is usually due to the fact that some shared library
  1522. X      modules have explicit    references to shared library versions
  1523. X      of the debug functions.  The only way    around this is to not
  1524. X      use the shared library when linking.
  1525. X
  1526. X      This malloc library, like most malloc    libraries, is not re-
  1527. X      entrant and therefore    should not be called from interrupt
  1528. X      handlers because of the potential for    receiving an interrupt
  1529. X      in the middle    of a call to malloc which would    really mess
  1530. X      things up.
  1531. X
  1532. X     SEE ALSO
  1533. X      malloc(3), string(3),    memory(3)
  1534. X
  1535. X
  1536. X
  1537. X
  1538. X
  1539. X
  1540. X
  1541. X
  1542. X
  1543. X     Page 23               1.11
  1544. X
  1545. X
  1546. X
  1547. X
  1548. X
  1549. X
  1550. X     DEBUG_MALLOC(3)           (VTI)           DEBUG_MALLOC(3)
  1551. X
  1552. X
  1553. X
  1554. X     COPYRIGHT
  1555. X       (c) Copyright 1990, 1991, 1992 Conor    P. Cahill (cpcahil@virtech.vti.com)
  1556. X
  1557. X       This    software may be    distributed freely as long as the following conditions
  1558. X       are met:
  1559. X          * the    distribution, or any derivative    thereof, may not be
  1560. X            included as    part of    a commercial product
  1561. X          * full source    code is    provided including this    copyright
  1562. X          * there is no    charge for the software    itself (there may be
  1563. X            a minimal charge for the copying or    distribution effort)
  1564. X          * this copyright notice is not modified or removed from any
  1565. X              source file
  1566. X
  1567. X
  1568. X     AUTHOR
  1569. X      Conor    P. Cahill
  1570. X      Virtual Technologies Incorporated
  1571. X      46030    Manekin    Plaza, Suite 160
  1572. X      Sterling VA 22170
  1573. X      703-430-9247
  1574. X
  1575. X      cpcahil@virtech.vti.com
  1576. X      uunet!virtech!cpcahil
  1577. X
  1578. X
  1579. X
  1580. X
  1581. X
  1582. X
  1583. X
  1584. X
  1585. X
  1586. X
  1587. X
  1588. X
  1589. X
  1590. X
  1591. X
  1592. X
  1593. X
  1594. X
  1595. X
  1596. X
  1597. X
  1598. X
  1599. X
  1600. X
  1601. X
  1602. X
  1603. X
  1604. X
  1605. X
  1606. X
  1607. X
  1608. X
  1609. X     Page 24               1.11
  1610. X
  1611. X
  1612. X
  1613. END_OF_FILE
  1614. if test 45140 -ne `wc -c <'malloc.man'`; then
  1615.     echo shar: \"'malloc.man'\" unpacked with wrong size!
  1616. fi
  1617. # end of 'malloc.man'
  1618. fi
  1619. if test -f 'size.c' -a "${1}" != "-c" ; then 
  1620.   echo shar: Will not clobber existing file \"'size.c'\"
  1621. else
  1622. echo shar: Extracting \"'size.c'\" \(3417 characters\)
  1623. sed "s/^X//" >'size.c' <<'END_OF_FILE'
  1624. X/*
  1625. X * (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
  1626. X *
  1627. X * This software may be distributed freely as long as the following conditions
  1628. X * are met:
  1629. X *         * the distribution, or any derivative thereof, may not be
  1630. X *          included as part of a commercial product
  1631. X *        * full source code is provided including this copyright
  1632. X *        * there is no charge for the software itself (there may be
  1633. X *          a minimal charge for the copying or distribution effort)
  1634. X *        * this copyright notice is not modified or removed from any
  1635. X *          source file
  1636. X */
  1637. X#include <stdio.h>
  1638. X#include "mallocin.h"
  1639. X#include "debug.h"
  1640. X
  1641. X/*
  1642. X * Function:    malloc_size()
  1643. X *
  1644. X * Purpose:    return the size of the allocated segment associated with ptr
  1645. X *
  1646. X * Arguments:    ptr    - pointer to allocated area 
  1647. X *
  1648. X * Returns:    the size of the segment
  1649. X *
  1650. X * Narrative:
  1651. X *        verify pointer is within malloc region
  1652. X *        get mlist pointer from passed address
  1653. X *        verify magic number
  1654. X *        verify inuse flag
  1655. X *        verify pointer connections with surrounding segments
  1656. X *        return size of segment
  1657. X */
  1658. X#ifndef lint
  1659. Xstatic
  1660. Xchar rcs_hdr[] = "$Id: size.c,v 1.4 1992/08/22 16:27:13 cpcahil Exp $";
  1661. X#endif
  1662. X
  1663. XSIZETYPE
  1664. Xmalloc_size(cptr)
  1665. X    CONST DATATYPE    * cptr;
  1666. X{
  1667. X    return( DBmalloc_size((char *)NULL, 0, cptr) );
  1668. X}
  1669. X
  1670. XSIZETYPE
  1671. XDBmalloc_size(file,line,cptr)
  1672. X    CONST char    * file;
  1673. X    int          line;
  1674. X    CONST DATATYPE    * cptr;
  1675. X{
  1676. X    char            * func = "malloc_size";
  1677. X    register struct mlist    * ptr;
  1678. X
  1679. X    /*
  1680. X     * initialize the malloc sub-system.
  1681. X     */
  1682. X    MALLOC_INIT();
  1683. X
  1684. X    /*
  1685. X     * IF malloc chain checking is on, go do it.
  1686. X     */
  1687. X    if( malloc_opts & MOPT_CKCHAIN )
  1688. X    {
  1689. X        VOIDCAST DBFmalloc_chain_check(func,file,line,1);
  1690. X    }
  1691. X
  1692. X    /*
  1693. X     * verify that cptr is within the malloc region and that it is on
  1694. X     * the correct alignment
  1695. X     */
  1696. X    if(        (cptr < malloc_data_start)
  1697. X        || (cptr > malloc_data_end)
  1698. X        || ((((long)cptr) & malloc_round) != 0)  )
  1699. X    {
  1700. X        malloc_errno = M_CODE_BAD_PTR;
  1701. X        malloc_warning(func,file,line,(struct mlist *)NULL);
  1702. X        return( (SIZETYPE) -1);
  1703. X    }
  1704. X
  1705. X    /* 
  1706. X     * convert pointer to mlist struct pointer.  To do this we must 
  1707. X     * move the pointer backwards the correct number of bytes...
  1708. X     */
  1709. X    ptr = DATATOMLIST(cptr);
  1710. X
  1711. X    /*
  1712. X     * check the magic number 
  1713. X     */    
  1714. X    if( (ptr->flag&M_MAGIC_BITS) != M_MAGIC )
  1715. X    {
  1716. X        malloc_errno = M_CODE_BAD_MAGIC;
  1717. X        malloc_warning(func,file,line,(struct mlist *)NULL);
  1718. X        return((SIZETYPE) -1);
  1719. X    }
  1720. X
  1721. X    /*
  1722. X     * if this segment is not flagged as being in use
  1723. X     */
  1724. X    if( ! (ptr->flag & M_INUSE) )
  1725. X    {
  1726. X        malloc_errno = M_CODE_NOT_INUSE;
  1727. X        malloc_warning(func,file,line,ptr);
  1728. X        return( (SIZETYPE) -1 );
  1729. X    }
  1730. X
  1731. X    /*
  1732. X     * check to see that the pointers are still connected
  1733. X     */
  1734. X     if( (ptr->prev && (ptr->prev->next != ptr) ) ||
  1735. X        (ptr->next && (ptr->next->prev != ptr) ) ||
  1736. X        ((ptr->next == NULL) && (ptr->prev == NULL)) )
  1737. X    {
  1738. X        malloc_errno = M_CODE_BAD_CONNECT;
  1739. X        malloc_warning(func,file,line,ptr);
  1740. X        return( (SIZETYPE) -1 );
  1741. X    }
  1742. X
  1743. X    /*
  1744. X     * check fill regions for overflow
  1745. X     */
  1746. X    VOIDCAST FILLCHECK(func,file,line,ptr,SHOWERRORS);
  1747. X
  1748. X    return(ptr->r_size);
  1749. X
  1750. X} /* DBmalloc_size(... */
  1751. X
  1752. X/*
  1753. X * $Log: size.c,v $
  1754. X * Revision 1.4  1992/08/22  16:27:13  cpcahil
  1755. X * final changes for pl14
  1756. X *
  1757. X * Revision 1.3  1992/07/03  00:03:25  cpcahil
  1758. X * more fixes for pl13, several suggestons from Rich Salz.
  1759. X *
  1760. X * Revision 1.2  1992/07/02  15:35:52  cpcahil
  1761. X * misc cleanups for PL13
  1762. X *
  1763. X * Revision 1.1  1992/07/02  13:49:54  cpcahil
  1764. X * added support for new malloc_size function and additional tests to testerr
  1765. X *
  1766. X */
  1767. END_OF_FILE
  1768. if test 3417 -ne `wc -c <'size.c'`; then
  1769.     echo shar: \"'size.c'\" unpacked with wrong size!
  1770. fi
  1771. # end of 'size.c'
  1772. fi
  1773. if test -f 'testerr.c' -a "${1}" != "-c" ; then 
  1774.   echo shar: Will not clobber existing file \"'testerr.c'\"
  1775. else
  1776. echo shar: Extracting \"'testerr.c'\" \(4588 characters\)
  1777. sed "s/^X//" >'testerr.c' <<'END_OF_FILE'
  1778. X/*
  1779. X * (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
  1780. X *
  1781. X * This software may be distributed freely as long as the following conditions
  1782. X * are met:
  1783. X *         * the distribution, or any derivative thereof, may not be
  1784. X *          included as part of a commercial product
  1785. X *        * full source code is provided including this copyright
  1786. X *        * there is no charge for the software itself (there may be
  1787. X *          a minimal charge for the copying or distribution effort)
  1788. X *        * this copyright notice is not modified or removed from any
  1789. X *          source file
  1790. X */
  1791. X#include "sysdefs.h"
  1792. X#include <stdio.h>
  1793. X#if ANSI_HEADERS
  1794. X#include <stdlib.h>
  1795. X#endif
  1796. X#include <sys/types.h>
  1797. X#include "malloc.h"
  1798. X
  1799. X#define ALLOCSIZE    20
  1800. X#define BIG_ALIGN    (4*1024)
  1801. X#define SMALL_ALIGN    (1*1024)
  1802. X
  1803. X/*ARGSUSED*/
  1804. Xint
  1805. Xmain(argc,argv)
  1806. X    int              argc;
  1807. X    char            **argv[];
  1808. X{
  1809. X
  1810. X    union dbmalloptarg      m;
  1811. X    unsigned long          oldsize;
  1812. X    char            * s;
  1813. X    unsigned long          size;
  1814. X    char            * t;
  1815. X    char            * u;
  1816. X
  1817. X
  1818. X    /*
  1819. X     * make sure we have both chain checking and fill area enabled
  1820. X     */
  1821. X    m.i = 1;
  1822. X    dbmallopt(MALLOC_CKCHAIN,&m);
  1823. X    m.i = 3;
  1824. X    dbmallopt(MALLOC_FILLAREA,&m);
  1825. X
  1826. X    /*
  1827. X     * test leak detection software
  1828. X     */
  1829. X    fprintf(stderr,"-------------------------------------\n");
  1830. X    fprintf(stderr,"Testing malloc_inuse()...");
  1831. X    oldsize = malloc_inuse( (unsigned long *)0);
  1832. X    s = malloc(ALLOCSIZE);
  1833. X    size = malloc_inuse( (unsigned long *)0);
  1834. X    if( size != (oldsize + ALLOCSIZE))
  1835. X    {
  1836. X        fprintf(stderr,"ERROR\n");
  1837. X        fprintf(stderr,"\toldsize = %lu, size = %lu - should be %lu\n",
  1838. X            oldsize, size, oldsize+ALLOCSIZE);
  1839. X    }
  1840. X    else
  1841. X    {
  1842. X        fprintf(stderr,"OK\n");
  1843. X    }
  1844. X    
  1845. X    fprintf(stderr,"-------------------------------------\n");
  1846. X    fprintf(stderr,"Testing malloc_mark()...");
  1847. X    malloc_mark(s);
  1848. X    size = malloc_inuse( (unsigned long *) 0);
  1849. X    if( size != oldsize )
  1850. X    {
  1851. X        fprintf(stderr,"ERROR\n");
  1852. X        fprintf(stderr,"\tsize = %lu, should be %lu\n",size,oldsize);
  1853. X    }
  1854. X    else
  1855. X    {
  1856. X        fprintf(stderr,"OK\n");
  1857. X    }
  1858. X
  1859. X    /*
  1860. X     * test new malloc_size function
  1861. X     */
  1862. X    fprintf(stderr,"-------------------------------------\n");
  1863. X    fprintf(stderr,"Testing malloc_size()...");
  1864. X    size = malloc_size(s);
  1865. X    if( size != ALLOCSIZE )
  1866. X    {
  1867. X        fprintf(stderr,"ERROR\n");
  1868. X        fprintf(stderr,"\tsize = %lu, should be %d\n",size,ALLOCSIZE);
  1869. X    }
  1870. X    else
  1871. X    {
  1872. X        fprintf(stderr,"OK\n");
  1873. X    }
  1874. X            
  1875. X        
  1876. X    /*
  1877. X     * test memalign
  1878. X     */
  1879. X    fprintf(stderr,"-------------------------------------\n");
  1880. X    fprintf(stderr,"Testing memalign()...");
  1881. X    s = memalign((SIZETYPE)BIG_ALIGN,(SIZETYPE)10);
  1882. X    t = memalign((SIZETYPE)BIG_ALIGN,(SIZETYPE)20);
  1883. X    if( (s == NULL) || ((((SIZETYPE)s)&(BIG_ALIGN-1)) != 0)
  1884. X            || ((((SIZETYPE)t)&(SMALL_ALIGN-1)) != 0) )
  1885. X    {
  1886. X        fprintf(stderr,"ERROR\n");
  1887. X        fprintf(stderr,"\ts = 0x%lx(align=%d), t = 0x%lx(align=%d)\n",
  1888. X            s, BIG_ALIGN, t, SMALL_ALIGN);
  1889. X    }
  1890. X    else
  1891. X    {
  1892. X        fprintf(stderr,"OK\n");
  1893. X    }
  1894. X    
  1895. X    s = memalign((SIZETYPE)4096,(SIZETYPE)10);
  1896. X    
  1897. X
  1898. X    t = malloc(20);
  1899. X
  1900. X    s = malloc(10);
  1901. X
  1902. X    fprintf(stderr,"-------------------------------------\n");
  1903. X    fprintf(stderr,"Error from strcpy() - out of bounds\n");
  1904. X    fflush(stderr);
  1905. X    strncpy(s," ",11);
  1906. X
  1907. X    fprintf(stderr,"-------------------------------------\n");
  1908. X    fprintf(stderr,"Error from memset() - out of bounds (beyond)\n");
  1909. X    fflush(stderr);
  1910. X    memset(t,' ',21);
  1911. X
  1912. X    fprintf(stderr,"-------------------------------------\n");
  1913. X    fprintf(stderr,"Error from free() - overrun\n");
  1914. X    fflush(stderr);
  1915. X    free(t);
  1916. X
  1917. X    fprintf(stderr,"-------------------------------------\n");
  1918. X    fprintf(stderr,"Error from free() - double free\n");
  1919. X    fflush(stderr);
  1920. X    free(t);
  1921. X
  1922. X    fprintf(stderr,"-------------------------------------\n");
  1923. X    fprintf(stderr,"NO error from bzero\n");
  1924. X    fflush(stderr);
  1925. X    bzero(s,10);
  1926. X
  1927. X    fprintf(stderr,"-------------------------------------\n");
  1928. X    fprintf(stderr,"Error from bzero() - out of bounds\n");
  1929. X    fflush(stderr);
  1930. X    bzero(s,11);
  1931. X
  1932. X    fprintf(stderr,"-------------------------------------\n");
  1933. X    fprintf(stderr,"Error from free() - overrun\n");
  1934. X    fflush(stderr);
  1935. X    free(s);
  1936. X
  1937. X    u = malloc(1);
  1938. X
  1939. X    fprintf(stderr,"-------------------------------------\n");
  1940. X    fprintf(stderr,"Error from memset() - out of bounds (before)\n");
  1941. X    fflush(stderr);
  1942. X    memset(u-2,' ',3);
  1943. X
  1944. X    fprintf(stderr,"-------------------------------------\n");
  1945. X    fprintf(stderr,"Error from free() - underrun\n");
  1946. X    fflush(stderr);
  1947. X    free(u);
  1948. X
  1949. X    s = malloc(10);
  1950. X    t = malloc(500);     /* do this to make sure memset doesnt core */
  1951. X
  1952. X    fprintf(stderr,"-------------------------------------\n");
  1953. X    fprintf(stderr,"Error from memset() - out of bounds\n");
  1954. X    fflush(stderr);
  1955. X    memset(s,'1',100);
  1956. X
  1957. X    
  1958. X    fprintf(stderr,"-------------------------------------\n");
  1959. X    fprintf(stderr,"Error from malloc() - chain broken\n");
  1960. X    fflush(stderr);
  1961. X    t = malloc(10);
  1962. X    
  1963. X    return(0);
  1964. X}
  1965. X
  1966. END_OF_FILE
  1967. if test 4588 -ne `wc -c <'testerr.c'`; then
  1968.     echo shar: \"'testerr.c'\" unpacked with wrong size!
  1969. fi
  1970. # end of 'testerr.c'
  1971. fi
  1972. echo shar: End of archive 7 \(of 10\).
  1973. cp /dev/null ark7isdone
  1974. MISSING=""
  1975. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  1976.     if test ! -f ark${I}isdone ; then
  1977.     MISSING="${MISSING} ${I}"
  1978.     fi
  1979. done
  1980. if test "${MISSING}" = "" ; then
  1981.     echo You have unpacked all 10 archives.
  1982.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1983. else
  1984.     echo You still need to unpack the following archives:
  1985.     echo "        " ${MISSING}
  1986. fi
  1987. ##  End of shell archive.
  1988. exit 0
  1989. *** SENTINEL(tm) The ultimate Debugging Environment - email for more info ***
  1990.  
  1991. Conor P. Cahill              (703)430-9247            cpcahil@virtech.vti.com
  1992. Virtual Technologies, Inc.  46030 Manekin Plaza          Dulles, VA 21066 
  1993.  
  1994. exit 0 # Just in case...
  1995.