home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume19 / dmake / part05 < prev    next >
Encoding:
Text File  |  1991-05-10  |  40.2 KB  |  1,658 lines

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