home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume27 / dmake / part05 < prev    next >
Encoding:
Text File  |  1992-01-29  |  40.0 KB  |  1,797 lines

  1. Newsgroups: comp.sources.misc
  2. From: dvadura@plg.waterloo.edu (Dennis Vadura)
  3. Subject:  v27i106:  dmake - dmake Version 3.8, Part05/41
  4. Message-ID: <1992Jan28.031308.7011@sparky.imd.sterling.com>
  5. X-Md4-Signature: bfbcc482364abe3521ca088b6ffcb493
  6. Date: Tue, 28 Jan 1992 03:13:08 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: dvadura@plg.waterloo.edu (Dennis Vadura)
  10. Posting-number: Volume 27, Issue 106
  11. Archive-name: dmake/part05
  12. Environment: Atari-ST, Coherent, Mac, MSDOS, OS/2, UNIX
  13. Supersedes: dmake: Volume 19, Issue 22-58
  14.  
  15. ---- Cut Here and feed the following to sh ----
  16. # this is dmake.shar.05 (part 5 of a multipart archive)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file dmake/dbug/malloc/malloc.3 continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 5; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test -f _shar_wnt_.tmp; then
  33. sed 's/^X//' << 'SHAR_EOF' >> 'dmake/dbug/malloc/malloc.3' &&
  34. of this check is considered a "warning level error" (described later) and
  35. is handled accordingly.
  36. .P
  37. 7. Run time checking can include verification of the malloc chain at each
  38. and every call to one of the malloc functions or manually by calling the
  39. malloc_chain_check function.
  40. .P
  41. 6. When a problem is found, the action taken is specified at runtime by
  42. environment variables or at compile time by the use of the mallopt()
  43. function.
  44. .P
  45. There are two arbitrary levels of errors, warning and fatal, that this
  46. library will detect.  They are broken down as follows:
  47. .P
  48. .nf
  49. .in +.25i
  50. Warning messages include:
  51. .sp
  52. .in +.5i
  53. .ti -.25i
  54. Calling free with a bad pointer
  55. .br
  56. .ti -.25i
  57. Calling a bstring/string/memory (3) function which will go beyond
  58. the end of a malloc block. Note that the library function is
  59. not modified to refuse the operation.
  60. .sp
  61. .in -.5i
  62. Fatal errors are:
  63. .in +.5i
  64. .ti -.25i
  65. Detectable corruption to the malloc chain.
  66. .in -.5i
  67. .in -.25i
  68. .P
  69. The error handling for each level (warning or fatal) are specified using
  70. environment variables or mallopt().  The coding for the error handling is
  71. as follows:
  72. .sp
  73. .nf
  74. .in +.5i
  75. .ti -.25i
  76. X  0 - continue operations
  77. .ti -.25i
  78. X  1 - drop core and exit
  79. .ti -.25i
  80. X  2 - just exit
  81. .ti -.25i
  82. X  3 - drop core, but continue executing.  Core files will
  83. be placed into core.[PID].[counter] i.e: core.00123.001
  84. .ti -.25i
  85. 128 - dump malloc chain and continue
  86. .ti -.25i
  87. 129 - dump malloc chain, dump core, and exit
  88. .ti -.25i
  89. 130 - dump malloc chain, exit
  90. .ti -.25i
  91. 131 - dump malloc chain, dump core, continue processing
  92. .in -.5i
  93. .P
  94. In addition error messages can be placed into an error file.
  95. .P
  96. \fBmalloc_opt\fP() is used to set the malloc debugging options. The
  97. following options can be set:
  98. .br
  99. .sp
  100. .in +.5i
  101. MALLOC_WARN - set the error handling for warning level errors.  \fBval.i\fP is
  102. an integer that can contain any one of the following values:
  103. .sp
  104. .in +.5i
  105. M_HANDLE_IGNORE - ignore error
  106. .br
  107. M_HANDLE_ABORT - drop core and exit
  108. .br
  109. M_HANDLE_EXIT - just exit (no core drop)
  110. .br
  111. M_HANDLE_CORE - drop core, but keep on going
  112. .br
  113. .in -.5i
  114. .sp
  115. In addition, M_HANDLE_DUMP may be or'd in to cause a dump of the current
  116. malloc chain.
  117. .br
  118. .sp
  119. MALLOC_FATAL - set the error handling for fatal level errors.  \fBval.i\fP is
  120. equivalent to \fBval.i\fP for MALLOC_WARN.
  121. .br
  122. .sp
  123. MALLOC_ERRFILE - set the destination for malloc error messages.  \fBval.str\fP
  124. is a pointer to a character string containing the name of the file to be used
  125. for error messages.
  126. .br
  127. .sp
  128. MALLOC_CKCHAIN - set the malloc chain checking flag.  If \fBval.i\fP is
  129. non-zero, chain checking at every call to malloc is turned on.
  130. .br
  131. .sp
  132. For example, to set up the session to generate a core file for
  133. every malloc warning, to drop core and exit on a malloc fatal, and 
  134. to log all messages to the file "malloc_log" do the following:
  135. .sp
  136. .nf
  137. .in +.5i
  138. #include <malloc.h>
  139. malloc_opt(MALLOC_WARN,131);
  140. malloc_opt(MALLOC_FATAL,1);
  141. malloc_opt(MALLOC_ERRFILE,"malloc_log");
  142. .in -.5i
  143. .fi
  144. .in -.5i
  145. .sp
  146. \fBmalloc_opt\fP() can be used to set/alter the debugging options at any
  147. time.
  148. .P
  149. \fBmalloc_dump\fP() will dump a table of the malloc arena showing all
  150. allocated/freed segments and the first few bytes of data in each segment.
  151. \fBfd\fP is the file descriptor to write the data to.
  152. .P
  153. \fBmalloc_chain_check\fP() will check the status of the malloc arena.
  154. If \fBflag\fP is non-zero, an error found in the chain will cause a 
  155. fatal error.  \fBmalloc_chain_check\fP() returns zero when there are no
  156. problems found in the malloc chain, non-zero otherwise.
  157. .SH "ENVIRONMENT VARIABLES"
  158. Environment variables can be used to control error handling, error logging
  159. and malloc chain checking at run time.  The following environment variables
  160. are used:
  161. .P
  162. MALLOC_WARN - specifies the error handling for warning errors
  163. .br
  164. MALLOC_FATAL - specifies the error handling for fatal errors
  165. .br
  166. MALLOC_ERRFILE - specifies the error log file for error messages.  
  167. .br
  168. MALLOC_CKCHAIN - if 1, turns on malloc chain checking at every call to any
  169. of the malloc functions.
  170. .P
  171. For example, to set up the session to generate a core file for
  172. every malloc warning, to drop core and exit on a malloc fatal, and 
  173. to log all messages to the file "malloc_log" do the following:
  174. .sp
  175. .nf
  176. .in +.5i
  177. MALLOC_WARN=131
  178. MALLOC_FATAL=1
  179. MALLOC_ERRFILE=malloc_log
  180. X
  181. export MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE
  182. .in -.5i
  183. .fi
  184. .SH WARNINGS
  185. This malloc library and it's associated string and memory functions are
  186. much less efficient than the standard functions due in part to the extra
  187. error checking.  You do not want to use this library when generating a
  188. production (i.e. releasable) version of your software.  It should only
  189. be used during development and testing.
  190. .SH SEE ALSO
  191. stat(2)
  192. .SH AUTHOR
  193. Conor P. Cahill
  194. Virtual Technologies Incorporated
  195. .sp
  196. uunet!virtech!cpcahil
  197. SHAR_EOF
  198. chmod 0640 dmake/dbug/malloc/malloc.3 ||
  199. echo 'restore of dmake/dbug/malloc/malloc.3 failed'
  200. Wc_c="`wc -c < 'dmake/dbug/malloc/malloc.3'`"
  201. test 6712 -eq "$Wc_c" ||
  202.     echo 'dmake/dbug/malloc/malloc.3: original size 6712, current size' "$Wc_c"
  203. rm -f _shar_wnt_.tmp
  204. fi
  205. # ============= dmake/dbug/malloc/malloc.c ==============
  206. if test -f 'dmake/dbug/malloc/malloc.c' -a X"$1" != X"-c"; then
  207.     echo 'x - skipping dmake/dbug/malloc/malloc.c (File already exists)'
  208.     rm -f _shar_wnt_.tmp
  209. else
  210. > _shar_wnt_.tmp
  211. sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/malloc.c' &&
  212. /*
  213. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  214. X * You may copy, distribute, and use this software as long as this
  215. X * copyright statement is not removed.
  216. X */
  217. #include <stdio.h>
  218. #include <fcntl.h>
  219. #include "malloc.h"
  220. #include "tostring.h"
  221. X
  222. /*
  223. X * Function:    malloc()
  224. X *
  225. X * Purpose:    memory allocator
  226. X *
  227. X * Arguments:    size    - size of data area needed
  228. X *
  229. X * Returns:    pointer to allocated area, or NULL if unable
  230. X *        to allocate addtional data.
  231. X *
  232. X * Narrative:
  233. X *
  234. X */
  235. #ifndef lint
  236. static
  237. char rcs_hdr[] = "$Id: malloc.c,v 1.1 1992/01/24 03:29:05 dvadura Exp $";
  238. #endif
  239. X
  240. extern int      malloc_checking;
  241. char        * malloc_data_start;
  242. char        * malloc_data_end;
  243. struct mlist     * malloc_end;
  244. int          malloc_errfd = 2;
  245. int          malloc_errno;
  246. int          malloc_fatal_level = M_HANDLE_CORE;
  247. struct mlist      malloc_start;
  248. int          malloc_warn_level;
  249. void          malloc_memset();
  250. X
  251. char *
  252. malloc(size)
  253. X    unsigned int      size;
  254. {
  255. X    char        * func = "malloc";
  256. X    char        * getenv();
  257. X    void          malloc_fatal();
  258. X    void          malloc_init();
  259. X    void          malloc_split();
  260. X    void          malloc_warning();
  261. X    unsigned int      need;
  262. X    struct mlist    * oldptr;
  263. X    struct mlist    * ptr;
  264. X    char        * sbrk();
  265. X
  266. X    /*
  267. X     * If this is the first call to malloc...
  268. X     */
  269. X    if( malloc_data_start == (char *) 0 )
  270. X    {
  271. X        malloc_init();
  272. X    }
  273. X
  274. X    /*
  275. X     * If malloc chain checking is on, go do it.
  276. X     */
  277. X    if( malloc_checking )
  278. X    {
  279. X        (void) malloc_chain_check(1);
  280. X    }
  281. X
  282. X    /*
  283. X     * always make sure there is at least on extra byte in the malloc
  284. X     * area so that we can verify that the user does not overrun the
  285. X     * data area.
  286. X     */
  287. X    size++;
  288. X
  289. X    /*
  290. X     * Now look for a free area of memory of size bytes...
  291. X     */
  292. X    oldptr = NULL;
  293. X    for(ptr = &malloc_start; ; ptr = ptr->next)
  294. X    {
  295. X        /*
  296. X         * Since the malloc chain is a forward only chain, any
  297. X         * pointer that we get should always be positioned in 
  298. X         * memory following the previous pointer.  If this is not
  299. X         * so, we must have a corrupted chain.
  300. X         */
  301. X        if( ptr )
  302. X        {
  303. X            if( IsLess(ptr,oldptr) )
  304. X            {
  305. X                malloc_errno = M_CODE_CHAIN_BROKE;
  306. X                malloc_fatal(func);
  307. X                return(NULL);
  308. X            }
  309. X            oldptr = ptr;
  310. X        }
  311. X        else if( oldptr != malloc_end )
  312. X        {
  313. X            /*
  314. X             * This should never happen.  If it does, then
  315. X             * we got a real problem.
  316. X             */
  317. X            malloc_errno = M_CODE_NO_END;
  318. X            malloc_fatal(func);
  319. X            return(NULL);
  320. X        }
  321. X        
  322. X
  323. X        /*
  324. X         * if this element is already in use...
  325. X         */
  326. X        if( ptr && ((ptr->flag & M_INUSE) != 0) )
  327. X        {
  328. X            continue;
  329. X        }
  330. X
  331. X        /*
  332. X         * if there isn't room for this block..
  333. X         */
  334. X        if( ptr && (ptr->s.size < size) )
  335. X        {
  336. X            continue;
  337. X        }
  338. X
  339. X        /*
  340. X         * If ptr is null, we have run out of memory and must sbrk more
  341. X         */
  342. X        if( ptr == NULL )
  343. X        {
  344. X            need = (size + M_SIZE) * (size > 10*1024 ? 1:2);
  345. X            if( need < M_BLOCKSIZE )
  346. X            {
  347. X                need = M_BLOCKSIZE;
  348. X            }
  349. X            else if( need & (M_BLOCKSIZE-1) )
  350. X            {
  351. X                need &= ~(M_BLOCKSIZE-1);
  352. X                need += M_BLOCKSIZE;
  353. X            }
  354. X            ptr = (struct mlist *) sbrk((int)need);
  355. X            if( ptr == (struct mlist *) -1 )
  356. X            {
  357. X                malloc_errno = M_CODE_NOMORE_MEM;
  358. X                malloc_fatal(func);
  359. X            }
  360. X            malloc_data_end = sbrk((int)0);
  361. X
  362. X            ptr->prev   = oldptr;
  363. X            ptr->next   = (struct mlist *) 0;
  364. X            ptr->s.size = need - M_SIZE;
  365. X            ptr->flag  = M_MAGIC;
  366. X
  367. X            oldptr->next = ptr;
  368. X            malloc_end = ptr;
  369. X
  370. X
  371. X        } /* if( ptr ==... */
  372. X
  373. X        /*
  374. X          * Now ptr points to a memory location that can store
  375. X         * this data, so lets go to work.
  376. X         */
  377. X
  378. X        ptr->r_size = size;        /* save requested size    */
  379. X        ptr->flag |= M_INUSE;
  380. X
  381. X        /*
  382. X          * split off unneeded data area in this block, if possible...
  383. X         */
  384. X        malloc_split(ptr);
  385. X
  386. X        /*
  387. X         * re-adjust the requested size so that it is what the user
  388. X         * actually requested...
  389. X         */
  390. X
  391. X        ptr->r_size--;
  392. X
  393. X        /*
  394. X         * just to make sure that noone is misusing malloced
  395. X          * memory without initializing it, lets set it to
  396. X         * all '\01's.  We call local_memset() because memset()
  397. X         * may be checking for malloc'd ptrs and this isn't
  398. X         * a malloc'd ptr yet.
  399. X         */
  400. X        malloc_memset(ptr->data,M_FILL,(int)ptr->s.size);
  401. X
  402. X        return( ptr->data);
  403. X
  404. X    } /* for(... */
  405. X
  406. } /* malloc(... */
  407. X
  408. /*
  409. X * Function:    malloc_split()
  410. X *
  411. X * Purpose:    to split a malloc segment if there is enough room at the
  412. X *        end of the segment that isn't being used
  413. X *
  414. X * Arguments:    ptr    - pointer to segment to split
  415. X *
  416. X * Returns:    nothing of any use.
  417. X *
  418. X * Narrative:
  419. X *        get the needed size of the module
  420. X *         round the size up to appropriat boundry
  421. X *        calculate amount of left over space
  422. X *        if there is enough left over space
  423. X *            create new malloc block out of remainder
  424. X *            if next block is free 
  425. X *            join the two blocks together
  426. X *            fill new empty block with free space filler
  427. X *             re-adjust pointers and size of current malloc block
  428. X *        
  429. X *        
  430. X *
  431. X * Mod History:    
  432. X *   90/01/27    cpcahil        Initial revision.
  433. X */
  434. void
  435. malloc_split(ptr)
  436. X    struct mlist        * ptr;
  437. {
  438. X    extern struct mlist    * malloc_end;
  439. X    void              malloc_join();
  440. X    int              rest;
  441. X    int              size;
  442. X    struct mlist        * tptr;
  443. X
  444. X    size = ptr->r_size;
  445. X
  446. X    /*
  447. X     * roundup size to the appropriate boundry
  448. X     */
  449. X
  450. X    M_ROUNDUP(size);
  451. X
  452. X    /*
  453. X     * figure out how much room is left in the array.
  454. X     * if there is enough room, create a new mlist 
  455. X     *     structure there.
  456. X     */
  457. X
  458. X    if( ptr->s.size > size )
  459. X    {
  460. X        rest = ptr->s.size - size;
  461. X    }
  462. X    else
  463. X    {
  464. X        rest = 0;
  465. X    }
  466. X    
  467. X    if( rest > (M_SIZE+M_RND) )
  468. X    {
  469. X        tptr = (struct mlist *) (ptr->data+size);
  470. X        tptr->prev = ptr;
  471. X        tptr->next = ptr->next;
  472. X        tptr->flag = M_MAGIC;
  473. X        tptr->s.size = rest - M_SIZE;
  474. X
  475. X        /*
  476. X         * If possible, join this segment with the next one
  477. X         */
  478. X
  479. X        malloc_join(tptr, tptr->next,0,0);
  480. X
  481. X        if( tptr->next )
  482. X        {
  483. X            tptr->next->prev = tptr;
  484. X        }
  485. X
  486. X        malloc_memset(tptr->data,M_FREE_FILL, (int)tptr->s.size);
  487. X
  488. X        ptr->next = tptr;
  489. X        ptr->s.size = size;
  490. X
  491. X        if( malloc_end == ptr )
  492. X        {
  493. X            malloc_end = tptr;
  494. X        }
  495. X    }
  496. X
  497. } /* malloc_split(... */
  498. X
  499. /*
  500. X * Function:    malloc_join()
  501. X *
  502. X * Purpose:    to join two malloc segments together (if possible)
  503. X *
  504. X * Arguments:    ptr    - pointer to segment to join to.
  505. X *         nextptr    - pointer to next segment to join to ptr.
  506. X *
  507. X * Returns:    nothing of any values.
  508. X *
  509. X * Narrative:
  510. X *
  511. X * Mod History:    
  512. X *   90/01/27    cpcahil        Initial revision.
  513. X */
  514. void
  515. malloc_join(ptr,nextptr, inuse_override, fill_flag)
  516. X    struct mlist    * ptr;
  517. X    struct mlist    * nextptr;
  518. X    int          inuse_override;
  519. X    int          fill_flag;
  520. {
  521. X    unsigned int      newsize;
  522. X
  523. X    if(     ptr     && ! (inuse_override || (ptr->flag & M_INUSE)) && 
  524. X        nextptr && ! (nextptr->flag & M_INUSE) &&
  525. X        ((ptr->data+ptr->s.size) == (char *) nextptr) )
  526. X    {
  527. X        if( malloc_end == nextptr )
  528. X        {
  529. X            malloc_end = ptr;
  530. X        }
  531. X        ptr->next = nextptr->next;
  532. X        newsize = nextptr->s.size + M_SIZE;
  533. X
  534. X        /*
  535. X         * if we are to fill and this segment is in use,
  536. X         *   fill in with M_FILL newly added space...
  537. X          */
  538. X
  539. X        if(fill_flag && (ptr->flag & M_INUSE) )
  540. X        {
  541. X            malloc_memset(ptr->data+ptr->s.size,
  542. X                      M_FILL, (int)(nextptr->s.size + M_SIZE));
  543. X        }
  544. X
  545. X        ptr->s.size += newsize;
  546. X        if( ptr->next )
  547. X        {
  548. X            ptr->next->prev = ptr;
  549. X        }
  550. X    }
  551. X
  552. } /* malloc_join(... */
  553. X
  554. X
  555. /*
  556. X * The following mess is just to ensure that the versions of these functions in
  557. X * the current library are included (to make sure that we don't accidentaly get 
  558. X * the libc versions. (This is the lazy man's -u ld directive)
  559. X */
  560. X
  561. void free();
  562. int strcmp();
  563. int memcmp();
  564. char    * realloc();
  565. X
  566. void        (*malloc_void_funcs[])() =
  567. {
  568. X    free,
  569. };
  570. X
  571. int        (*malloc_int_funcs[])() =
  572. {
  573. X    strcmp,
  574. X    memcmp,
  575. };
  576. X
  577. char        * (*malloc_char_star_funcs[])() =
  578. {
  579. X    realloc,
  580. };
  581. X
  582. /*
  583. X * This is malloc's own memset which is used without checking the parameters.
  584. X */
  585. X
  586. void
  587. malloc_memset(ptr,byte,len)
  588. X    char        * ptr;
  589. X    char          byte;
  590. X    int          len;
  591. {
  592. X
  593. X    while(len-- > 0)
  594. X    {
  595. X        *ptr++ = byte;
  596. X    }
  597. X
  598. } /* malloc_memset(... */
  599. X
  600. /*
  601. X * Function:    malloc_fatal()
  602. X *
  603. X * Purpose:    to display fatal error message and take approrpriate action
  604. X *
  605. X * Arguments:    funcname - name of function calling this routine
  606. X *
  607. X * Returns:    nothing of any value
  608. X *
  609. X * Narrative:
  610. X *
  611. X * Notes:    This routine does not make use of any libc functions to build
  612. X *        and/or disply the error message.  This is due to the fact that
  613. X *        we are probably at a point where malloc is having a real problem
  614. X *        and we don't want to call any function that may use malloc.
  615. X */
  616. void
  617. malloc_fatal(funcname)
  618. X    char        * funcname;
  619. {
  620. X    char          errbuf[128];
  621. X    void          exit();
  622. X    void          malloc_err_handler();
  623. X    extern char    * malloc_err_strings[];
  624. X    extern int      malloc_errno;
  625. X    extern int      malloc_fatal_level;
  626. X    char        * s;
  627. X    char        * t;
  628. X
  629. X    s = errbuf;
  630. X    t = "Fatal error: ";
  631. X    while( *s = *t++)
  632. X    {
  633. X        s++;
  634. X    }
  635. X    t = funcname;
  636. X    while( *s = *t++)
  637. X    {
  638. X        s++;
  639. X    }
  640. X
  641. X    t = "(): ";
  642. X    while( *s = *t++)
  643. X    {
  644. X        s++;
  645. X    }
  646. X
  647. X    t = malloc_err_strings[malloc_errno];
  648. X    while( *s = *t++)
  649. X    {
  650. X        s++;
  651. X    }
  652. X
  653. X    *(s++) = '\n';
  654. X
  655. X    if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf))
  656. X    {
  657. X        (void) write(2,"I/O error to error file\n",(unsigned)24);
  658. X        exit(110);
  659. X    }
  660. X    malloc_err_handler(malloc_fatal_level);
  661. X
  662. } /* malloc_fatal(... */
  663. X
  664. /*
  665. X * Function:    malloc_warning()
  666. X *
  667. X * Purpose:    to display warning error message and take approrpriate action
  668. X *
  669. X * Arguments:    funcname - name of function calling this routine
  670. X *
  671. X * Returns:    nothing of any value
  672. X *
  673. X * Narrative:
  674. X *
  675. X * Notes:    This routine does not make use of any libc functions to build
  676. X *        and/or disply the error message.  This is due to the fact that
  677. X *        we are probably at a point where malloc is having a real problem
  678. X *        and we don't want to call any function that may use malloc.
  679. X */
  680. void
  681. malloc_warning(funcname)
  682. X    char        * funcname;
  683. {
  684. X    char          errbuf[128];
  685. X    void          exit();
  686. X    void          malloc_err_handler();
  687. X    extern char    * malloc_err_strings[];
  688. X    extern int      malloc_errno;
  689. X    extern int      malloc_warn_level;
  690. X    char        * s;
  691. X    char        * t;
  692. X
  693. X    s = errbuf;
  694. X    t = "Warning: ";
  695. X    while( *s = *t++)
  696. X    {
  697. X        s++;
  698. X    }
  699. X    t = funcname;
  700. X    while( *s = *t++)
  701. X    {
  702. X        s++;
  703. X    }
  704. X
  705. X    t = "(): ";
  706. X    while( *s = *t++)
  707. X    {
  708. X        s++;
  709. X    }
  710. X
  711. X    t = malloc_err_strings[malloc_errno];
  712. X    while( *s = *t++)
  713. X    {
  714. X        s++;
  715. X    }
  716. X
  717. X    *(s++) = '\n';
  718. X
  719. X    if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf))
  720. X    {
  721. X        (void) write(2,"I/O error to error file\n",(unsigned)24);
  722. X        exit(110);
  723. X    }
  724. X
  725. X    malloc_err_handler(malloc_warn_level);
  726. X
  727. } /* malloc_warning(... */
  728. X
  729. /*
  730. X * Function:    malloc_err_handler()
  731. X *
  732. X * Purpose:    to take the appropriate action for warning and/or fatal 
  733. X *        error conditions.
  734. X *
  735. X * Arguments:    level - error handling level 
  736. X *
  737. X * Returns:    nothing of any value
  738. X *
  739. X * Narrative:
  740. X *
  741. X * Notes:    This routine does not make use of any libc functions to build
  742. X *        and/or disply the error message.  This is due to the fact that
  743. X *        we are probably at a point where malloc is having a real problem
  744. X *        and we don't want to call any function that may use malloc.
  745. X */
  746. void
  747. malloc_err_handler(level)
  748. {
  749. X    void          exit();
  750. X    void          malloc_dump();
  751. X    extern int      malloc_errfd;
  752. X
  753. X    if( level & M_HANDLE_DUMP )
  754. X    {
  755. X        malloc_dump(malloc_errfd);
  756. X    }
  757. X
  758. X    switch( level & ~M_HANDLE_DUMP )
  759. X    {
  760. X        /*
  761. X         * If we are to drop a core file and exit
  762. X         */
  763. X        case M_HANDLE_ABORT:
  764. X            (void) abort();
  765. X            break;
  766. X
  767. X        /*
  768. X         * If we are to exit..
  769. X         */
  770. X        case M_HANDLE_EXIT:
  771. X            exit(200);
  772. X            break;
  773. X
  774. #ifndef __MSDOS__
  775. X        /*
  776. X         * If we are to dump a core, but keep going on our merry way
  777. X         */
  778. X        case M_HANDLE_CORE:
  779. X            {
  780. X                int      pid;
  781. X
  782. X                /*
  783. X                 * fork so child can abort (and dump core)
  784. X                 */
  785. X                if( (pid = fork()) == 0 )
  786. X                {
  787. X                    (void) write(2,"Child dumping core\n",
  788. X                            (unsigned)9);
  789. X                    (void) abort();
  790. X                }
  791. X
  792. X                /*
  793. X                  * wait for child to finish dumping core
  794. X                 */
  795. X                while( wait((int *)0) != pid)
  796. X                {
  797. X                }
  798. X
  799. X                /*
  800. X                 * Move core file to core.pid.cnt so 
  801. X                 * multiple cores don't overwrite each
  802. X                 * other.
  803. X                 */
  804. X                if( access("core",0) == 0 )
  805. X                {
  806. X                    static int      corecnt;
  807. X                    char            filenam[32];
  808. X                    filenam[0] = 'c';
  809. X                    filenam[1] = 'o';
  810. X                    filenam[2] = 'r';
  811. X                    filenam[3] = 'e';
  812. X                    filenam[4] = '.';
  813. X                    (void)tostring(filenam+5,getpid(),
  814. X                        5, B_DEC, '0');
  815. X                    filenam[10] = '.';
  816. X                    (void)tostring(filenam+11,corecnt++,
  817. X                        3, B_DEC, '0');
  818. X                    filenam[14] = '\0';
  819. X                    (void) unlink(filenam);
  820. X                    if( link("core",filenam) == 0)
  821. X                    {
  822. X                        (void) unlink("core");
  823. X                    }
  824. X                }
  825. X            }
  826. #endif
  827. X
  828. X
  829. X        /* 
  830. X         * If we are to just ignore the error and keep on processing
  831. X         */
  832. X        case M_HANDLE_IGNORE:
  833. X            break;
  834. X
  835. X    } /* switch(... */
  836. X
  837. } /* malloc_err_handler(... */
  838. X
  839. /*
  840. X * $Log: malloc.c,v $
  841. X * Revision 1.1  1992/01/24  03:29:05  dvadura
  842. X * dmake Version 3.8, Initial revision
  843. X *
  844. X * Revision 1.6  90/05/11  00:13:09  cpcahil
  845. X * added copyright statment
  846. X * 
  847. X * Revision 1.5  90/02/25  11:01:18  cpcahil
  848. X * added support for malloc chain checking.
  849. X * 
  850. X * Revision 1.4  90/02/24  21:50:21  cpcahil
  851. X * lots of lint fixes
  852. X * 
  853. X * Revision 1.3  90/02/24  14:51:18  cpcahil
  854. X * 1. changed malloc_fatal and malloc_warn to use malloc_errno and be passed
  855. X *    the function name as a parameter.
  856. X * 2. Added several function headers.
  857. X * 3. Changed uses of malloc_fatal/warning to conform to new usage.
  858. X * 
  859. X * Revision 1.2  90/02/23  18:05:23  cpcahil
  860. X * fixed open of error log to use append mode.
  861. X * 
  862. X * Revision 1.1  90/02/22  23:17:43  cpcahil
  863. X * Initial revision
  864. X * 
  865. X */
  866. SHAR_EOF
  867. chmod 0640 dmake/dbug/malloc/malloc.c ||
  868. echo 'restore of dmake/dbug/malloc/malloc.c failed'
  869. Wc_c="`wc -c < 'dmake/dbug/malloc/malloc.c'`"
  870. test 12856 -eq "$Wc_c" ||
  871.     echo 'dmake/dbug/malloc/malloc.c: original size 12856, current size' "$Wc_c"
  872. rm -f _shar_wnt_.tmp
  873. fi
  874. # ============= dmake/dbug/malloc/malloc.h ==============
  875. if test -f 'dmake/dbug/malloc/malloc.h' -a X"$1" != X"-c"; then
  876.     echo 'x - skipping dmake/dbug/malloc/malloc.h (File already exists)'
  877.     rm -f _shar_wnt_.tmp
  878. else
  879. > _shar_wnt_.tmp
  880. sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/malloc.h' &&
  881. /*
  882. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  883. X * You may copy, distribute, and use this software as long as this
  884. X * copyright statement is not removed.
  885. X */
  886. /*
  887. X * $Id: malloc.h,v 1.1 1992/01/24 03:29:06 dvadura Exp $
  888. X */
  889. struct mlist
  890. {
  891. X    struct mlist    * next;            /* next entry in chain    */
  892. X    struct mlist    * prev;            /* prev entry in chain    */
  893. X    int           flag;            /* inuse flag        */
  894. X    unsigned int      r_size;        /* requested size    */
  895. X    union
  896. X    {
  897. X        unsigned int      size;        /* actual size        */
  898. X        double          unused_just_for_alignment;
  899. X    } s;
  900. X    char          data[4];
  901. };
  902. X
  903. #define M_SIZE        ((int)(char *)((struct mlist *)0)->data)
  904. #define M_RND        0x08
  905. X
  906. #define M_INUSE     0x01
  907. #define M_MAGIC     0x03156100
  908. X
  909. #define M_BLOCKSIZE    (1024*8)
  910. X
  911. #define M_FILL        '\01'
  912. #define M_FREE_FILL    '\02'
  913. X
  914. #define M_ROUNDUP(size)    {\
  915. X                if( size & (M_RND-1) ) \
  916. X                { \
  917. X                    size &= ~(M_RND-1); \
  918. X                    size += M_RND; \
  919. X                } \
  920. X            }
  921. X
  922. /*
  923. X * Malloc warning/fatal error handler defines...
  924. X */
  925. #define M_HANDLE_DUMP    0x80  /* 128 */
  926. #define M_HANDLE_IGNORE    0
  927. #define M_HANDLE_ABORT    1
  928. #define M_HANDLE_EXIT    2
  929. #define M_HANDLE_CORE    3
  930. X    
  931. /*
  932. X * Mallopt commands and defaults
  933. X */
  934. X
  935. #define MALLOC_WARN    1        /* set malloc warning handling    */
  936. #define MALLOC_FATAL    2        /* set malloc fatal handling    */
  937. #define MALLOC_ERRFILE    3        /* specify malloc error file    */
  938. #define MALLOC_CKCHAIN    4        /* turn on chain checking    */
  939. union malloptarg
  940. {
  941. X    int      i;
  942. X    char    * str;
  943. };
  944. X
  945. /*
  946. X * Malloc warning/fatal error codes
  947. X */
  948. X
  949. #define M_CODE_CHAIN_BROKE    1    /* malloc chain is broken    */
  950. #define M_CODE_NO_END        2    /* chain end != endptr        */
  951. #define M_CODE_BAD_PTR        3    /* pointer not in malloc area    */
  952. #define M_CODE_BAD_MAGIC    4    /* bad magic number in header    */
  953. #define M_CODE_BAD_CONNECT    5    /* chain poingers corrupt    */
  954. #define M_CODE_OVERRUN        6    /* data overrun in malloc seg    */
  955. #define M_CODE_REUSE        7    /* reuse of freed area        */
  956. #define M_CODE_NOT_INUSE    8    /* pointer is not in use    */
  957. #define M_CODE_NOMORE_MEM    9    /* no more memory available    */
  958. #define M_CODE_OUTOF_BOUNDS    10    /* gone beyound bounds         */
  959. X
  960. void malloc_warning();
  961. void malloc_fatal();
  962. void malloc_check_data();
  963. void malloc_check_str();
  964. void malloc_verify();
  965. X
  966. /*
  967. X * $Log: malloc.h,v $
  968. X * Revision 1.1  1992/01/24  03:29:06  dvadura
  969. X * dmake Version 3.8, Initial revision
  970. X *
  971. X * Revision 1.4  90/08/29  22:23:38  cpcahil
  972. X * fixed mallopt to use a union as an argument.
  973. X * 
  974. X * Revision 1.3  90/05/11  11:04:10  cpcahil
  975. X * took out some extraneous lines
  976. X * 
  977. X * Revision 1.2  90/05/11  00:13:09  cpcahil
  978. X * added copyright statment
  979. X * 
  980. X * Revision 1.1  90/02/23  07:09:03  cpcahil
  981. X * Initial revision
  982. X * 
  983. X */
  984. SHAR_EOF
  985. chmod 0640 dmake/dbug/malloc/malloc.h ||
  986. echo 'restore of dmake/dbug/malloc/malloc.h failed'
  987. Wc_c="`wc -c < 'dmake/dbug/malloc/malloc.h'`"
  988. test 2578 -eq "$Wc_c" ||
  989.     echo 'dmake/dbug/malloc/malloc.h: original size 2578, current size' "$Wc_c"
  990. rm -f _shar_wnt_.tmp
  991. fi
  992. # ============= dmake/dbug/malloc/mallopt.c ==============
  993. if test -f 'dmake/dbug/malloc/mallopt.c' -a X"$1" != X"-c"; then
  994.     echo 'x - skipping dmake/dbug/malloc/mallopt.c (File already exists)'
  995.     rm -f _shar_wnt_.tmp
  996. else
  997. > _shar_wnt_.tmp
  998. sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/mallopt.c' &&
  999. /*
  1000. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  1001. X * You may copy, distribute, and use this software as long as this
  1002. X * copyright statement is not removed.
  1003. X */
  1004. #include <stdio.h>
  1005. #include <fcntl.h>
  1006. #include "malloc.h"
  1007. X
  1008. /*
  1009. X * Function:    mallopt()
  1010. X *
  1011. X * Purpose:    to set options for the malloc debugging library
  1012. X *
  1013. X * Arguments:    none
  1014. X *
  1015. X * Returns:    nothing of any value
  1016. X *
  1017. X * Narrative:    
  1018. X *
  1019. X */
  1020. X
  1021. #ifndef lint
  1022. static
  1023. char rcs_hdr[] = "$Id: mallopt.c,v 1.1 1992/01/24 03:29:07 dvadura Exp $";
  1024. #endif
  1025. X
  1026. int
  1027. mallopt(cmd,value)
  1028. X    int              cmd;
  1029. X    union malloptarg      value;
  1030. {
  1031. X    int              i;
  1032. X    extern int          malloc_checking;
  1033. X    extern char        * malloc_data_start;
  1034. X    extern int          malloc_errfd;
  1035. X    extern int          malloc_fatal_level;
  1036. X    void              malloc_init();
  1037. X    extern int          malloc_warn_level;
  1038. X    register char        * s;
  1039. X
  1040. X    /*
  1041. X      * If not initialized...
  1042. X     */
  1043. X    if( malloc_data_start == (char *) 0)
  1044. X    {
  1045. X        malloc_init();
  1046. X    }
  1047. X
  1048. X
  1049. X    switch(cmd)
  1050. X    {
  1051. X        case MALLOC_WARN:
  1052. X            malloc_warn_level = value.i;
  1053. X            break;
  1054. X
  1055. X        case MALLOC_FATAL:
  1056. X            malloc_fatal_level = value.i;
  1057. X            break;
  1058. X
  1059. X        case MALLOC_CKCHAIN:
  1060. X            malloc_checking = value.i;
  1061. X            break;
  1062. X
  1063. X        case MALLOC_ERRFILE:
  1064. X            
  1065. X            i = open(value.str,O_CREAT|O_APPEND|O_WRONLY,0666);
  1066. X            if( i == -1 )
  1067. X            {
  1068. X                (void) write(2,
  1069. X                      "Unable to open malloc error file: ",
  1070. X                      (unsigned) 34);
  1071. X                for(s=value.str; *s; s++)
  1072. X                {
  1073. X                    /* do nothing */;
  1074. X                }
  1075. X                (void) write(2,value.str,
  1076. X                         (unsigned)(s-value.str));
  1077. X                (void) write(2,"\n",(unsigned)1);
  1078. X            }
  1079. X            else
  1080. X            {
  1081. X                if( malloc_errfd != 2 )
  1082. X                {
  1083. X                    (void) close(malloc_errfd);
  1084. X                }
  1085. X                malloc_errfd = i;
  1086. X            }
  1087. X            
  1088. X            break;
  1089. X
  1090. X        default:
  1091. X            return(1);
  1092. X    }
  1093. X
  1094. X    return(0);
  1095. }
  1096. X
  1097. /*
  1098. X * $Log: mallopt.c,v $
  1099. X * Revision 1.1  1992/01/24  03:29:07  dvadura
  1100. X * dmake Version 3.8, Initial revision
  1101. X *
  1102. X * Revision 1.6  90/08/29  22:23:36  cpcahil
  1103. X * fixed mallopt to use a union as an argument.
  1104. X * 
  1105. X * Revision 1.5  90/08/29  21:22:51  cpcahil
  1106. X * miscellaneous lint fixes
  1107. X * 
  1108. X * Revision 1.4  90/05/11  00:13:10  cpcahil
  1109. X * added copyright statment
  1110. X * 
  1111. X * Revision 1.3  90/02/25  11:03:26  cpcahil
  1112. X * changed to return int so that it agrees with l libmalloc.a's mallopt()
  1113. X * 
  1114. X * Revision 1.2  90/02/25  11:01:21  cpcahil
  1115. X * added support for malloc chain checking.
  1116. X * 
  1117. X * Revision 1.1  90/02/24  21:50:24  cpcahil
  1118. X * Initial revision
  1119. X * 
  1120. X * Revision 1.1  90/02/24  17:10:53  cpcahil
  1121. X * Initial revision
  1122. X * 
  1123. X */
  1124. SHAR_EOF
  1125. chmod 0640 dmake/dbug/malloc/mallopt.c ||
  1126. echo 'restore of dmake/dbug/malloc/mallopt.c failed'
  1127. Wc_c="`wc -c < 'dmake/dbug/malloc/mallopt.c'`"
  1128. test 2372 -eq "$Wc_c" ||
  1129.     echo 'dmake/dbug/malloc/mallopt.c: original size 2372, current size' "$Wc_c"
  1130. rm -f _shar_wnt_.tmp
  1131. fi
  1132. # ============= dmake/dbug/malloc/memory.c ==============
  1133. if test -f 'dmake/dbug/malloc/memory.c' -a X"$1" != X"-c"; then
  1134.     echo 'x - skipping dmake/dbug/malloc/memory.c (File already exists)'
  1135.     rm -f _shar_wnt_.tmp
  1136. else
  1137. > _shar_wnt_.tmp
  1138. sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/memory.c' &&
  1139. /*
  1140. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  1141. X * You may copy, distribute, and use this software as long as this
  1142. X * copyright statement is not removed.
  1143. X */
  1144. X
  1145. #ifndef lint
  1146. static
  1147. char rcs_hdr[] = "$Id: memory.c,v 1.1 1992/01/24 03:29:08 dvadura Exp $";
  1148. #endif
  1149. X
  1150. void malloc_check_data();
  1151. X
  1152. char *
  1153. memccpy(ptr1, ptr2, ch, len)
  1154. X    register char    * ptr1;
  1155. X    register char    * ptr2;
  1156. X    int          len;
  1157. X    int          ch;
  1158. {
  1159. X    int          check;
  1160. X    register int      i;
  1161. X    char        * rtn;
  1162. X
  1163. X    /*
  1164. X     * I know that the assignment could be done in the following, but
  1165. X     * I wanted to perform a check before any assignment, so first I 
  1166. X     * determine the length, check the pointers and then do the assignment.
  1167. X     */
  1168. X    for( i=0; (i < len) && (ptr2[i] != ch); i++)
  1169. X    {
  1170. X    }
  1171. X    if( ptr2[i] == ch )
  1172. X    {
  1173. X        check = i+1;
  1174. X    }
  1175. X    else
  1176. X    {
  1177. X        check = len;
  1178. X    }
  1179. X
  1180. X    malloc_check_data("memccpy", ptr1, check);
  1181. X    malloc_check_data("memccpy", ptr2, check);
  1182. X
  1183. X    /*
  1184. X     * if we found the character...
  1185. X      */
  1186. X
  1187. X    if( i < len )
  1188. X    {
  1189. X        rtn = ptr1+i+1;
  1190. X        i++;
  1191. X    }
  1192. X    else
  1193. X    {
  1194. X        rtn = (char *) 0;
  1195. X    }
  1196. X
  1197. X     while( i-- )
  1198. X    {
  1199. X        *(ptr1++) = *(ptr2++);
  1200. X    }
  1201. X    
  1202. X    return(rtn);
  1203. }
  1204. X
  1205. char *
  1206. memchr(ptr1,ch,len)
  1207. X    register char    * ptr1;
  1208. X    register int      ch;
  1209. X    int          len;
  1210. {
  1211. X    int          i;
  1212. X
  1213. X    for( i=0; (i < len) && (ptr1[i] != (char) ch); i++)
  1214. X    {
  1215. X    }
  1216. X
  1217. X    malloc_check_data("memchr", ptr1, i);
  1218. X
  1219. X    if( i < len )
  1220. X    {
  1221. X        return( ptr1+i );
  1222. X    }
  1223. X    else
  1224. X    {
  1225. X        return( (char *) 0);    
  1226. X    }
  1227. }
  1228. X
  1229. char *
  1230. memcpy(ptr1, ptr2, len)
  1231. X    register char    * ptr1;
  1232. X    register char    * ptr2;
  1233. X    register int      len;
  1234. {
  1235. X    char        * rtn = ptr1;
  1236. X
  1237. X    malloc_check_data("memcpy", ptr1, len);
  1238. X    malloc_check_data("memcpy", ptr2, len);
  1239. X
  1240. X    /*
  1241. X     * while the normal memcpy does not guarrantee that it will 
  1242. X     * handle overlapping memory correctly, we will try...
  1243. X     */
  1244. X    if( ptr1 > ptr2  && ptr1 < (ptr2+len))
  1245. X    {
  1246. X        ptr1 += (len-1);
  1247. X        ptr2 += (len-1);
  1248. X        while( len-- > 0 )
  1249. X        {
  1250. X            *(ptr1--) = *(ptr2--);
  1251. X        }
  1252. X    }
  1253. X    else
  1254. X    {
  1255. X        while( len-- > 0 )
  1256. X        {
  1257. X            *(ptr1++) = *(ptr2++);
  1258. X        }
  1259. X    }
  1260. X    
  1261. X    return(rtn);
  1262. }
  1263. X
  1264. int
  1265. memcmp(ptr1, ptr2, len)
  1266. X    register char    * ptr1;
  1267. X    register char    * ptr2;
  1268. X    register int      len;
  1269. {
  1270. X    malloc_check_data("memcpy", ptr1, len);
  1271. X    malloc_check_data("memcpy", ptr2, len);
  1272. X
  1273. X    while( --len >= 0  && (*ptr1 == *ptr2) )
  1274. X    {
  1275. X        ptr1++;
  1276. X        ptr2++;
  1277. X    }
  1278. X
  1279. X    /* 
  1280. X     * If stopped by len, return zero
  1281. X     */
  1282. X    if( len < 0 )
  1283. X    {
  1284. X        return(0);
  1285. X    }
  1286. X
  1287. X    return( *ptr1 - *ptr2 );
  1288. }
  1289. X
  1290. char * 
  1291. memset(ptr1, ch, len)
  1292. X    register char    * ptr1;
  1293. X    register int      ch;
  1294. X    register int      len;
  1295. {
  1296. X    char        * rtn = ptr1;
  1297. X
  1298. X    malloc_check_data("memcpy", ptr1, len);
  1299. X
  1300. X    while( len-- )
  1301. X    {
  1302. X        *(ptr1++) = ch;
  1303. X    }
  1304. X
  1305. X    return(rtn);
  1306. }
  1307. X
  1308. char *
  1309. bcopy(ptr2,ptr1,len)
  1310. X    char        * ptr2;
  1311. X    char        * ptr1;
  1312. X    int          len;
  1313. {
  1314. X    return(memcpy(ptr1,ptr2,len));
  1315. }
  1316. X
  1317. char *
  1318. bzero(ptr1,len)
  1319. X    char        * ptr1;
  1320. X    int          len;
  1321. {
  1322. X    return(memset(ptr1,'\0',len));
  1323. }
  1324. X
  1325. int
  1326. bcmp(ptr2, ptr1, len)
  1327. X    char        * ptr1;
  1328. X    char        * ptr2;
  1329. X    int          len;
  1330. {
  1331. X    return( memcmp(ptr1,ptr2,len) );
  1332. }
  1333. X
  1334. /*
  1335. X * $Log: memory.c,v $
  1336. X * Revision 1.1  1992/01/24  03:29:08  dvadura
  1337. X * dmake Version 3.8, Initial revision
  1338. X *
  1339. X * Revision 1.7  90/08/29  21:27:58  cpcahil
  1340. X * fixed value of check in memccpy when character was not found.
  1341. X * 
  1342. X * Revision 1.6  90/07/16  20:06:26  cpcahil
  1343. X * fixed several minor bugs found with Henry Spencer's string/mem tester 
  1344. X * program.
  1345. X * 
  1346. X * 
  1347. X * Revision 1.5  90/05/11  15:39:36  cpcahil
  1348. X * fixed bug in memccpy().
  1349. X * 
  1350. X * Revision 1.4  90/05/11  00:13:10  cpcahil
  1351. X * added copyright statment
  1352. X * 
  1353. X * Revision 1.3  90/02/24  21:50:29  cpcahil
  1354. X * lots of lint fixes
  1355. X * 
  1356. X * Revision 1.2  90/02/24  17:29:41  cpcahil
  1357. X * changed $Header to $Id so full path wouldnt be included as part of rcs 
  1358. X * id string
  1359. X * 
  1360. X * Revision 1.1  90/02/22  23:17:43  cpcahil
  1361. X * Initial revision
  1362. X * 
  1363. X */
  1364. SHAR_EOF
  1365. chmod 0640 dmake/dbug/malloc/memory.c ||
  1366. echo 'restore of dmake/dbug/malloc/memory.c failed'
  1367. Wc_c="`wc -c < 'dmake/dbug/malloc/memory.c'`"
  1368. test 3596 -eq "$Wc_c" ||
  1369.     echo 'dmake/dbug/malloc/memory.c: original size 3596, current size' "$Wc_c"
  1370. rm -f _shar_wnt_.tmp
  1371. fi
  1372. # ============= dmake/dbug/malloc/mlc_chk.c ==============
  1373. if test -f 'dmake/dbug/malloc/mlc_chk.c' -a X"$1" != X"-c"; then
  1374.     echo 'x - skipping dmake/dbug/malloc/mlc_chk.c (File already exists)'
  1375.     rm -f _shar_wnt_.tmp
  1376. else
  1377. > _shar_wnt_.tmp
  1378. sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/mlc_chk.c' &&
  1379. /*
  1380. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  1381. X * You may copy, distribute, and use this software as long as this
  1382. X * copyright statement is not removed.
  1383. X */
  1384. X
  1385. #include <stdio.h>
  1386. #include "malloc.h"
  1387. #include "debug.h"
  1388. X
  1389. #ifndef lint
  1390. static
  1391. char rcs_hdr[] = "$Id: mlc_chk.c,v 1.1 1992/01/24 03:29:09 dvadura Exp $";
  1392. #endif
  1393. X
  1394. extern struct mlist      malloc_start;
  1395. extern struct mlist    * malloc_end;
  1396. extern char        * malloc_data_start;
  1397. extern char        * malloc_data_end;
  1398. X
  1399. /*
  1400. X * Function:    malloc_in_arena()
  1401. X *
  1402. X * Purpose:    to verify address is within malloc arena.
  1403. X *
  1404. X * Arguments:    ptr    - pointer to verify
  1405. X *
  1406. X * Returns:    TRUE    - if pointer is within malloc area
  1407. X *        FALSE    - otherwise
  1408. X *
  1409. X * Narrative:
  1410. X *   IF pointer is >= malloc area start AND <= malloc area end
  1411. X *      return TRUE
  1412. X *   ELSE
  1413. X *      return FALSE
  1414. X *
  1415. X * Mod History:    
  1416. X *   90/01/24    cpcahil        Initial revision.
  1417. X */
  1418. int
  1419. malloc_in_arena(ptr)
  1420. X    char    * ptr;
  1421. {
  1422. X    extern char    * malloc_data_start;
  1423. X    extern char    * malloc_data_end;
  1424. X    int          rtn = 0;
  1425. X
  1426. X    if( ptr >= malloc_data_start && ptr <= malloc_data_end )
  1427. X    {
  1428. X        rtn = 1;
  1429. X    }
  1430. X    
  1431. X    return(rtn);
  1432. }
  1433. X
  1434. /*
  1435. X * Function:    malloc_check_str()
  1436. X *
  1437. X * Arguments:    func    - name of function calling this routine
  1438. X *        str    - pointer to area to check
  1439. X *
  1440. X * Purpose:    to verify that if str is within the malloc arena, the data 
  1441. X *        it points to does not extend beyond the applicable region.
  1442. X *
  1443. X * Returns:    Nothing of any use (function is void).
  1444. X *
  1445. X * Narrative:
  1446. X *   IF pointer is within malloc arena
  1447. X *      determin length of string
  1448. X *      call malloc_verify() to verify data is withing applicable region
  1449. X *   return 
  1450. X *
  1451. X * Mod History:    
  1452. X *   90/01/24    cpcahil        Initial revision.
  1453. X *   90/01/29    cpcahil        Added code to ignore recursive calls.
  1454. X */
  1455. void
  1456. malloc_check_str(func,str)
  1457. X    char        * func;
  1458. X    char        * str;
  1459. {
  1460. X    static int      layers;
  1461. X    register char    * s;
  1462. X
  1463. X    if( (layers++ == 0) &&  malloc_in_arena(str) )
  1464. X    {
  1465. X        for( s=str; *s; s++)
  1466. X        {
  1467. X        }
  1468. X        
  1469. X        malloc_verify(func,str,s-str+1);
  1470. X    }
  1471. X
  1472. X    layers--;
  1473. }
  1474. X
  1475. /*
  1476. X * Function:    malloc_check_strn()
  1477. X *
  1478. X * Arguments:    func    - name of function calling this routine
  1479. X *        str    - pointer to area to check
  1480. X *         len     - max length of string
  1481. X *
  1482. X * Purpose:    to verify that if str is within the malloc arena, the data 
  1483. X *        it points to does not extend beyond the applicable region.
  1484. X *
  1485. X * Returns:    Nothing of any use (function is void).
  1486. X *
  1487. X * Narrative:
  1488. X *   IF pointer is within malloc arena
  1489. X *      determin length of string
  1490. X *      call malloc_verify() to verify data is withing applicable region
  1491. X *   return 
  1492. X *
  1493. X * Mod History:    
  1494. X *   90/01/24    cpcahil        Initial revision.
  1495. X *   90/01/29    cpcahil        Added code to ignore recursive calls.
  1496. X *   90/08/29    cpcahil        added length (for strn* functions)
  1497. X */
  1498. void
  1499. malloc_check_strn(func,str,len)
  1500. X    char        * func;
  1501. X    char        * str;
  1502. X    int          len;
  1503. {
  1504. X    register int      i;
  1505. X    static int      layers;
  1506. X    register char    * s;
  1507. X
  1508. X    if( (layers++ == 0) &&  malloc_in_arena(str) )
  1509. X    {
  1510. X        for( s=str,i=0; (i < len) && *s; s++)
  1511. X        {
  1512. X        }
  1513. X        
  1514. X        malloc_verify(func,str,s-str+1);
  1515. X    }
  1516. X
  1517. X    layers--;
  1518. }
  1519. X
  1520. /*
  1521. X * Function:    malloc_check_data()
  1522. X *
  1523. X * Arguments:    func    - name of function calling this routine
  1524. X *        ptr    - pointer to area to check
  1525. X *        len     - length to verify
  1526. X *
  1527. X * Purpose:    to verify that if ptr is within the malloc arena, the data 
  1528. X *        it points to does not extend beyond the applicable region.
  1529. X *
  1530. X * Returns:    Nothing of any use (function is void).
  1531. X *
  1532. X * Narrative:
  1533. X *   IF pointer is within malloc arena
  1534. X *      call malloc_verify() to verify data is withing applicable region
  1535. X *   return 
  1536. X *
  1537. X * Mod History:    
  1538. X *   90/01/24    cpcahil        Initial revision.
  1539. X *   90/01/29    cpcahil        Added code to ignore recursive calls.
  1540. X */
  1541. void
  1542. malloc_check_data(func,ptr,len)
  1543. X    char        * func;
  1544. X    char        * ptr;
  1545. X    int          len;
  1546. {
  1547. X    static int      layers;
  1548. X
  1549. X    if( layers++ == 0 )
  1550. X    {
  1551. X        DEBUG3(40,"malloc_check_data(%s,0x%x,%d) called...",
  1552. X            func,ptr,len);
  1553. X        if( malloc_in_arena(ptr) )
  1554. X        {
  1555. X            DEBUG0(10,"pointer in malloc arena, verifying...");
  1556. X            malloc_verify(func,ptr,len);
  1557. X        }
  1558. X    }
  1559. X
  1560. X    layers--;
  1561. }
  1562. X
  1563. /*
  1564. X * Function:    malloc_verify()
  1565. X *
  1566. X * Arguments:    func    - name of function calling the malloc check routines
  1567. X *        ptr    - pointer to area to check
  1568. X *        len     - length to verify
  1569. X *
  1570. X * Purpose:    to verify that the data ptr points to does not extend beyond
  1571. X *        the applicable malloc region.  This function is only called 
  1572. X *        if it has been determined that ptr points into the malloc arena.
  1573. X *
  1574. X * Returns:    Nothing of any use (function is void).
  1575. X *
  1576. X * Narrative:
  1577. X *
  1578. X * Mod History:    
  1579. X *   90/01/24    cpcahil        Initial revision.
  1580. X */
  1581. void
  1582. malloc_verify(func,ptr,len)
  1583. X    char        * func;
  1584. X    char        * ptr;
  1585. X    int          len;
  1586. {
  1587. X    extern struct mlist    * malloc_end;
  1588. X    extern int          malloc_errno;
  1589. X    extern struct mlist       malloc_start;
  1590. X    struct mlist        * mptr;
  1591. X    
  1592. X    DEBUG3(40,"malloc_verify(%s,0x%x,%d) called...", func,ptr,len);
  1593. X    /*
  1594. X     * Find the malloc block that includes this pointer
  1595. X     */
  1596. X    mptr = &malloc_start;
  1597. X    while( mptr && 
  1598. X        ! (((char *)mptr < ptr) && ((mptr->data+mptr->s.size) > ptr) ) )
  1599. X    {
  1600. X        mptr = mptr->next;
  1601. X    }
  1602. X
  1603. X    /*
  1604. X     * if ptr was not in a malloc block, it must be part of
  1605. X     *    some direct sbrk() stuff, so just return.
  1606. X     */
  1607. X    if( ! mptr )
  1608. X    {
  1609. X        DEBUG1(10,"ptr (0x%x) not found in malloc search", ptr);
  1610. X        return;
  1611. X    }
  1612. X    
  1613. X    /*
  1614. X      * Now we have a valid malloc block that contains the indicated
  1615. X     * pointer.  We must verify that it is withing the requested block
  1616. X     * size (as opposed to the real block size which is rounded up to
  1617. X     * allow for correct alignment).
  1618. X     */
  1619. X
  1620. X    DEBUG4(60,"Checking  0x%x-0x%x, 0x%x-0x%x",
  1621. X            ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
  1622. X    
  1623. X    if( (ptr < mptr->data) || ((ptr+len) > (mptr->data+mptr->r_size)) )
  1624. X    {
  1625. X        DEBUG4(0,"pointer not within region 0x%x-0x%x, 0x%x-0x%x",
  1626. X            ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
  1627. X
  1628. X        malloc_errno = M_CODE_OUTOF_BOUNDS;
  1629. X        malloc_warning(func);
  1630. X    }
  1631. X
  1632. X    return;
  1633. }
  1634. X
  1635. /*
  1636. X * $Log: mlc_chk.c,v $
  1637. X * Revision 1.1  1992/01/24  03:29:09  dvadura
  1638. X * dmake Version 3.8, Initial revision
  1639. X *
  1640. X * Revision 1.5  90/08/29  22:23:48  cpcahil
  1641. X * added new function to check on strings up to a specified length 
  1642. X * and used it within several strn* functions.
  1643. X * 
  1644. X * Revision 1.4  90/05/11  00:13:09  cpcahil
  1645. X * added copyright statment
  1646. X * 
  1647. X * Revision 1.3  90/02/24  21:50:22  cpcahil
  1648. X * lots of lint fixes
  1649. X * 
  1650. X * Revision 1.2  90/02/24  17:29:38  cpcahil
  1651. X * changed $Header to $Id so full path wouldnt be included as part of rcs 
  1652. X * id string
  1653. X * 
  1654. X * Revision 1.1  90/02/24  14:57:03  cpcahil
  1655. X * Initial revision
  1656. X * 
  1657. X */
  1658. SHAR_EOF
  1659. chmod 0640 dmake/dbug/malloc/mlc_chk.c ||
  1660. echo 'restore of dmake/dbug/malloc/mlc_chk.c failed'
  1661. Wc_c="`wc -c < 'dmake/dbug/malloc/mlc_chk.c'`"
  1662. test 6393 -eq "$Wc_c" ||
  1663.     echo 'dmake/dbug/malloc/mlc_chk.c: original size 6393, current size' "$Wc_c"
  1664. rm -f _shar_wnt_.tmp
  1665. fi
  1666. # ============= dmake/dbug/malloc/mlc_chn.c ==============
  1667. if test -f 'dmake/dbug/malloc/mlc_chn.c' -a X"$1" != X"-c"; then
  1668.     echo 'x - skipping dmake/dbug/malloc/mlc_chn.c (File already exists)'
  1669.     rm -f _shar_wnt_.tmp
  1670. else
  1671. > _shar_wnt_.tmp
  1672. sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/mlc_chn.c' &&
  1673. /*
  1674. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  1675. X * You may copy, distribute, and use this software as long as this
  1676. X * copyright statement is not removed.
  1677. X */
  1678. #include <stdio.h>
  1679. #include <fcntl.h>
  1680. #include "malloc.h"
  1681. X
  1682. /*
  1683. X * Function:    malloc_chain_check()
  1684. X *
  1685. X * Purpose:    to verify malloc chain is intact
  1686. X *
  1687. X * Arguments:    todo    - 0 - just check and return status
  1688. X *              1 - call malloc_warn if error detected
  1689. X *
  1690. X * Returns:    0    - malloc chain intact & no overflows
  1691. X *        other    - problems detected in malloc chain
  1692. X *
  1693. X * Narrative:
  1694. X *
  1695. X * Notes:    If todo is non-zero the malloc_warn function, when called
  1696. X *        may not return (i.e. it may exit)
  1697. X *
  1698. X */
  1699. #ifndef lint
  1700. static
  1701. char rcs_hdr[] = "$Id: mlc_chn.c,v 1.1 1992/01/24 03:29:10 dvadura Exp $";
  1702. #endif
  1703. X
  1704. X
  1705. int
  1706. malloc_chain_check(todo)
  1707. X    int          todo;
  1708. {
  1709. X    char            * func = "malloc_chain_check";
  1710. X    int              i;
  1711. X    extern char        * malloc_data_start;
  1712. X    extern char        * malloc_data_end;
  1713. X    extern struct mlist     * malloc_end;
  1714. X    extern int          malloc_errno;
  1715. X    extern struct mlist      malloc_start;
  1716. X    struct mlist        * oldptr;
  1717. X    struct mlist        * ptr;
  1718. X    int              rtn = 0;
  1719. X
  1720. X    oldptr = &malloc_start;
  1721. X    for(ptr = malloc_start.next; ; ptr = ptr->next)
  1722. X    {
  1723. X        /*
  1724. X         * Since the malloc chain is a forward only chain, any
  1725. X         * pointer that we get should always be positioned in 
  1726. X         * memory following the previous pointer.  If this is not
  1727. X         * so, we must have a corrupted chain.
  1728. X         */
  1729. X        if( ptr )
  1730. X        {
  1731. X            if(ptr < oldptr )
  1732. X            {
  1733. X                malloc_errno = M_CODE_CHAIN_BROKE;
  1734. X                if( todo )
  1735. X                {
  1736. X                    malloc_fatal(func);
  1737. X                }
  1738. X                rtn++;
  1739. X                break;
  1740. X            }
  1741. X            oldptr = ptr;
  1742. X        }
  1743. X        else
  1744. X        {
  1745. X            if( oldptr != malloc_end )
  1746. X            {
  1747. X                /*
  1748. X                 * This should never happen.  If it does, then
  1749. X                 * we got a real problem.
  1750. X                 */
  1751. X                malloc_errno = M_CODE_NO_END;
  1752. X                if( todo )
  1753. X                {
  1754. X                    malloc_fatal(func);
  1755. X                }
  1756. X                rtn++;
  1757. X            }
  1758. X            break;
  1759. X        }
  1760. X        
  1761. X        /*
  1762. X         * verify that ptr is within the malloc region...
  1763. X         * since we started within the malloc chain this should never
  1764. X         * happen.
  1765. X         */
  1766. X
  1767. X        if( ((char *)ptr < malloc_data_start) ||
  1768. X            ((char *)ptr > malloc_data_end) )
  1769. X        {
  1770. X            malloc_errno = M_CODE_BAD_PTR;
  1771. X            if( todo )
  1772. X            {
  1773. X                malloc_fatal(func);
  1774. X            }
  1775. X            rtn++;
  1776. X            break;
  1777. X        }
  1778. X
  1779. X        /* 
  1780. X         * verify magic flag is set
  1781. X         */
  1782. X        
  1783. X        if( (ptr->flag&M_MAGIC) != M_MAGIC )
  1784. X        {
  1785. X            malloc_errno = M_CODE_BAD_MAGIC;
  1786. X            if( todo )
  1787. X            {
  1788. X                malloc_warning(func);
  1789. X            }
  1790. SHAR_EOF
  1791. true || echo 'restore of dmake/dbug/malloc/mlc_chn.c failed'
  1792. fi
  1793. echo 'End of part 5, continue with part 6'
  1794. echo 6 > _shar_seq_.tmp
  1795. exit 0
  1796. exit 0 # Just in case...
  1797.