home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume22 / debug_malloc / part01 next >
Text File  |  1990-10-09  |  49KB  |  1,956 lines

  1. Subject:  v22i112:  Debugging malloc() library, Part01/02
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: e80a5aa3 4d17bf71 233d6222 ad37b7d8
  5.  
  6. Submitted-by: "Conor P. Cahill" <virtech!cpcahil@uunet.uu.net>
  7. Posting-number: Volume 22, Issue 112
  8. Archive-name: debug_malloc/part01
  9.  
  10. This package is a collection of routines which are a drop-in replacement
  11. for the malloc(3), memory(3), string(3), and bstring(3) library functions.
  12.  
  13. To use these functions all you need to do is compile the library and
  14. include it on your loader command line.  You do not need to recompile
  15. your code, only a relink is necessary.  
  16.  
  17. Features of this library include:
  18.  1. The malloced area returned from each call to malloc is filled with
  19.     non-null bytes.
  20.  2. When free is called numerous validity checks are made on the 
  21.     pointer it is passed.  In addition, the data in the malloc block
  22.     beyound the size requested on the initial malloc is checked to 
  23.     verify that it is still filled with the original fill characters.
  24.     And finally, the freed block is filled with a different fill pattern
  25.  3. Whenever a bstring(3)/string(3)/memory(3) function is called, it's 
  26.     parameters are checked.
  27.  4. The operations to perform when an error is detected are specified at
  28.     run time by the use of environment variables.
  29.  
  30.   This code is already at patchlevel 1.
  31.  
  32. Conor.
  33.  
  34. Submitted-by: cpcahil@virtech
  35. Archive-name: Malloclib/part01
  36.  
  37. #!/bin/sh
  38. # This is Malloclib, a shell archive (shar 3.21)
  39. # made 06/21/1990 14:37 UTC by cpcahil@virtech
  40. # Source directory /usr/local/src/lib/malloclib
  41. #
  42. # existing files will NOT be overwritten
  43. #
  44. # This shar contains:
  45. # length  mode       name
  46. # ------ ---------- ------------------------------------------
  47. #   1138 -r--r--r-- Makefile
  48. #   4758 -rw-rw-r-- README
  49. #      2 -rw-rw-rw- patchlevel
  50. #   1481 -r--r--r-- calloc.c
  51. #   2628 -r--r--r-- debug.h
  52. #   3097 -r--r--r-- dump.c
  53. #   4379 -r--r--r-- free.c
  54. #   1751 -r--r--r-- m_init.c
  55. #   1776 -r--r--r-- m_perror.c
  56. #   6694 -r--r--r-- malloc.3
  57. #  12756 -r--r--r-- malloc.c
  58. #   2346 -r--r--r-- malloc.h
  59. #   5125 -r--r--r-- malloc_chk.c
  60. #   3449 -r--r--r-- malloc_chn.c
  61. #   2128 -r--r--r-- mallopt.c
  62. #   2817 -r--r--r-- memory.c
  63. #   4496 -r--r--r-- realloc.c
  64. #   8521 -r--r--r-- string.c
  65. #   3971 -r--r--r-- testmalloc.c
  66. #   2552 -r--r--r-- testmem.c
  67. #   2716 -r--r--r-- tostring.c
  68. #    491 -r--r--r-- tostring.h
  69. #
  70. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  71.  then TOUCH=touch
  72.  else TOUCH=true
  73. fi
  74. # ============= Makefile ==============
  75. if test X"$1" != X"-c" -a -f 'Makefile'; then
  76.     echo "File already exists: skipping 'Makefile'"
  77. else
  78. echo "x - extracting Makefile (Text)"
  79. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  80. X#
  81. X# (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  82. X# You may copy, distribute, and use this software as long as this
  83. X# copyright statement is not removed.
  84. X#
  85. X#
  86. X# This is the Makefile for the malloc debugging library
  87. X#
  88. X# $Id: Makefile,v 1.3 90/06/21 10:37:06 cpcahil Exp $
  89. X#
  90. XCC=cc
  91. X# for System V systems use this CFLAGS
  92. XCFLAGS=-g -DSYS5
  93. X# else for BSD use:
  94. X#CFLAGS=-g
  95. XSHARCMD=shar -o mallocshar -l50 -x -a -n Malloclib
  96. X
  97. XLIB=libmalloc.a
  98. X
  99. XOBJS=    malloc.o    \
  100. X    free.o        \
  101. X    realloc.o    \
  102. X    calloc.o    \
  103. X    string.o    \
  104. X    malloc_chk.o    \
  105. X    malloc_chn.o    \
  106. X    memory.o    \
  107. X    tostring.o    \
  108. X    m_perror.o    \
  109. X    m_init.o    \
  110. X    mallopt.o    \
  111. X    dump.o
  112. X
  113. XTESTS=testmalloc testmem
  114. X
  115. Xall:    $(LIB) $(TESTS)
  116. X
  117. Xclean:  
  118. X    rm -f $(TESTS) pgm $(LIB) *.o *.ln
  119. X
  120. Xsharfile:
  121. X    $(SHARCMD) Makefile README patchlevel *.[ch3] 
  122. X    
  123. X$(LIB): $(OBJS)
  124. X    ar -ru $(LIB) $(OBJS)
  125. X    -if test -s /bin/ranlib; then /bin/ranlib $(LIB); else exit 0; fi
  126. X    -if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(LIB); else exit 0; fi
  127. X
  128. Xtestmalloc:    $(LIB) testmalloc.o
  129. X    $(CC) -o $@ testmalloc.o $(LIB)
  130. X
  131. Xtestmem:    $(LIB) testmem.o
  132. X    $(CC) -o $@ testmem.o $(LIB)
  133. X
  134. X$(OBJS):    malloc.h
  135. X
  136. Xtostring.o malloc.o dump.o:    tostring.h
  137. SHAR_EOF
  138. $TOUCH -am 0621103790 Makefile &&
  139. chmod 0444 Makefile ||
  140. echo "restore of Makefile failed"
  141. set `wc -c Makefile`;Wc_c=$1
  142. if test "$Wc_c" != "1138"; then
  143.     echo original size 1138, current size $Wc_c
  144. fi
  145. fi
  146. # ============= README ==============
  147. if test X"$1" != X"-c" -a -f 'README'; then
  148.     echo "File already exists: skipping 'README'"
  149. else
  150. echo "x - extracting README (Text)"
  151. sed 's/^X//' << 'SHAR_EOF' > README &&
  152. X# (c) Copyright 1990 Conor P. Cahill. (uunet!virtech!cpcahil) 
  153. X# You may copy, distribute, and use this software as long as this
  154. X# copyright statement is not removed.
  155. X
  156. XThis package is a collection of routines which are a drop-in replacement
  157. Xfor the malloc(3), memory(3), string(3), and bstring(3) library functions.
  158. X
  159. XThe purpose of these programs is to aid the development and/or debugging
  160. Xof programs using these functions by providing a high level of consistancy
  161. Xchecking whenever a malloc pointer is used.  Due to this increased 
  162. Xlevel of consistancy checking, these functions have a considerably larger
  163. Xoverhead than the standard functions, but the extra checking should be
  164. Xwell worth it in a development environment.
  165. X
  166. XTo use these functions all you need to do is compile the library and
  167. Xinclude it on your loader command line.  You do not need to recompile
  168. Xyour code, only a relink is necessary.  
  169. X
  170. XFeatures of this library:
  171. X
  172. X 1. The malloced area returned from each call to malloc is filled with
  173. X    non-null bytes.  This should catch any use of uninitialized malloc
  174. X    area.  The fill pattern for malloced area is 0x01.
  175. X
  176. X 2. When free is called numerous validity checks are made on the 
  177. X    pointer it is passed.  In addition, the data in the malloc block
  178. X    beyound the size requested on the initial malloc is checked to 
  179. X    verify that it is still filled with the original fill characters.
  180. X
  181. X    This is usefull for catching things like:
  182. X
  183. X        ptr = malloc(5);
  184. X        ptr[5] = '\0';
  185. X
  186. X        /*
  187. X         * You should not that this will be caught when it is
  188. X         * freed not when it is done
  189. X         */
  190. X
  191. X    And finally, the freed block is filled with a different fill pattern
  192. X    so that you can easily determine if you are still using free'd space.
  193. X    The fill pattern for free'd areas is 0x02.
  194. X
  195. X    This is usefull for catching things like:
  196. X
  197. X        ptr = malloc(20);
  198. X
  199. X        bptr = ptr+10;
  200. X
  201. X        /* do something usefule with bptr */
  202. X
  203. X        free(ptr);
  204. X
  205. X        /* 
  206. X         * now try to do something useful with bptr, it should
  207. X         * be trashed enough that it would cause real problems
  208. X         * and when you went to debug the problem it would be
  209. X         * filled with 0x02's and you would then know to look 
  210. X         * for something free'ing what bptr points to.
  211. X         */
  212. X        
  213. X
  214. X 3. Whenever a bstring(3)/string(3)/memory(3) function is called, it's 
  215. X    parameters are checked as follows:
  216. X
  217. X    If they point somewhere in the malloc arena
  218. X        If the operation goes beyond requested malloc space
  219. X            call malloc_warning()
  220. X
  221. X    This is usefull for catching things like:
  222. X
  223. X        ptr = malloc(5);
  224. X        strcpy(ptr,"abcde");
  225. X            
  226. X    
  227. X 4. Malloc_warning() and malloc_fatal() are used when an error condition
  228. X    is detected.  If the error is severe, malloc_fatal is called.  
  229. X    Malloc_warning is used otherwise.  The decision about what is fatal
  230. X    and what is a warning was made somewhat arbitrarily.
  231. X
  232. X    Warning messages include:
  233. X
  234. X    Calling free with a bad pointer
  235. X        Calling a bstring/string/memory (3) function which will go beyond
  236. X        the end of a malloc block (Note that the library function is
  237. X            not modified to refuse the operation.  If malloc warnings are
  238. X        in the default IGNORE case, the operation will continue and 
  239. X        at some point cause a real problem).
  240. X
  241. X    Fatal errors are:
  242. X
  243. X    Detectable corruption to the malloc chain.
  244. X    
  245. X
  246. X 5. The operations to perform when an error is detected are specified at
  247. X    run time by the use of environment variables.
  248. X
  249. X    MALLOC_WARN - specifies the warning error message handling
  250. X    MALLOC_FATAL - specifies the fatal error handling
  251. X
  252. X
  253. X    When one of these error conditions occur you will get an error
  254. X    message and the handler will execute based upon what setting
  255. X    is in the environment variables.  Currently understood settings
  256. X    are as follows:
  257. X
  258. X          0 - continue operations
  259. X          1 - drop core and exit
  260. X          2 - just exit
  261. X          3 - drop core, but continue executing.  Core files will
  262. X             be placed into core.[PID].[counter] i.e: core.00123.001
  263. X        128 - dump malloc chain and continue
  264. X        129 - dump malloc chain, dump core, and exit
  265. X        130 - dump malloc chain, exit
  266. X        131 - dump malloc chain, dump core, continue processing
  267. X        
  268. X
  269. X    There is an additional environment variable MALLOC_ERRFILE which
  270. X    is used to indicate the name of the file for error message output.
  271. X
  272. X    For example, to set up the session to generate a core file for
  273. X    every malloc warning, to drop core and exit on a malloc fatal, and 
  274. X    to log all messages to the file "malloc_log" do the following:
  275. X
  276. X        MALLOC_WARN=131
  277. X        MALLOC_FATAL=1
  278. X        MALLOC_ERRFILE=malloc_log
  279. X
  280. X        export MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE
  281. X
  282. X 6. The function malloc_dump() is available to dump the malloc chain whenever
  283. X    you might want.  It's only argument is a file descriptor to use to write
  284. X    the data.  Review the code if you need to know what data is printed.
  285. SHAR_EOF
  286. $TOUCH -am 0511001190 README &&
  287. chmod 0664 README ||
  288. echo "restore of README failed"
  289. set `wc -c README`;Wc_c=$1
  290. if test "$Wc_c" != "4758"; then
  291.     echo original size 4758, current size $Wc_c
  292. fi
  293. fi
  294. # ============= patchlevel ==============
  295. if test X"$1" != X"-c" -a -f 'patchlevel'; then
  296.     echo "File already exists: skipping 'patchlevel'"
  297. else
  298. echo "x - extracting patchlevel (Text)"
  299. sed 's/^X//' << 'SHAR_EOF' > patchlevel &&
  300. X1
  301. SHAR_EOF
  302. $TOUCH -am 0621103390 patchlevel &&
  303. chmod 0666 patchlevel ||
  304. echo "restore of patchlevel failed"
  305. set `wc -c patchlevel`;Wc_c=$1
  306. if test "$Wc_c" != "2"; then
  307.     echo original size 2, current size $Wc_c
  308. fi
  309. fi
  310. # ============= calloc.c ==============
  311. if test X"$1" != X"-c" -a -f 'calloc.c'; then
  312.     echo "File already exists: skipping 'calloc.c'"
  313. else
  314. echo "x - extracting calloc.c (Text)"
  315. sed 's/^X//' << 'SHAR_EOF' > calloc.c &&
  316. X/*
  317. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  318. X * You may copy, distribute, and use this software as long as this
  319. X * copyright statement is not removed.
  320. X */
  321. X#include <stdio.h>
  322. X
  323. X/*
  324. X * Function:    calloc()
  325. X *
  326. X * Purpose:    to allocate and nullify a data area
  327. X *
  328. X * Arguments:    nelem    - number of elements
  329. X *        elsize    - size of each element
  330. X *
  331. X * Returns:    NULL    - if malloc fails
  332. X *        or pointer to allocated space
  333. X *
  334. X * Narrative:    determine size of area to malloc
  335. X *        malloc area.
  336. X *        if malloc succeeds
  337. X *            fill area with nulls
  338. X *        return ptr to malloc'd region
  339. X */
  340. X#ifndef lint
  341. Xstatic char rcs_header[] = "$Id: calloc.c,v 1.6 90/05/11 00:13:07 cpcahil Exp $";
  342. X#endif
  343. X
  344. Xchar *
  345. Xcalloc(nelem,elsize)
  346. X    unsigned int       nelem;
  347. X    unsigned int       elsize;
  348. X{
  349. X    char        * malloc();
  350. X    char        * memset();
  351. X    char        * ptr;
  352. X    unsigned int      size;
  353. X
  354. X    size = elsize * nelem;
  355. X
  356. X    if( (ptr = malloc(size)) != NULL)
  357. X    {
  358. X        (void) memset(ptr,'\0',(int)size);
  359. X    }
  360. X
  361. X    return(ptr);
  362. X}
  363. X
  364. X
  365. X/*
  366. X * $Log:    calloc.c,v $
  367. X * Revision 1.6  90/05/11  00:13:07  cpcahil
  368. X * added copyright statment
  369. X * 
  370. X * Revision 1.5  90/02/24  20:41:57  cpcahil
  371. X * lint changes.
  372. X * 
  373. X * Revision 1.4  90/02/24  17:25:47  cpcahil
  374. X * changed $header to $id so full path isn't included.
  375. X * 
  376. X * Revision 1.3  90/02/24  13:32:24  cpcahil
  377. X * added function header.  moved log to end of file.
  378. X * 
  379. X * Revision 1.2  90/02/22  23:08:26  cpcahil
  380. X * fixed rcs_header line
  381. X * 
  382. X * Revision 1.1  90/02/22  23:07:38  cpcahil
  383. X * Initial revision
  384. X * 
  385. X */
  386. SHAR_EOF
  387. $TOUCH -am 0511001490 calloc.c &&
  388. chmod 0444 calloc.c ||
  389. echo "restore of calloc.c failed"
  390. set `wc -c calloc.c`;Wc_c=$1
  391. if test "$Wc_c" != "1481"; then
  392.     echo original size 1481, current size $Wc_c
  393. fi
  394. fi
  395. # ============= debug.h ==============
  396. if test X"$1" != X"-c" -a -f 'debug.h'; then
  397.     echo "File already exists: skipping 'debug.h'"
  398. else
  399. echo "x - extracting debug.h (Text)"
  400. sed 's/^X//' << 'SHAR_EOF' > debug.h &&
  401. X/*
  402. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  403. X * You may copy, distribute, and use this software as long as this
  404. X * copyright statement is not removed.
  405. X */
  406. X/************************************************************************/
  407. X/*                                    */
  408. X/* this include sets up some macro functions which can be used while    */
  409. X/* debugging the program, and then left in the code, but turned of by    */
  410. X/* just not defining "DEBUG".  This way your production version of     */
  411. X/* the program will not be filled with bunches of debugging junk    */
  412. X/*                                    */
  413. X/************************************************************************/
  414. X/*
  415. X * $Id: debug.h,v 1.2 90/05/11 00:13:08 cpcahil Exp $
  416. X */
  417. X
  418. X#ifdef DEBUG
  419. X
  420. X#if DEBUG == 1            /* if default level            */
  421. X#undef DEBUG
  422. X#define DEBUG    100        /*   use level 100            */
  423. X#endif
  424. X
  425. X#include <stdio.h>
  426. X
  427. X#define DEBUG0(val,str)\
  428. X                {\
  429. X                  if( DEBUG > val ) \
  430. X                    fprintf(stderr,"%s(%d): %s\n",\
  431. X                        __FILE__,__LINE__,str);\
  432. X                }
  433. X#define DEBUG1(val,str,a1)\
  434. X                    {\
  435. X                  char _debugbuf[100];\
  436. X                  if( DEBUG > val )\
  437. X                   {\
  438. X                    sprintf(_debugbuf,str,a1);\
  439. X                    fprintf(stderr,"%s(%d): %s\n",\
  440. X                        __FILE__,__LINE__,_debugbuf);\
  441. X                   }\
  442. X                       }
  443. X
  444. X#define DEBUG2(val,str,a1,a2)\
  445. X                    {\
  446. X                 char _debugbuf[100];\
  447. X                  if( DEBUG > val )\
  448. X                   {\
  449. X                    sprintf(_debugbuf,str,a1,a2);\
  450. X                    fprintf(stderr,"%s(%d): %s\n",\
  451. X                        __FILE__,__LINE__,_debugbuf);\
  452. X                   }\
  453. X                       }
  454. X
  455. X#define DEBUG3(val,str,a1,a2,a3)\
  456. X                    {\
  457. X                  char _debugbuf[100];\
  458. X                  if( DEBUG > val )\
  459. X                   {\
  460. X                    sprintf(_debugbuf,str,a1,a2,a3);\
  461. X                    fprintf(stderr,"%s(%d): %s\n",\
  462. X                        __FILE__,__LINE__,_debugbuf);\
  463. X                   }\
  464. X                       }
  465. X
  466. X#define DEBUG4(val,str,a1,a2,a3,a4)\
  467. X                     {\
  468. X                  char _debugbuf[100];\
  469. X                  if( DEBUG > val )\
  470. X                   {\
  471. X                    sprintf(_debugbuf,str,a1,a2,a3,a4);\
  472. X                    fprintf(stderr,"%s(%d): %s\n",\
  473. X                        __FILE__,__LINE__,_debugbuf);\
  474. X                   }\
  475. X                       }
  476. X
  477. X#define DEBUG5(val,str,a1,a2,a3,a4,a5)\
  478. X                     {\
  479. X                  char _debugbuf[100];\
  480. X                  if( DEBUG > val )\
  481. X                   {\
  482. X                    sprintf(_debugbuf,str,a1,a2,a3,a4,a5);\
  483. X                    fprintf(stderr,"%s(%d): %s\n",\
  484. X                        __FILE__,__LINE__,_debugbuf);\
  485. X                   }\
  486. X                       }
  487. X
  488. X#else
  489. X
  490. X#define DEBUG0(val,s)
  491. X#define DEBUG1(val,s,a1)
  492. X#define DEBUG2(val,s,a1,a2)
  493. X#define DEBUG3(val,s,a1,a2,a3)
  494. X#define DEBUG4(val,s,a1,a2,a3,a4)
  495. X#define DEBUG5(val,s,a1,a2,a3,a4,a5)
  496. X
  497. X#endif /* DEBUG */
  498. X
  499. X
  500. X/*
  501. X * $Log:    debug.h,v $
  502. X * Revision 1.2  90/05/11  00:13:08  cpcahil
  503. X * added copyright statment
  504. X * 
  505. X * Revision 1.1  90/02/23  07:09:01  cpcahil
  506. X * Initial revision
  507. X * 
  508. X */
  509. SHAR_EOF
  510. $TOUCH -am 0511001490 debug.h &&
  511. chmod 0444 debug.h ||
  512. echo "restore of debug.h failed"
  513. set `wc -c debug.h`;Wc_c=$1
  514. if test "$Wc_c" != "2628"; then
  515.     echo original size 2628, current size $Wc_c
  516. fi
  517. fi
  518. # ============= dump.c ==============
  519. if test X"$1" != X"-c" -a -f 'dump.c'; then
  520.     echo "File already exists: skipping 'dump.c'"
  521. else
  522. echo "x - extracting dump.c (Text)"
  523. sed 's/^X//' << 'SHAR_EOF' > dump.c &&
  524. X/*
  525. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  526. X * You may copy, distribute, and use this software as long as this
  527. X * copyright statement is not removed.
  528. X */
  529. X#include <stdio.h>
  530. X#include "malloc.h"
  531. X#include "tostring.h"
  532. X
  533. X/*
  534. X * Function:    malloc_dump()
  535. X *
  536. X * Purpose:    to dump a printed copy of the malloc chain and
  537. X *        associated data elements
  538. X *
  539. X * Arguments:    fd    - file descriptor to write data to
  540. X *
  541. X * Returns:    nothing of any use
  542. X *
  543. X * Narrative:    Just print out all the junk
  544. X *
  545. X * Notes:    This function is implemented using low level calls because
  546. X *         of the likelyhood that the malloc tree is damaged when it
  547. X *        is called.  (Lots of things in the c library use malloc and
  548. X *        we don't want to get into a catch-22).
  549. X *
  550. X */
  551. X
  552. X#ifndef lint
  553. Xstatic
  554. Xchar rcs_hdr[] = "$Id: dump.c,v 1.4 90/05/11 00:13:08 cpcahil Exp $";
  555. X#endif
  556. X
  557. X
  558. X#define ERRSTR    "I/O Error on malloc dump file descriptor\n"
  559. X
  560. X#define WRITEOUT(fd,str,len)    if( write(fd,str,(unsigned)len) != len ) \
  561. X                { \
  562. X                    (void) write(2,ERRSTR,\
  563. X                             (unsigned)strlen(ERRSTR));\
  564. X                    exit(120); \
  565. X                }
  566. X
  567. Xmalloc_dump(fd)
  568. X    int        fd;
  569. X{
  570. X    char              buffer[512];
  571. X    void              exit();
  572. X    int              i;
  573. X    extern char        * malloc_data_end;
  574. X    extern char        * malloc_data_start;
  575. X    extern struct mlist     * malloc_end;
  576. X    extern struct mlist      malloc_start;
  577. X    struct mlist         * ptr;
  578. X
  579. X    WRITEOUT(fd,"MALLOC CHAIN:\n",14);
  580. X    WRITEOUT(fd,"-------------------- START ----------------\n",44);
  581. X
  582. X    for(i=0; i < 80; i++)
  583. X    {
  584. X        buffer[i] = ' ';
  585. X    }
  586. X
  587. X    for(ptr = &malloc_start; ptr; ptr = ptr->next)
  588. X    {
  589. X        (void) tostring(buffer,       (int)ptr,         8,    B_HEX,    '0');
  590. X        (void) tostring(buffer+9,  (int)ptr->next,   8,    B_HEX,    '0');
  591. X        (void) tostring(buffer+18, (int)ptr->prev,   8,    B_HEX,    '0');
  592. X        (void) tostring(buffer+27, (int)ptr->flag,  10,    B_HEX,    '0');
  593. X        (void) tostring(buffer+38, (int)ptr->s.size, 8,    B_DEC,    ' ');
  594. X        (void) tostring(buffer+47, (int)ptr->s.size, 8,    B_HEX,    '0');
  595. X        (void) tostring(buffer+57, (int)ptr->data,   8,    B_HEX,    '0');
  596. X        buffer[46] = '(';
  597. X        buffer[55] = ')';
  598. X        buffer[65] = '\n';
  599. X        WRITEOUT(fd,buffer,66);
  600. X    }
  601. X    WRITEOUT(fd,"-------------------- DONE -----------------\n",44);
  602. X
  603. X    WRITEOUT(fd,"Malloc start:      ",19);
  604. X    (void) tostring(buffer, (int) &malloc_start, 8, B_HEX, '0');
  605. X    buffer[8] = '\n';
  606. X    WRITEOUT(fd,buffer,9);
  607. X
  608. X    WRITEOUT(fd,"Malloc end:        ", 19);
  609. X    (void) tostring(buffer, (int) malloc_end, 8, B_HEX, '0');
  610. X    buffer[8] = '\n';
  611. X    WRITEOUT(fd,buffer,9);
  612. X
  613. X    WRITEOUT(fd,"Malloc data start: ", 19);
  614. X    (void) tostring(buffer, (int) malloc_data_start, 8, B_HEX, '0');
  615. X    buffer[8] = '\n';
  616. X    WRITEOUT(fd,buffer,9);
  617. X
  618. X    WRITEOUT(fd,"Malloc data end:   ", 19);
  619. X    (void) tostring(buffer, (int) malloc_data_end, 8, B_HEX, '0');
  620. X    buffer[8] = '\n';
  621. X    WRITEOUT(fd,buffer,9);
  622. X    
  623. X} /* malloc_dump(... */
  624. X
  625. X
  626. X/*
  627. X * $Log:    dump.c,v $
  628. X * Revision 1.4  90/05/11  00:13:08  cpcahil
  629. X * added copyright statment
  630. X * 
  631. X * Revision 1.3  90/02/24  21:50:07  cpcahil
  632. X * lots of lint fixes
  633. X * 
  634. X * Revision 1.2  90/02/24  17:27:48  cpcahil
  635. X * changed $header to $Id to remove full path from rcs id string
  636. X * 
  637. X * Revision 1.1  90/02/22  23:17:43  cpcahil
  638. X * Initial revision
  639. X * 
  640. X */
  641. SHAR_EOF
  642. $TOUCH -am 0511001490 dump.c &&
  643. chmod 0444 dump.c ||
  644. echo "restore of dump.c failed"
  645. set `wc -c dump.c`;Wc_c=$1
  646. if test "$Wc_c" != "3097"; then
  647.     echo original size 3097, current size $Wc_c
  648. fi
  649. fi
  650. # ============= free.c ==============
  651. if test X"$1" != X"-c" -a -f 'free.c'; then
  652.     echo "File already exists: skipping 'free.c'"
  653. else
  654. echo "x - extracting free.c (Text)"
  655. sed 's/^X//' << 'SHAR_EOF' > free.c &&
  656. X/*
  657. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  658. X * You may copy, distribute, and use this software as long as this
  659. X * copyright statement is not removed.
  660. X */
  661. X#include <stdio.h>
  662. X#include "malloc.h"
  663. X#include "debug.h"
  664. X
  665. X/*
  666. X * Function:    free()
  667. X *
  668. X * Purpose:    to deallocate malloced data
  669. X *
  670. X * Arguments:    ptr    - pointer to data area to deallocate
  671. X *
  672. X * Returns:    nothing of any value
  673. X *
  674. X * Narrative:
  675. X *        verify pointer is within malloc region
  676. X *        get mlist pointer from passed address
  677. X *        verify magic number
  678. X *        verify inuse flag
  679. X *        verify pointer connections with surrounding segments
  680. X *        turn off inuse flag
  681. X *        verify no data overrun into non-malloced area at end of segment
  682. X *        IF possible join segment with next segment
  683. X *        IF possible join segment with previous segment
  684. X *        Clear all data in segment (to make sure it isn't reused)
  685. X *
  686. X */
  687. X#ifndef lint
  688. Xstatic
  689. Xchar rcs_hdr[] = "$Id: free.c,v 1.8 90/05/11 00:13:08 cpcahil Exp $";
  690. X#endif
  691. X
  692. Xvoid
  693. Xfree(cptr)
  694. X    char    * cptr;
  695. X{
  696. X    char            * func = "free";
  697. X    int              i;
  698. X    extern int          malloc_checking;
  699. X    extern struct mlist    * malloc_end;
  700. X    extern int          malloc_errno;
  701. X    extern char        * malloc_data_end;
  702. X    extern char        * malloc_data_start;
  703. X    struct mlist        * oldptr;
  704. X    struct mlist        * ptr;
  705. X
  706. X    /*
  707. X     * IF malloc chain checking is on, go do it.
  708. X     */
  709. X    if( malloc_checking )
  710. X    {
  711. X        (void) malloc_chain_check(1);
  712. X    }
  713. X
  714. X    /*
  715. X     * verify that cptr is within the malloc region...
  716. X     */
  717. X    if( cptr < malloc_data_start || cptr > malloc_data_end )
  718. X    {
  719. X        malloc_errno = M_CODE_BAD_PTR;
  720. X        malloc_warning(func);
  721. X        return;
  722. X    }
  723. X
  724. X    /* 
  725. X     * convert pointer to mlist struct pointer.  To do this we must 
  726. X     * move the pointer backwards the correct number of bytes...
  727. X     */
  728. X    
  729. X    ptr = (struct mlist *) (cptr - M_SIZE);
  730. X    
  731. X    if( (ptr->flag&M_MAGIC) != M_MAGIC )
  732. X    {
  733. X        malloc_errno = M_CODE_BAD_MAGIC;
  734. X        malloc_warning(func);
  735. X        return;
  736. X    }
  737. X
  738. X    if( ! (ptr->flag & M_INUSE) )
  739. X    {
  740. X        malloc_errno = M_CODE_NOT_INUSE;
  741. X        malloc_warning(func);
  742. X        return;
  743. X    }
  744. X
  745. X     if( (ptr->prev && (ptr->prev->next != ptr) ) ||
  746. X        (ptr->next && (ptr->next->prev != ptr) ) ||
  747. X        ((ptr->next == NULL) && (ptr->prev == NULL)) )
  748. X    {
  749. X        malloc_errno = M_CODE_BAD_CONNECT;
  750. X        malloc_warning(func);
  751. X        return;
  752. X    }
  753. X
  754. X    ptr->flag &= ~M_INUSE;
  755. X
  756. X    /*
  757. X     * verify that the user did not overrun the requested number of bytes.
  758. X     */
  759. X    for(i=ptr->r_size; i < ptr->s.size; i++)
  760. X    {
  761. X        if( ptr->data[i] != M_FILL )
  762. X        {
  763. X            malloc_errno = M_CODE_OVERRUN;
  764. X            malloc_warning(func);
  765. X            break;
  766. X        }
  767. X    }
  768. X
  769. X    DEBUG3(10,"pointers: prev: 0x%.7x,  ptr: 0x%.7x, next: 0x%.7x",
  770. X            ptr->prev, ptr, ptr->next);
  771. X    
  772. X    DEBUG3(10,"size:     prev: %9d,  ptr: %9d, next: %9d",
  773. X            ptr->prev->s.size, ptr->s.size, ptr->next->s.size);
  774. X    
  775. X    DEBUG3(10,"flags:    prev: 0x%.7x,  ptr: 0x%.7x, next: 0x%.7x",
  776. X            ptr->prev->flag, ptr->flag, ptr->next->flag);
  777. X    
  778. X    /*
  779. X     * check to see if this block can be combined with the next and/or
  780. X     * previous block.  Since it may be joined with the previous block
  781. X     * we will save a pointer to the previous block and test to verify
  782. X     * if it is joined (it's next ptr will no longer point to ptr).
  783. X      */
  784. X    malloc_join(ptr,ptr->next,0,0);
  785. X    
  786. X    oldptr = ptr->prev;
  787. X
  788. X    malloc_join(ptr->prev, ptr,0,0);
  789. X
  790. X    if( oldptr->next != ptr )
  791. X    {
  792. X        DEBUG0(10,"Oldptr was changed");
  793. X        ptr = oldptr;
  794. X    }
  795. X    
  796. X    /*
  797. X     * fill this block with '\02's to ensure that nobody is using a 
  798. X     * pointer to already freed data...
  799. X     */
  800. X    malloc_memset(ptr->data,M_FREE_FILL,ptr->s.size);
  801. X
  802. X}
  803. X
  804. X/*
  805. X * $Log:    free.c,v $
  806. X * Revision 1.8  90/05/11  00:13:08  cpcahil
  807. X * added copyright statment
  808. X * 
  809. X * Revision 1.7  90/02/25  11:00:18  cpcahil
  810. X * added support for malloc chain checking.
  811. X * 
  812. X * Revision 1.6  90/02/24  21:50:18  cpcahil
  813. X * lots of lint fixes
  814. X * 
  815. X * Revision 1.5  90/02/24  17:29:13  cpcahil
  816. X * changed $Header to $Id so full path wouldnt be included as part of rcs 
  817. X * id string
  818. X * 
  819. X * Revision 1.4  90/02/24  15:15:32  cpcahil
  820. X * 1. changed ALREADY_FREE errno to NOT_INUSE so that the same errno could
  821. X *    be used by both free and realloc (since it was the same error).
  822. X * 2. fixed coding bug
  823. X * 
  824. X * Revision 1.3  90/02/24  14:23:45  cpcahil
  825. X * fixed malloc_warning calls
  826. X * 
  827. X * Revision 1.2  90/02/24  13:59:10  cpcahil
  828. X * added function header.
  829. X * Modified calls to malloc_warning/malloc_fatal to use new code error messages
  830. X * Added support for malloc_errno setting of error codes.
  831. X * 
  832. X * Revision 1.1  90/02/22  23:17:43  cpcahil
  833. X * Initial revision
  834. X * 
  835. X */
  836. SHAR_EOF
  837. $TOUCH -am 0511001490 free.c &&
  838. chmod 0444 free.c ||
  839. echo "restore of free.c failed"
  840. set `wc -c free.c`;Wc_c=$1
  841. if test "$Wc_c" != "4379"; then
  842.     echo original size 4379, current size $Wc_c
  843. fi
  844. fi
  845. # ============= m_init.c ==============
  846. if test X"$1" != X"-c" -a -f 'm_init.c'; then
  847.     echo "File already exists: skipping 'm_init.c'"
  848. else
  849. echo "x - extracting m_init.c (Text)"
  850. sed 's/^X//' << 'SHAR_EOF' > m_init.c &&
  851. X/*
  852. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  853. X * You may copy, distribute, and use this software as long as this
  854. X * copyright statement is not removed.
  855. X */
  856. X#include <stdio.h>
  857. X#include "malloc.h"
  858. X
  859. X/*
  860. X * Function:    malloc_init()
  861. X *
  862. X * Purpose:    to initialize the pointers and variables use by the
  863. X *        malloc() debugging library
  864. X *
  865. X * Arguments:    none
  866. X *
  867. X * Returns:    nothing of any value
  868. X *
  869. X * Narrative:    Just initialize all the needed variables.  Use mallopt
  870. X *        to set options taken from the environment.
  871. X *
  872. X */
  873. X#ifndef lint
  874. Xstatic
  875. Xchar rcs_hdr[] = "$Id: m_init.c,v 1.4 90/05/11 15:53:35 cpcahil Exp $";
  876. X#endif
  877. X
  878. Xvoid
  879. Xmalloc_init()
  880. X{
  881. X    char            * cptr;
  882. X    char            * getenv();
  883. X    extern char        * malloc_data_end;
  884. X    extern char        * malloc_data_start;
  885. X    extern struct mlist    * malloc_end;
  886. X    extern struct mlist      malloc_start;
  887. X    char            * sbrk();
  888. X
  889. X    /*
  890. X      * If already initialized...
  891. X     */
  892. X    if( malloc_data_start != (char *) 0)
  893. X    {
  894. X        return;
  895. X    }
  896. X
  897. X
  898. X    malloc_data_start = sbrk(0);
  899. X    malloc_data_end = malloc_data_start;
  900. X    malloc_start.s.size = 0;
  901. X    malloc_end = &malloc_start;
  902. X    
  903. X    if( (cptr=getenv("MALLOC_WARN")) != NULL )
  904. X    {
  905. X        mallopt(MALLOC_WARN,atoi(cptr));
  906. X    }
  907. X
  908. X    if( (cptr=getenv("MALLOC_FATAL")) != NULL)
  909. X    {
  910. X        mallopt(MALLOC_FATAL,atoi(cptr));
  911. X    }
  912. X
  913. X    if( (cptr=getenv("MALLOC_CKCHAIN")) != NULL)
  914. X    {
  915. X        mallopt(MALLOC_CKCHAIN,atoi(cptr));
  916. X    }
  917. X
  918. X    if( (cptr=getenv("MALLOC_ERRFILE")) != NULL)
  919. X    {
  920. X        mallopt(MALLOC_ERRFILE,cptr);
  921. X    }
  922. X
  923. X}
  924. X
  925. X/*
  926. X * $Log:    m_init.c,v $
  927. X * Revision 1.4  90/05/11  15:53:35  cpcahil
  928. X * fixed bug in initialization code.
  929. X * 
  930. X * Revision 1.3  90/05/11  00:13:08  cpcahil
  931. X * added copyright statment
  932. X * 
  933. X * Revision 1.2  90/02/24  21:50:20  cpcahil
  934. X * lots of lint fixes
  935. X * 
  936. X * Revision 1.1  90/02/24  17:10:53  cpcahil
  937. X * Initial revision
  938. X * 
  939. X */
  940. SHAR_EOF
  941. $TOUCH -am 0511155390 m_init.c &&
  942. chmod 0444 m_init.c ||
  943. echo "restore of m_init.c failed"
  944. set `wc -c m_init.c`;Wc_c=$1
  945. if test "$Wc_c" != "1751"; then
  946.     echo original size 1751, current size $Wc_c
  947. fi
  948. fi
  949. # ============= m_perror.c ==============
  950. if test X"$1" != X"-c" -a -f 'm_perror.c'; then
  951.     echo "File already exists: skipping 'm_perror.c'"
  952. else
  953. echo "x - extracting m_perror.c (Text)"
  954. sed 's/^X//' << 'SHAR_EOF' > m_perror.c &&
  955. X/*
  956. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  957. X * You may copy, distribute, and use this software as long as this
  958. X * copyright statement is not removed.
  959. X */
  960. X
  961. X#ifndef lint
  962. Xstatic
  963. Xchar rcsid[] = "$Id: m_perror.c,v 1.4 90/05/11 00:13:08 cpcahil Exp $";
  964. X#endif
  965. X
  966. X/*
  967. X * malloc errno error strings...
  968. X */
  969. X
  970. Xchar *malloc_err_strings[] = 
  971. X{
  972. X    "No errors",
  973. X    "Malloc chain is corrupted, pointers out of order",
  974. X    "Malloc chain is corrupted, end before end pointer",
  975. X    "Pointer is not within malloc area",
  976. X    "Malloc region does not have valid magic number in header",
  977. X    "Pointers between this segment and ajoining segments are invalid",
  978. X    "Data has overrun beyond requested number of bytes",
  979. X    "Data in free'd area has been modified",
  980. X    "Data are is not in use (can't be freed or realloced)",
  981. X    "Unable to get additional memory from the system",
  982. X    (char *) 0
  983. X};
  984. X
  985. X/*
  986. X * Function:    malloc_perror()
  987. X *
  988. X * Purpose:    to print malloc_errno error message
  989. X *
  990. X * Arguments:    str    - string to print with error message
  991. X *
  992. X * Returns:    nothing of any value
  993. X *
  994. X * Narrative:
  995. X */
  996. Xvoid
  997. Xmalloc_perror(str)
  998. X    char    * str;
  999. X{
  1000. X    extern int      malloc_errno;
  1001. X    register char     * s;
  1002. X    register char     * t;
  1003. X
  1004. X    if( str && *str)
  1005. X    {
  1006. X        for(s=str; *s; s++)
  1007. X        {
  1008. X            /* do nothing */;
  1009. X        }
  1010. X
  1011. X        (void) write(2,str,(unsigned)(s-str));
  1012. X        (void) write(2,": ",(unsigned)2);
  1013. X    }
  1014. X
  1015. X    t = malloc_err_strings[malloc_errno];
  1016. X
  1017. X    for(s=t; *s; s++)
  1018. X    {
  1019. X        /* do nothing */;
  1020. X    }
  1021. X
  1022. X    (void) write(2,t,(unsigned)(s-t));
  1023. X
  1024. X    (void) write(2,"\n",(unsigned)1);
  1025. X}
  1026. X
  1027. X/*
  1028. X * $Log:    m_perror.c,v $
  1029. X * Revision 1.4  90/05/11  00:13:08  cpcahil
  1030. X * added copyright statment
  1031. X * 
  1032. X * Revision 1.3  90/02/24  21:50:21  cpcahil
  1033. X * lots of lint fixes
  1034. X * 
  1035. X * Revision 1.2  90/02/24  17:39:55  cpcahil
  1036. X * 1. added function header
  1037. X * 2. added rcs id and log strings.
  1038. X * 
  1039. X */
  1040. SHAR_EOF
  1041. $TOUCH -am 0511001490 m_perror.c &&
  1042. chmod 0444 m_perror.c ||
  1043. echo "restore of m_perror.c failed"
  1044. set `wc -c m_perror.c`;Wc_c=$1
  1045. if test "$Wc_c" != "1776"; then
  1046.     echo original size 1776, current size $Wc_c
  1047. fi
  1048. fi
  1049. # ============= malloc.3 ==============
  1050. if test X"$1" != X"-c" -a -f 'malloc.3'; then
  1051.     echo "File already exists: skipping 'malloc.3'"
  1052. else
  1053. echo "x - extracting malloc.3 (Text)"
  1054. sed 's/^X//' << 'SHAR_EOF' > malloc.3 &&
  1055. X.TH MALLOC 3 "" "" "1.0"
  1056. X.ds ]T 
  1057. X.\"/*
  1058. X.\" * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  1059. X.\" * You may copy, distribute, and use this software as long as this
  1060. X.\" * copyright statement is not removed.
  1061. X.\" */
  1062. X.\" $Id: malloc.3,v 1.1 90/05/11 15:53:20 cpcahil Exp $
  1063. X.SH NAME
  1064. Xmalloc \t- debugging malloc library
  1065. X.SH SYNOPSIS
  1066. X.ft B
  1067. X.nf
  1068. X#include <malloc.h>
  1069. X
  1070. Xchar    * calloc(nelem,elsize);
  1071. Xvoid      free(ptr);
  1072. Xchar    * malloc(size);
  1073. Xint      malloc_chain_check(flag);
  1074. Xvoid      malloc_dump(fd);
  1075. Xint      mallopt(cmd,value)
  1076. Xchar    * realloc(ptr,size);
  1077. X
  1078. Xint          cmd,fd,flag;
  1079. Xunsigned      elsize,nelem,size;
  1080. Xchar        * ptr;
  1081. Xunion val      value;
  1082. X
  1083. X.fi
  1084. X.ft R
  1085. X.SH DESCRIPTION
  1086. XThis malloc library is a replacement for the standard library to be used
  1087. Xduring software development/debugging.  See the standard malloc(3) pages
  1088. Xfor more information on the use of the following functions:
  1089. X.nf
  1090. X.in +.5i
  1091. Xcalloc(), free(), malloc(), realloc()
  1092. X.in -.5i
  1093. X.fi
  1094. X.sp
  1095. XThis library differs from the standard malloc library in the
  1096. Xfollowing ways:
  1097. X.P
  1098. X1. Each malloc segment contains a magic number so that free can 
  1099. Xverify that the pointer passed points to a valid malloc segment.
  1100. X.P
  1101. X2. Each malloc segment is filled with a non-zero pattern so that code that
  1102. Xdepends upon malloc segments being null will fail.
  1103. X.P
  1104. X3. The size of each segment will be at least 1 byte larger than requested
  1105. Xand the extra bytes will be filled with a non-zero pattern.  When free is
  1106. Xcalled, it will verify that you did not go beyond the number of bytes 
  1107. Xyou asked for.
  1108. X.P
  1109. X4. When a segment is freed, it will be filled with a different non-zero pattern
  1110. Xto ensure that the program doesn't depend upon the use of already freed data.
  1111. X.P
  1112. X5. Whenever any of the string or memory functions (str*, b*, mem*) are 
  1113. Xcalled with a pointer that is within the malloc arena,  the operation is
  1114. Xchecked to verify that it does not overrun the malloced segment.  A failure
  1115. Xof this check is considered a "warning level error" (described later) and
  1116. Xis handled accordingly.
  1117. X.P
  1118. X7. Run time checking can include verification of the malloc chain at each
  1119. Xand every call to one of the malloc functions or manually by calling the
  1120. Xmalloc_chain_check function.
  1121. X.P
  1122. X6. When a problem is found, the action taken is specified at runtime by
  1123. Xenvironment variables or at compile time by the use of the mallopt()
  1124. Xfunction.
  1125. X.P
  1126. XThere are two arbitrary levels of errors, warning and fatal, that this
  1127. Xlibrary will detect.  They are broken down as follows:
  1128. X.P
  1129. X.nf
  1130. X.in +.25i
  1131. XWarning messages include:
  1132. X.sp
  1133. X.in +.5i
  1134. X.ti -.25i
  1135. XCalling free with a bad pointer
  1136. X.br
  1137. X.ti -.25i
  1138. XCalling a bstring/string/memory (3) function which will go beyond
  1139. Xthe end of a malloc block. Note that the library function is
  1140. Xnot modified to refuse the operation.
  1141. X.sp
  1142. X.in -.5i
  1143. XFatal errors are:
  1144. X.in +.5i
  1145. X.ti -.25i
  1146. XDetectable corruption to the malloc chain.
  1147. X.in -.5i
  1148. X.in -.25i
  1149. X.P
  1150. XThe error handling for each level (warning or fatal) are specified using
  1151. Xenvironment variables or mallopt().  The coding for the error handling is
  1152. Xas follows:
  1153. X.sp
  1154. X.nf
  1155. X.in +.5i
  1156. X.ti -.25i
  1157. X  0 - continue operations
  1158. X.ti -.25i
  1159. X  1 - drop core and exit
  1160. X.ti -.25i
  1161. X  2 - just exit
  1162. X.ti -.25i
  1163. X  3 - drop core, but continue executing.  Core files will
  1164. Xbe placed into core.[PID].[counter] i.e: core.00123.001
  1165. X.ti -.25i
  1166. X128 - dump malloc chain and continue
  1167. X.ti -.25i
  1168. X129 - dump malloc chain, dump core, and exit
  1169. X.ti -.25i
  1170. X130 - dump malloc chain, exit
  1171. X.ti -.25i
  1172. X131 - dump malloc chain, dump core, continue processing
  1173. X.in -.5i
  1174. X.P
  1175. XIn addition error messages can be placed into an error file.
  1176. X.P
  1177. X\fBmalloc_opt\fP() is used to set the malloc debugging options. The
  1178. Xfollowing options can be set:
  1179. X.br
  1180. X.sp
  1181. X.in +.5i
  1182. XMALLOC_WARN - set the error handling for warning level errors.  \fBval\fP is
  1183. Xan integer that can contain any one of the following values:
  1184. X.sp
  1185. X.in +.5i
  1186. XM_HANDLE_IGNORE - ignore error
  1187. X.br
  1188. XM_HANDLE_ABORT - drop core and exit
  1189. X.br
  1190. XM_HANDLE_EXIT - just exit (no core drop)
  1191. X.br
  1192. XM_HANDLE_CORE - drop core, but keep on going
  1193. X.br
  1194. X.in -.5i
  1195. X.sp
  1196. XIn addition, M_HANDLE_DUMP may be or'd in to cause a dump of the current
  1197. Xmalloc chain.
  1198. X.br
  1199. X.sp
  1200. XMALLOC_FATAL - set the error handling for fatal level errors.  \fBval\fP is
  1201. Xequivalent to \fBval\fP for MALLOC_WARN.
  1202. X.br
  1203. X.sp
  1204. XMALLOC_ERRFILE - set the destination for malloc error messages.  \fBval\fP is
  1205. Xa pointer to a character string containing the name of the file to be used
  1206. Xfor error messages.
  1207. X.br
  1208. X.sp
  1209. XMALLOC_CKCHAIN - set the malloc chain checking flag.  If \fBval\fP is
  1210. Xnon-zero, chain checking at every call to malloc is turned on.
  1211. X.br
  1212. X.sp
  1213. XFor example, to set up the session to generate a core file for
  1214. Xevery malloc warning, to drop core and exit on a malloc fatal, and 
  1215. Xto log all messages to the file "malloc_log" do the following:
  1216. X.sp
  1217. X.nf
  1218. X.in +.5i
  1219. X#include <malloc.h>
  1220. Xmalloc_opt(MALLOC_WARN,131);
  1221. Xmalloc_opt(MALLOC_FATAL,1);
  1222. Xmalloc_opt(MALLOC_ERRFILE,"malloc_log");
  1223. X.in -.5i
  1224. X.fi
  1225. X.in -.5i
  1226. X.sp
  1227. X\fBmalloc_opt\fP() can be used to set/alter the debugging options at any
  1228. Xtime.
  1229. X.P
  1230. X\fBmalloc_dump\fP() will dump a table of the malloc arena showing all
  1231. Xallocated/freed segments and the first few bytes of data in each segment.
  1232. X\fBfd\fP is the file descriptor to write the data to.
  1233. X.P
  1234. X\fBmalloc_chain_check\fP() will check the status of the malloc arena.
  1235. XIf \fBflag\fP is non-zero, an error found in the chain will cause a 
  1236. Xfatal error.  \fBmalloc_chain_check\fP() returns zero when there are no
  1237. Xproblems found in the malloc chain, non-zero otherwise.
  1238. X.SH "ENVIRONMENT VARIABLES"
  1239. XEnvironment variables can be used to control error handling, error logging
  1240. Xand malloc chain checking at run time.  The following environment variables
  1241. Xare used:
  1242. X.P
  1243. XMALLOC_WARN - specifies the error handling for warning errors
  1244. X.br
  1245. XMALLOC_FATAL - specifies the error handling for fatal errors
  1246. X.br
  1247. XMALLOC_ERRFILE - specifies the error log file for error messages.  
  1248. X.br
  1249. XMALLOC_CKCHAIN - if 1, turns on malloc chain checking at every call to any
  1250. Xof the malloc functions.
  1251. X.P
  1252. XFor example, to set up the session to generate a core file for
  1253. Xevery malloc warning, to drop core and exit on a malloc fatal, and 
  1254. Xto log all messages to the file "malloc_log" do the following:
  1255. X.sp
  1256. X.nf
  1257. X.in +.5i
  1258. XMALLOC_WARN=131
  1259. XMALLOC_FATAL=1
  1260. XMALLOC_ERRFILE=malloc_log
  1261. X
  1262. Xexport MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE
  1263. X.in -.5i
  1264. X.fi
  1265. X.SH WARNINGS
  1266. XThis malloc library and it's associated string and memory functions are
  1267. Xmuch less efficient than the standard functions due in part to the extra
  1268. Xerror checking.  You do not want to use this library when generating a
  1269. Xproduction (i.e. releasable) version of your software.  It should only
  1270. Xbe used during development and testing.
  1271. X.SH SEE ALSO
  1272. Xstat(2)
  1273. X.SH AUTHOR
  1274. XConor P. Cahill
  1275. XVirtual Technologies Incorporated
  1276. X.sp
  1277. Xuunet!virtech!cpcahil
  1278. SHAR_EOF
  1279. $TOUCH -am 0511155390 malloc.3 &&
  1280. chmod 0444 malloc.3 ||
  1281. echo "restore of malloc.3 failed"
  1282. set `wc -c malloc.3`;Wc_c=$1
  1283. if test "$Wc_c" != "6694"; then
  1284.     echo original size 6694, current size $Wc_c
  1285. fi
  1286. fi
  1287. # ============= malloc.c ==============
  1288. if test X"$1" != X"-c" -a -f 'malloc.c'; then
  1289.     echo "File already exists: skipping 'malloc.c'"
  1290. else
  1291. echo "x - extracting malloc.c (Text)"
  1292. sed 's/^X//' << 'SHAR_EOF' > malloc.c &&
  1293. X/*
  1294. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  1295. X * You may copy, distribute, and use this software as long as this
  1296. X * copyright statement is not removed.
  1297. X */
  1298. X#include <stdio.h>
  1299. X#include <fcntl.h>
  1300. X#include "malloc.h"
  1301. X#include "tostring.h"
  1302. X
  1303. X/*
  1304. X * Function:    malloc()
  1305. X *
  1306. X * Purpose:    memory allocator
  1307. X *
  1308. X * Arguments:    size    - size of data area needed
  1309. X *
  1310. X * Returns:    pointer to allocated area, or NULL if unable
  1311. X *        to allocate addtional data.
  1312. X *
  1313. X * Narrative:
  1314. X *
  1315. X */
  1316. X#ifndef lint
  1317. Xstatic
  1318. Xchar rcs_hdr[] = "$Id: malloc.c,v 1.6 90/05/11 00:13:09 cpcahil Exp $";
  1319. X#endif
  1320. X
  1321. Xint          malloc_checking;
  1322. Xchar        * malloc_data_start;
  1323. Xchar        * malloc_data_end;
  1324. Xstruct mlist     * malloc_end;
  1325. Xint          malloc_errfd = 2;
  1326. Xint          malloc_errno;
  1327. Xint          malloc_fatal_level = M_HANDLE_CORE;
  1328. Xstruct mlist      malloc_start;
  1329. Xint          malloc_warn_level;
  1330. X
  1331. Xchar *
  1332. Xmalloc(size)
  1333. X    unsigned int      size;
  1334. X{
  1335. X    char        * func = "malloc";
  1336. X    char        * getenv();
  1337. X    void          malloc_fatal();
  1338. X    void          malloc_init();
  1339. X    void          malloc_memset();
  1340. X    void          malloc_split();
  1341. X    void          malloc_warning();
  1342. X    unsigned int      need;
  1343. X    struct mlist    * oldptr;
  1344. X    struct mlist    * ptr;
  1345. X    char        * sbrk();
  1346. X
  1347. X    /*
  1348. X     * If this is the first call to malloc...
  1349. X     */
  1350. X    if( malloc_data_start == (char *) 0 )
  1351. X    {
  1352. X        malloc_init();
  1353. X    }
  1354. X
  1355. X    /*
  1356. X     * If malloc chain checking is on, go do it.
  1357. X     */
  1358. X    if( malloc_checking )
  1359. X    {
  1360. X        (void) malloc_chain_check(1);
  1361. X    }
  1362. X
  1363. X    /*
  1364. X     * always make sure there is at least on extra byte in the malloc
  1365. X     * area so that we can verify that the user does not overrun the
  1366. X     * data area.
  1367. X     */
  1368. X    size++;
  1369. X
  1370. X    /*
  1371. X     * Now look for a free area of memory of size bytes...
  1372. X     */
  1373. X    oldptr = NULL;
  1374. X    for(ptr = &malloc_start; ; ptr = ptr->next)
  1375. X    {
  1376. X        /*
  1377. X         * Since the malloc chain is a forward only chain, any
  1378. X         * pointer that we get should always be positioned in 
  1379. X         * memory following the previous pointer.  If this is not
  1380. X         * so, we must have a corrupted chain.
  1381. X         */
  1382. X        if( ptr )
  1383. X        {
  1384. X            if(ptr < oldptr )
  1385. X            {
  1386. X                malloc_errno = M_CODE_CHAIN_BROKE;
  1387. X                malloc_fatal(func);
  1388. X                return(NULL);
  1389. X            }
  1390. X            oldptr = ptr;
  1391. X        }
  1392. X        else if( oldptr != malloc_end )
  1393. X        {
  1394. X            /*
  1395. X             * This should never happen.  If it does, then
  1396. X             * we got a real problem.
  1397. X             */
  1398. X            malloc_errno = M_CODE_NO_END;
  1399. X            malloc_fatal(func);
  1400. X            return(NULL);
  1401. X        }
  1402. X        
  1403. X
  1404. X        /*
  1405. X         * if this element is already in use...
  1406. X         */
  1407. X        if( ptr && ((ptr->flag & M_INUSE) != 0) )
  1408. X        {
  1409. X            continue;
  1410. X        }
  1411. X
  1412. X        /*
  1413. X         * if there isn't room for this block..
  1414. X         */
  1415. X        if( ptr && (ptr->s.size < size) )
  1416. X        {
  1417. X            continue;
  1418. X        }
  1419. X
  1420. X        /*
  1421. X         * If ptr is null, we have run out of memory and must sbrk more
  1422. X         */
  1423. X        if( ptr == NULL )
  1424. X        {
  1425. X            need = (size + M_SIZE) * (size > 100*1024 ? 1:2);
  1426. X            if( need < M_BLOCKSIZE )
  1427. X            {
  1428. X                need = M_BLOCKSIZE;
  1429. X            }
  1430. X            else if( need & (M_BLOCKSIZE-1) )
  1431. X            {
  1432. X                need &= ~(M_BLOCKSIZE-1);
  1433. X                need += M_BLOCKSIZE;
  1434. X            }
  1435. X            ptr = (struct mlist *) sbrk((int)need);
  1436. X            if( ptr == (struct mlist *) -1 )
  1437. X            {
  1438. X                malloc_errno = M_CODE_NOMORE_MEM;
  1439. X                malloc_fatal(func);
  1440. X            }
  1441. X            malloc_data_end = sbrk((int)0);
  1442. X
  1443. X            ptr->prev   = oldptr;
  1444. X            ptr->next   = (struct mlist *) 0;
  1445. X            ptr->s.size = need - M_SIZE;
  1446. X            ptr->flag  = M_MAGIC;
  1447. X
  1448. X            oldptr->next = ptr;
  1449. X            malloc_end = ptr;
  1450. X
  1451. X
  1452. X        } /* if( ptr ==... */
  1453. X
  1454. X        /*
  1455. X          * Now ptr points to a memory location that can store
  1456. X         * this data, so lets go to work.
  1457. X         */
  1458. X
  1459. X        ptr->r_size = size;        /* save requested size    */
  1460. X        ptr->flag |= M_INUSE;
  1461. X
  1462. X        /*
  1463. X          * split off unneeded data area in this block, if possible...
  1464. X         */
  1465. X        malloc_split(ptr);
  1466. X
  1467. X        /*
  1468. X         * re-adjust the requested size so that it is what the user
  1469. X         * actually requested...
  1470. X         */
  1471. X
  1472. X        ptr->r_size--;
  1473. X
  1474. X        /*
  1475. X         * just to make sure that noone is misusing malloced
  1476. X          * memory without initializing it, lets set it to
  1477. X         * all '\01's.  We call local_memset() because memset()
  1478. X         * may be checking for malloc'd ptrs and this isn't
  1479. X         * a malloc'd ptr yet.
  1480. X         */
  1481. X        malloc_memset(ptr->data,M_FILL,(int)ptr->s.size);
  1482. X
  1483. X        return( ptr->data);
  1484. X
  1485. X    } /* for(... */
  1486. X
  1487. X} /* malloc(... */
  1488. X
  1489. X/*
  1490. X * Function:    malloc_split()
  1491. X *
  1492. X * Purpose:    to split a malloc segment if there is enough room at the
  1493. X *        end of the segment that isn't being used
  1494. X *
  1495. X * Arguments:    ptr    - pointer to segment to split
  1496. X *
  1497. X * Returns:    nothing of any use.
  1498. X *
  1499. X * Narrative:
  1500. X *        get the needed size of the module
  1501. X *         round the size up to appropriat boundry
  1502. X *        calculate amount of left over space
  1503. X *        if there is enough left over space
  1504. X *            create new malloc block out of remainder
  1505. X *            if next block is free 
  1506. X *            join the two blocks together
  1507. X *            fill new empty block with free space filler
  1508. X *             re-adjust pointers and size of current malloc block
  1509. X *        
  1510. X *        
  1511. X *
  1512. X * Mod History:    
  1513. X *   90/01/27    cpcahil        Initial revision.
  1514. X */
  1515. Xvoid
  1516. Xmalloc_split(ptr)
  1517. X    struct mlist        * ptr;
  1518. X{
  1519. X    extern struct mlist    * malloc_end;
  1520. X    void              malloc_join();
  1521. X    void              malloc_memset();
  1522. X    int              rest;
  1523. X    int              size;
  1524. X    struct mlist        * tptr;
  1525. X
  1526. X    size = ptr->r_size;
  1527. X
  1528. X    /*
  1529. X     * roundup size to the appropriate boundry
  1530. X     */
  1531. X
  1532. X    M_ROUNDUP(size);
  1533. X
  1534. X    /*
  1535. X     * figure out how much room is left in the array.
  1536. X     * if there is enough room, create a new mlist 
  1537. X     *     structure there.
  1538. X     */
  1539. X
  1540. X    if( ptr->s.size > size )
  1541. X    {
  1542. X        rest = ptr->s.size - size;
  1543. X    }
  1544. X    else
  1545. X    {
  1546. X        rest = 0;
  1547. X    }
  1548. X    
  1549. X    if( rest > (M_SIZE+M_RND) )
  1550. X    {
  1551. X        tptr = (struct mlist *) (ptr->data+size);
  1552. X        tptr->prev = ptr;
  1553. X        tptr->next = ptr->next;
  1554. X        tptr->flag = M_MAGIC;
  1555. X        tptr->s.size = rest - M_SIZE;
  1556. X
  1557. X        /*
  1558. X         * If possible, join this segment with the next one
  1559. X         */
  1560. X
  1561. X        malloc_join(tptr, tptr->next,0,0);
  1562. X
  1563. X        if( tptr->next )
  1564. X        {
  1565. X            tptr->next->prev = tptr;
  1566. X        }
  1567. X
  1568. X        malloc_memset(tptr->data,M_FREE_FILL, (int)tptr->s.size);
  1569. X
  1570. X        ptr->next = tptr;
  1571. X        ptr->s.size = size;
  1572. X
  1573. X        if( malloc_end == ptr )
  1574. X        {
  1575. X            malloc_end = tptr;
  1576. X        }
  1577. X    }
  1578. X
  1579. X} /* malloc_split(... */
  1580. X
  1581. X/*
  1582. X * Function:    malloc_join()
  1583. X *
  1584. X * Purpose:    to join two malloc segments together (if possible)
  1585. X *
  1586. X * Arguments:    ptr    - pointer to segment to join to.
  1587. X *         nextptr    - pointer to next segment to join to ptr.
  1588. X *
  1589. X * Returns:    nothing of any values.
  1590. X *
  1591. X * Narrative:
  1592. X *
  1593. X * Mod History:    
  1594. X *   90/01/27    cpcahil        Initial revision.
  1595. X */
  1596. Xvoid
  1597. Xmalloc_join(ptr,nextptr, inuse_override, fill_flag)
  1598. X    struct mlist    * ptr;
  1599. X    struct mlist    * nextptr;
  1600. X    int          inuse_override;
  1601. X    int          fill_flag;
  1602. X{
  1603. X    unsigned int      newsize;
  1604. X
  1605. X    if(     ptr     && ! (inuse_override || (ptr->flag & M_INUSE)) && 
  1606. X        nextptr && ! (nextptr->flag & M_INUSE) &&
  1607. X        ((ptr->data+ptr->s.size) == (char *) nextptr) )
  1608. X    {
  1609. X        if( malloc_end == nextptr )
  1610. X        {
  1611. X            malloc_end = ptr;
  1612. X        }
  1613. X        ptr->next = nextptr->next;
  1614. X        newsize = nextptr->s.size + M_SIZE;
  1615. X
  1616. X        /*
  1617. X         * if we are to fill and this segment is in use,
  1618. X         *   fill in with M_FILL newly added space...
  1619. X          */
  1620. X
  1621. X        if(fill_flag && (ptr->flag & M_INUSE) )
  1622. X        {
  1623. X            malloc_memset(ptr->data+ptr->s.size,
  1624. X                      M_FILL, (int)(nextptr->s.size + M_SIZE));
  1625. X        }
  1626. X
  1627. X        ptr->s.size += newsize;
  1628. X        if( ptr->next )
  1629. X        {
  1630. X            ptr->next->prev = ptr;
  1631. X        }
  1632. X    }
  1633. X
  1634. X} /* malloc_join(... */
  1635. X
  1636. X
  1637. X/*
  1638. X * The following mess is just to ensure that the versions of these functions in
  1639. X * the current library are included (to make sure that we don't accidentaly get 
  1640. X * the libc versions. (This is the lazy man's -u ld directive)
  1641. X */
  1642. X
  1643. Xvoid free();
  1644. Xint strcmp();
  1645. Xint memcmp();
  1646. Xchar    * realloc();
  1647. X
  1648. Xvoid        (*malloc_void_funcs[])() =
  1649. X{
  1650. X    free,
  1651. X};
  1652. X
  1653. Xint        (*malloc_int_funcs[])() =
  1654. X{
  1655. X    strcmp,
  1656. X    memcmp,
  1657. X};
  1658. X
  1659. Xchar        * (*malloc_char_star_funcs[])() =
  1660. X{
  1661. X    realloc,
  1662. X};
  1663. X
  1664. X/*
  1665. X * This is malloc's own memset which is used without checking the parameters.
  1666. X */
  1667. X
  1668. Xvoid
  1669. Xmalloc_memset(ptr,byte,len)
  1670. X    char        * ptr;
  1671. X    char          byte;
  1672. X    int          len;
  1673. X{
  1674. X
  1675. X    while(len-- > 0)
  1676. X    {
  1677. X        *ptr++ = byte;
  1678. X    }
  1679. X
  1680. X} /* malloc_memset(... */
  1681. X
  1682. X/*
  1683. X * Function:    malloc_fatal()
  1684. X *
  1685. X * Purpose:    to display fatal error message and take approrpriate action
  1686. X *
  1687. X * Arguments:    funcname - name of function calling this routine
  1688. X *
  1689. X * Returns:    nothing of any value
  1690. X *
  1691. X * Narrative:
  1692. X *
  1693. X * Notes:    This routine does not make use of any libc functions to build
  1694. X *        and/or disply the error message.  This is due to the fact that
  1695. X *        we are probably at a point where malloc is having a real problem
  1696. X *        and we don't want to call any function that may use malloc.
  1697. X */
  1698. Xvoid
  1699. Xmalloc_fatal(funcname)
  1700. X    char        * funcname;
  1701. X{
  1702. X    char          errbuf[128];
  1703. X    void          exit();
  1704. X    void          malloc_err_handler();
  1705. X    extern char    * malloc_err_strings[];
  1706. X    extern int      malloc_errno;
  1707. X    extern int      malloc_fatal_level;
  1708. X    char        * s;
  1709. X    char        * t;
  1710. X
  1711. X    s = errbuf;
  1712. X    t = "Fatal error: ";
  1713. X    while( *s = *t++)
  1714. X    {
  1715. X        s++;
  1716. X    }
  1717. X    t = funcname;
  1718. X    while( *s = *t++)
  1719. X    {
  1720. X        s++;
  1721. X    }
  1722. X
  1723. X    t = "(): ";
  1724. X    while( *s = *t++)
  1725. X    {
  1726. X        s++;
  1727. X    }
  1728. X
  1729. X    t = malloc_err_strings[malloc_errno];
  1730. X    while( *s = *t++)
  1731. X    {
  1732. X        s++;
  1733. X    }
  1734. X
  1735. X    *(s++) = '\n';
  1736. X
  1737. X    if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf))
  1738. X    {
  1739. X        (void) write(2,"I/O error to error file\n",(unsigned)24);
  1740. X        exit(110);
  1741. X    }
  1742. X    malloc_err_handler(malloc_fatal_level);
  1743. X
  1744. X} /* malloc_fatal(... */
  1745. X
  1746. X/*
  1747. X * Function:    malloc_warning()
  1748. X *
  1749. X * Purpose:    to display warning error message and take approrpriate action
  1750. X *
  1751. X * Arguments:    funcname - name of function calling this routine
  1752. X *
  1753. X * Returns:    nothing of any value
  1754. X *
  1755. X * Narrative:
  1756. X *
  1757. X * Notes:    This routine does not make use of any libc functions to build
  1758. X *        and/or disply the error message.  This is due to the fact that
  1759. X *        we are probably at a point where malloc is having a real problem
  1760. X *        and we don't want to call any function that may use malloc.
  1761. X */
  1762. Xvoid
  1763. Xmalloc_warning(funcname)
  1764. X    char        * funcname;
  1765. X{
  1766. X    char          errbuf[128];
  1767. X    void          exit();
  1768. X    void          malloc_err_handler();
  1769. X    extern char    * malloc_err_strings[];
  1770. X    extern int      malloc_errno;
  1771. X    extern int      malloc_warn_level;
  1772. X    char        * s;
  1773. X    char        * t;
  1774. X
  1775. X    s = errbuf;
  1776. X    t = "Warning: ";
  1777. X    while( *s = *t++)
  1778. X    {
  1779. X        s++;
  1780. X    }
  1781. X    t = funcname;
  1782. X    while( *s = *t++)
  1783. X    {
  1784. X        s++;
  1785. X    }
  1786. X
  1787. X    t = "(): ";
  1788. X    while( *s = *t++)
  1789. X    {
  1790. X        s++;
  1791. X    }
  1792. X
  1793. X    t = malloc_err_strings[malloc_errno];
  1794. X    while( *s = *t++)
  1795. X    {
  1796. X        s++;
  1797. X    }
  1798. X
  1799. X    *(s++) = '\n';
  1800. X
  1801. X    if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf))
  1802. X    {
  1803. X        (void) write(2,"I/O error to error file\n",(unsigned)24);
  1804. X        exit(110);
  1805. X    }
  1806. X
  1807. X    malloc_err_handler(malloc_warn_level);
  1808. X
  1809. X} /* malloc_warning(... */
  1810. X
  1811. X/*
  1812. X * Function:    malloc_err_handler()
  1813. X *
  1814. X * Purpose:    to take the appropriate action for warning and/or fatal 
  1815. X *        error conditions.
  1816. X *
  1817. X * Arguments:    level - error handling level 
  1818. X *
  1819. X * Returns:    nothing of any value
  1820. X *
  1821. X * Narrative:
  1822. X *
  1823. X * Notes:    This routine does not make use of any libc functions to build
  1824. X *        and/or disply the error message.  This is due to the fact that
  1825. X *        we are probably at a point where malloc is having a real problem
  1826. X *        and we don't want to call any function that may use malloc.
  1827. X */
  1828. Xvoid
  1829. Xmalloc_err_handler(level)
  1830. X{
  1831. X    void          exit();
  1832. X    void          malloc_dump();
  1833. X    extern int      malloc_errfd;
  1834. X
  1835. X    if( level & M_HANDLE_DUMP )
  1836. X    {
  1837. X        malloc_dump(malloc_errfd);
  1838. X    }
  1839. X
  1840. X    switch( level & ~M_HANDLE_DUMP )
  1841. X    {
  1842. X        /*
  1843. X         * If we are to drop a core file and exit
  1844. X         */
  1845. X        case M_HANDLE_ABORT:
  1846. X            (void) abort();
  1847. X            break;
  1848. X
  1849. X        /*
  1850. X         * If we are to exit..
  1851. X         */
  1852. X        case M_HANDLE_EXIT:
  1853. X            exit(200);
  1854. X            break;
  1855. X
  1856. X        /*
  1857. X         * If we are to dump a core, but keep going on our merry way
  1858. X         */
  1859. X        case M_HANDLE_CORE:
  1860. X            {
  1861. X                int      pid;
  1862. X
  1863. X                /*
  1864. X                 * fork so child can abort (and dump core)
  1865. X                 */
  1866. X                if( (pid = fork()) == 0 )
  1867. X                {
  1868. X                    (void) write(2,"Child dumping core\n",
  1869. X                            (unsigned)9);
  1870. X                    (void) abort();
  1871. X                }
  1872. X
  1873. X                /*
  1874. X                  * wait for child to finish dumping core
  1875. X                 */
  1876. X                while( wait((int *)0) != pid)
  1877. X                {
  1878. X                }
  1879. X
  1880. X                /*
  1881. X                 * Move core file to core.pid.cnt so 
  1882. X                 * multiple cores don't overwrite each
  1883. X                 * other.
  1884. X                 */
  1885. X                if( access("core",0) == 0 )
  1886. X                {
  1887. X                    static int      corecnt;
  1888. X                    char            filenam[32];
  1889. X                    filenam[0] = 'c';
  1890. X                    filenam[1] = 'o';
  1891. X                    filenam[2] = 'r';
  1892. X                    filenam[3] = 'e';
  1893. X                    filenam[4] = '.';
  1894. X                    (void)tostring(filenam+5,getpid(),
  1895. X                        5, B_DEC, '0');
  1896. X                    filenam[10] = '.';
  1897. X                    (void)tostring(filenam+11,corecnt++,
  1898. X                        3, B_DEC, '0');
  1899. X                    filenam[14] = '\0';
  1900. X                    (void) unlink(filenam);
  1901. X                    if( link("core",filenam) == 0)
  1902. X                    {
  1903. X                        (void) unlink("core");
  1904. X                    }
  1905. X                }
  1906. X            }
  1907. X
  1908. X
  1909. X        /* 
  1910. X         * If we are to just ignore the error and keep on processing
  1911. X         */
  1912. X        case M_HANDLE_IGNORE:
  1913. X            break;
  1914. X
  1915. X    } /* switch(... */
  1916. X
  1917. X} /* malloc_err_handler(... */
  1918. X
  1919. X/*
  1920. X * $Log:    malloc.c,v $
  1921. X * Revision 1.6  90/05/11  00:13:09  cpcahil
  1922. X * added copyright statment
  1923. X * 
  1924. X * Revision 1.5  90/02/25  11:01:18  cpcahil
  1925. X * added support for malloc chain checking.
  1926. X * 
  1927. X * Revision 1.4  90/02/24  21:50:21  cpcahil
  1928. X * lots of lint fixes
  1929. X * 
  1930. X * Revision 1.3  90/02/24  14:51:18  cpcahil
  1931. X * 1. changed malloc_fatal and malloc_warn to use malloc_errno and be passed
  1932. X *    the function name as a parameter.
  1933. X * 2. Added several function headers.
  1934. X * 3. Changed uses of malloc_fatal/warning to conform to new usage.
  1935. X * 
  1936. X * Revision 1.2  90/02/23  18:05:23  cpcahil
  1937. X * fixed open of error log to use append mode.
  1938. X * 
  1939. X * Revision 1.1  90/02/22  23:17:43  cpcahil
  1940. X * Initial revision
  1941. X * 
  1942. X */
  1943. SHAR_EOF
  1944. $TOUCH -am 0511001490 malloc.c &&
  1945. chmod 0444 malloc.c ||
  1946. echo "restore of malloc.c failed"
  1947. set `wc -c malloc.c`;Wc_c=$1
  1948. if test "$Wc_c" != "12756"; then
  1949.     echo original size 12756, current size $Wc_c
  1950. fi
  1951. fi
  1952. echo "End of part 1, continue with part 2"
  1953. exit 0
  1954.  
  1955. exit 0 # Just in case...
  1956.