home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i112: Debugging malloc() library, Part01/02
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: e80a5aa3 4d17bf71 233d6222 ad37b7d8
-
- Submitted-by: "Conor P. Cahill" <virtech!cpcahil@uunet.uu.net>
- Posting-number: Volume 22, Issue 112
- Archive-name: debug_malloc/part01
-
- This package is a collection of routines which are a drop-in replacement
- for the malloc(3), memory(3), string(3), and bstring(3) library functions.
-
- To use these functions all you need to do is compile the library and
- include it on your loader command line. You do not need to recompile
- your code, only a relink is necessary.
-
- Features of this library include:
- 1. The malloced area returned from each call to malloc is filled with
- non-null bytes.
- 2. When free is called numerous validity checks are made on the
- pointer it is passed. In addition, the data in the malloc block
- beyound the size requested on the initial malloc is checked to
- verify that it is still filled with the original fill characters.
- And finally, the freed block is filled with a different fill pattern
- 3. Whenever a bstring(3)/string(3)/memory(3) function is called, it's
- parameters are checked.
- 4. The operations to perform when an error is detected are specified at
- run time by the use of environment variables.
-
- This code is already at patchlevel 1.
-
- Conor.
-
- Submitted-by: cpcahil@virtech
- Archive-name: Malloclib/part01
-
- #!/bin/sh
- # This is Malloclib, a shell archive (shar 3.21)
- # made 06/21/1990 14:37 UTC by cpcahil@virtech
- # Source directory /usr/local/src/lib/malloclib
- #
- # existing files will NOT be overwritten
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 1138 -r--r--r-- Makefile
- # 4758 -rw-rw-r-- README
- # 2 -rw-rw-rw- patchlevel
- # 1481 -r--r--r-- calloc.c
- # 2628 -r--r--r-- debug.h
- # 3097 -r--r--r-- dump.c
- # 4379 -r--r--r-- free.c
- # 1751 -r--r--r-- m_init.c
- # 1776 -r--r--r-- m_perror.c
- # 6694 -r--r--r-- malloc.3
- # 12756 -r--r--r-- malloc.c
- # 2346 -r--r--r-- malloc.h
- # 5125 -r--r--r-- malloc_chk.c
- # 3449 -r--r--r-- malloc_chn.c
- # 2128 -r--r--r-- mallopt.c
- # 2817 -r--r--r-- memory.c
- # 4496 -r--r--r-- realloc.c
- # 8521 -r--r--r-- string.c
- # 3971 -r--r--r-- testmalloc.c
- # 2552 -r--r--r-- testmem.c
- # 2716 -r--r--r-- tostring.c
- # 491 -r--r--r-- tostring.h
- #
- if touch 2>&1 | fgrep '[-amc]' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= Makefile ==============
- if test X"$1" != X"-c" -a -f 'Makefile'; then
- echo "File already exists: skipping 'Makefile'"
- else
- echo "x - extracting Makefile (Text)"
- sed 's/^X//' << 'SHAR_EOF' > Makefile &&
- X#
- X# (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
- X# You may copy, distribute, and use this software as long as this
- X# copyright statement is not removed.
- X#
- X#
- X# This is the Makefile for the malloc debugging library
- X#
- X# $Id: Makefile,v 1.3 90/06/21 10:37:06 cpcahil Exp $
- X#
- XCC=cc
- X# for System V systems use this CFLAGS
- XCFLAGS=-g -DSYS5
- X# else for BSD use:
- X#CFLAGS=-g
- XSHARCMD=shar -o mallocshar -l50 -x -a -n Malloclib
- X
- XLIB=libmalloc.a
- X
- XOBJS= malloc.o \
- X free.o \
- X realloc.o \
- X calloc.o \
- X string.o \
- X malloc_chk.o \
- X malloc_chn.o \
- X memory.o \
- X tostring.o \
- X m_perror.o \
- X m_init.o \
- X mallopt.o \
- X dump.o
- X
- XTESTS=testmalloc testmem
- X
- Xall: $(LIB) $(TESTS)
- X
- Xclean:
- X rm -f $(TESTS) pgm $(LIB) *.o *.ln
- X
- Xsharfile:
- X $(SHARCMD) Makefile README patchlevel *.[ch3]
- X
- X$(LIB): $(OBJS)
- X ar -ru $(LIB) $(OBJS)
- X -if test -s /bin/ranlib; then /bin/ranlib $(LIB); else exit 0; fi
- X -if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(LIB); else exit 0; fi
- X
- Xtestmalloc: $(LIB) testmalloc.o
- X $(CC) -o $@ testmalloc.o $(LIB)
- X
- Xtestmem: $(LIB) testmem.o
- X $(CC) -o $@ testmem.o $(LIB)
- X
- X$(OBJS): malloc.h
- X
- Xtostring.o malloc.o dump.o: tostring.h
- SHAR_EOF
- $TOUCH -am 0621103790 Makefile &&
- chmod 0444 Makefile ||
- echo "restore of Makefile failed"
- set `wc -c Makefile`;Wc_c=$1
- if test "$Wc_c" != "1138"; then
- echo original size 1138, current size $Wc_c
- fi
- fi
- # ============= README ==============
- if test X"$1" != X"-c" -a -f 'README'; then
- echo "File already exists: skipping 'README'"
- else
- echo "x - extracting README (Text)"
- sed 's/^X//' << 'SHAR_EOF' > README &&
- X# (c) Copyright 1990 Conor P. Cahill. (uunet!virtech!cpcahil)
- X# You may copy, distribute, and use this software as long as this
- X# copyright statement is not removed.
- X
- XThis package is a collection of routines which are a drop-in replacement
- Xfor the malloc(3), memory(3), string(3), and bstring(3) library functions.
- X
- XThe purpose of these programs is to aid the development and/or debugging
- Xof programs using these functions by providing a high level of consistancy
- Xchecking whenever a malloc pointer is used. Due to this increased
- Xlevel of consistancy checking, these functions have a considerably larger
- Xoverhead than the standard functions, but the extra checking should be
- Xwell worth it in a development environment.
- X
- XTo use these functions all you need to do is compile the library and
- Xinclude it on your loader command line. You do not need to recompile
- Xyour code, only a relink is necessary.
- X
- XFeatures of this library:
- X
- X 1. The malloced area returned from each call to malloc is filled with
- X non-null bytes. This should catch any use of uninitialized malloc
- X area. The fill pattern for malloced area is 0x01.
- X
- X 2. When free is called numerous validity checks are made on the
- X pointer it is passed. In addition, the data in the malloc block
- X beyound the size requested on the initial malloc is checked to
- X verify that it is still filled with the original fill characters.
- X
- X This is usefull for catching things like:
- X
- X ptr = malloc(5);
- X ptr[5] = '\0';
- X
- X /*
- X * You should not that this will be caught when it is
- X * freed not when it is done
- X */
- X
- X And finally, the freed block is filled with a different fill pattern
- X so that you can easily determine if you are still using free'd space.
- X The fill pattern for free'd areas is 0x02.
- X
- X This is usefull for catching things like:
- X
- X ptr = malloc(20);
- X
- X bptr = ptr+10;
- X
- X /* do something usefule with bptr */
- X
- X free(ptr);
- X
- X /*
- X * now try to do something useful with bptr, it should
- X * be trashed enough that it would cause real problems
- X * and when you went to debug the problem it would be
- X * filled with 0x02's and you would then know to look
- X * for something free'ing what bptr points to.
- X */
- X
- X
- X 3. Whenever a bstring(3)/string(3)/memory(3) function is called, it's
- X parameters are checked as follows:
- X
- X If they point somewhere in the malloc arena
- X If the operation goes beyond requested malloc space
- X call malloc_warning()
- X
- X This is usefull for catching things like:
- X
- X ptr = malloc(5);
- X strcpy(ptr,"abcde");
- X
- X
- X 4. Malloc_warning() and malloc_fatal() are used when an error condition
- X is detected. If the error is severe, malloc_fatal is called.
- X Malloc_warning is used otherwise. The decision about what is fatal
- X and what is a warning was made somewhat arbitrarily.
- X
- X Warning messages include:
- X
- X Calling free with a bad pointer
- X Calling a bstring/string/memory (3) function which will go beyond
- X the end of a malloc block (Note that the library function is
- X not modified to refuse the operation. If malloc warnings are
- X in the default IGNORE case, the operation will continue and
- X at some point cause a real problem).
- X
- X Fatal errors are:
- X
- X Detectable corruption to the malloc chain.
- X
- X
- X 5. The operations to perform when an error is detected are specified at
- X run time by the use of environment variables.
- X
- X MALLOC_WARN - specifies the warning error message handling
- X MALLOC_FATAL - specifies the fatal error handling
- X
- X
- X When one of these error conditions occur you will get an error
- X message and the handler will execute based upon what setting
- X is in the environment variables. Currently understood settings
- X are as follows:
- X
- X 0 - continue operations
- X 1 - drop core and exit
- X 2 - just exit
- X 3 - drop core, but continue executing. Core files will
- X be placed into core.[PID].[counter] i.e: core.00123.001
- X 128 - dump malloc chain and continue
- X 129 - dump malloc chain, dump core, and exit
- X 130 - dump malloc chain, exit
- X 131 - dump malloc chain, dump core, continue processing
- X
- X
- X There is an additional environment variable MALLOC_ERRFILE which
- X is used to indicate the name of the file for error message output.
- X
- X For example, to set up the session to generate a core file for
- X every malloc warning, to drop core and exit on a malloc fatal, and
- X to log all messages to the file "malloc_log" do the following:
- X
- X MALLOC_WARN=131
- X MALLOC_FATAL=1
- X MALLOC_ERRFILE=malloc_log
- X
- X export MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE
- X
- X 6. The function malloc_dump() is available to dump the malloc chain whenever
- X you might want. It's only argument is a file descriptor to use to write
- X the data. Review the code if you need to know what data is printed.
- SHAR_EOF
- $TOUCH -am 0511001190 README &&
- chmod 0664 README ||
- echo "restore of README failed"
- set `wc -c README`;Wc_c=$1
- if test "$Wc_c" != "4758"; then
- echo original size 4758, current size $Wc_c
- fi
- fi
- # ============= patchlevel ==============
- if test X"$1" != X"-c" -a -f 'patchlevel'; then
- echo "File already exists: skipping 'patchlevel'"
- else
- echo "x - extracting patchlevel (Text)"
- sed 's/^X//' << 'SHAR_EOF' > patchlevel &&
- X1
- SHAR_EOF
- $TOUCH -am 0621103390 patchlevel &&
- chmod 0666 patchlevel ||
- echo "restore of patchlevel failed"
- set `wc -c patchlevel`;Wc_c=$1
- if test "$Wc_c" != "2"; then
- echo original size 2, current size $Wc_c
- fi
- fi
- # ============= calloc.c ==============
- if test X"$1" != X"-c" -a -f 'calloc.c'; then
- echo "File already exists: skipping 'calloc.c'"
- else
- echo "x - extracting calloc.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > calloc.c &&
- X/*
- X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
- X * You may copy, distribute, and use this software as long as this
- X * copyright statement is not removed.
- X */
- X#include <stdio.h>
- X
- X/*
- X * Function: calloc()
- X *
- X * Purpose: to allocate and nullify a data area
- X *
- X * Arguments: nelem - number of elements
- X * elsize - size of each element
- X *
- X * Returns: NULL - if malloc fails
- X * or pointer to allocated space
- X *
- X * Narrative: determine size of area to malloc
- X * malloc area.
- X * if malloc succeeds
- X * fill area with nulls
- X * return ptr to malloc'd region
- X */
- X#ifndef lint
- Xstatic char rcs_header[] = "$Id: calloc.c,v 1.6 90/05/11 00:13:07 cpcahil Exp $";
- X#endif
- X
- Xchar *
- Xcalloc(nelem,elsize)
- X unsigned int nelem;
- X unsigned int elsize;
- X{
- X char * malloc();
- X char * memset();
- X char * ptr;
- X unsigned int size;
- X
- X size = elsize * nelem;
- X
- X if( (ptr = malloc(size)) != NULL)
- X {
- X (void) memset(ptr,'\0',(int)size);
- X }
- X
- X return(ptr);
- X}
- X
- X
- X/*
- X * $Log: calloc.c,v $
- X * Revision 1.6 90/05/11 00:13:07 cpcahil
- X * added copyright statment
- X *
- X * Revision 1.5 90/02/24 20:41:57 cpcahil
- X * lint changes.
- X *
- X * Revision 1.4 90/02/24 17:25:47 cpcahil
- X * changed $header to $id so full path isn't included.
- X *
- X * Revision 1.3 90/02/24 13:32:24 cpcahil
- X * added function header. moved log to end of file.
- X *
- X * Revision 1.2 90/02/22 23:08:26 cpcahil
- X * fixed rcs_header line
- X *
- X * Revision 1.1 90/02/22 23:07:38 cpcahil
- X * Initial revision
- X *
- X */
- SHAR_EOF
- $TOUCH -am 0511001490 calloc.c &&
- chmod 0444 calloc.c ||
- echo "restore of calloc.c failed"
- set `wc -c calloc.c`;Wc_c=$1
- if test "$Wc_c" != "1481"; then
- echo original size 1481, current size $Wc_c
- fi
- fi
- # ============= debug.h ==============
- if test X"$1" != X"-c" -a -f 'debug.h'; then
- echo "File already exists: skipping 'debug.h'"
- else
- echo "x - extracting debug.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > debug.h &&
- X/*
- X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
- X * You may copy, distribute, and use this software as long as this
- X * copyright statement is not removed.
- X */
- X/************************************************************************/
- X/* */
- X/* this include sets up some macro functions which can be used while */
- X/* debugging the program, and then left in the code, but turned of by */
- X/* just not defining "DEBUG". This way your production version of */
- X/* the program will not be filled with bunches of debugging junk */
- X/* */
- X/************************************************************************/
- X/*
- X * $Id: debug.h,v 1.2 90/05/11 00:13:08 cpcahil Exp $
- X */
- X
- X#ifdef DEBUG
- X
- X#if DEBUG == 1 /* if default level */
- X#undef DEBUG
- X#define DEBUG 100 /* use level 100 */
- X#endif
- X
- X#include <stdio.h>
- X
- X#define DEBUG0(val,str)\
- X {\
- X if( DEBUG > val ) \
- X fprintf(stderr,"%s(%d): %s\n",\
- X __FILE__,__LINE__,str);\
- X }
- X#define DEBUG1(val,str,a1)\
- X {\
- X char _debugbuf[100];\
- X if( DEBUG > val )\
- X {\
- X sprintf(_debugbuf,str,a1);\
- X fprintf(stderr,"%s(%d): %s\n",\
- X __FILE__,__LINE__,_debugbuf);\
- X }\
- X }
- X
- X#define DEBUG2(val,str,a1,a2)\
- X {\
- X char _debugbuf[100];\
- X if( DEBUG > val )\
- X {\
- X sprintf(_debugbuf,str,a1,a2);\
- X fprintf(stderr,"%s(%d): %s\n",\
- X __FILE__,__LINE__,_debugbuf);\
- X }\
- X }
- X
- X#define DEBUG3(val,str,a1,a2,a3)\
- X {\
- X char _debugbuf[100];\
- X if( DEBUG > val )\
- X {\
- X sprintf(_debugbuf,str,a1,a2,a3);\
- X fprintf(stderr,"%s(%d): %s\n",\
- X __FILE__,__LINE__,_debugbuf);\
- X }\
- X }
- X
- X#define DEBUG4(val,str,a1,a2,a3,a4)\
- X {\
- X char _debugbuf[100];\
- X if( DEBUG > val )\
- X {\
- X sprintf(_debugbuf,str,a1,a2,a3,a4);\
- X fprintf(stderr,"%s(%d): %s\n",\
- X __FILE__,__LINE__,_debugbuf);\
- X }\
- X }
- X
- X#define DEBUG5(val,str,a1,a2,a3,a4,a5)\
- X {\
- X char _debugbuf[100];\
- X if( DEBUG > val )\
- X {\
- X sprintf(_debugbuf,str,a1,a2,a3,a4,a5);\
- X fprintf(stderr,"%s(%d): %s\n",\
- X __FILE__,__LINE__,_debugbuf);\
- X }\
- X }
- X
- X#else
- X
- X#define DEBUG0(val,s)
- X#define DEBUG1(val,s,a1)
- X#define DEBUG2(val,s,a1,a2)
- X#define DEBUG3(val,s,a1,a2,a3)
- X#define DEBUG4(val,s,a1,a2,a3,a4)
- X#define DEBUG5(val,s,a1,a2,a3,a4,a5)
- X
- X#endif /* DEBUG */
- X
- X
- X/*
- X * $Log: debug.h,v $
- X * Revision 1.2 90/05/11 00:13:08 cpcahil
- X * added copyright statment
- X *
- X * Revision 1.1 90/02/23 07:09:01 cpcahil
- X * Initial revision
- X *
- X */
- SHAR_EOF
- $TOUCH -am 0511001490 debug.h &&
- chmod 0444 debug.h ||
- echo "restore of debug.h failed"
- set `wc -c debug.h`;Wc_c=$1
- if test "$Wc_c" != "2628"; then
- echo original size 2628, current size $Wc_c
- fi
- fi
- # ============= dump.c ==============
- if test X"$1" != X"-c" -a -f 'dump.c'; then
- echo "File already exists: skipping 'dump.c'"
- else
- echo "x - extracting dump.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > dump.c &&
- X/*
- X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
- X * You may copy, distribute, and use this software as long as this
- X * copyright statement is not removed.
- X */
- X#include <stdio.h>
- X#include "malloc.h"
- X#include "tostring.h"
- X
- X/*
- X * Function: malloc_dump()
- X *
- X * Purpose: to dump a printed copy of the malloc chain and
- X * associated data elements
- X *
- X * Arguments: fd - file descriptor to write data to
- X *
- X * Returns: nothing of any use
- X *
- X * Narrative: Just print out all the junk
- X *
- X * Notes: This function is implemented using low level calls because
- X * of the likelyhood that the malloc tree is damaged when it
- X * is called. (Lots of things in the c library use malloc and
- X * we don't want to get into a catch-22).
- X *
- X */
- X
- X#ifndef lint
- Xstatic
- Xchar rcs_hdr[] = "$Id: dump.c,v 1.4 90/05/11 00:13:08 cpcahil Exp $";
- X#endif
- X
- X
- X#define ERRSTR "I/O Error on malloc dump file descriptor\n"
- X
- X#define WRITEOUT(fd,str,len) if( write(fd,str,(unsigned)len) != len ) \
- X { \
- X (void) write(2,ERRSTR,\
- X (unsigned)strlen(ERRSTR));\
- X exit(120); \
- X }
- X
- Xmalloc_dump(fd)
- X int fd;
- X{
- X char buffer[512];
- X void exit();
- X int i;
- X extern char * malloc_data_end;
- X extern char * malloc_data_start;
- X extern struct mlist * malloc_end;
- X extern struct mlist malloc_start;
- X struct mlist * ptr;
- X
- X WRITEOUT(fd,"MALLOC CHAIN:\n",14);
- X WRITEOUT(fd,"-------------------- START ----------------\n",44);
- X
- X for(i=0; i < 80; i++)
- X {
- X buffer[i] = ' ';
- X }
- X
- X for(ptr = &malloc_start; ptr; ptr = ptr->next)
- X {
- X (void) tostring(buffer, (int)ptr, 8, B_HEX, '0');
- X (void) tostring(buffer+9, (int)ptr->next, 8, B_HEX, '0');
- X (void) tostring(buffer+18, (int)ptr->prev, 8, B_HEX, '0');
- X (void) tostring(buffer+27, (int)ptr->flag, 10, B_HEX, '0');
- X (void) tostring(buffer+38, (int)ptr->s.size, 8, B_DEC, ' ');
- X (void) tostring(buffer+47, (int)ptr->s.size, 8, B_HEX, '0');
- X (void) tostring(buffer+57, (int)ptr->data, 8, B_HEX, '0');
- X buffer[46] = '(';
- X buffer[55] = ')';
- X buffer[65] = '\n';
- X WRITEOUT(fd,buffer,66);
- X }
- X WRITEOUT(fd,"-------------------- DONE -----------------\n",44);
- X
- X WRITEOUT(fd,"Malloc start: ",19);
- X (void) tostring(buffer, (int) &malloc_start, 8, B_HEX, '0');
- X buffer[8] = '\n';
- X WRITEOUT(fd,buffer,9);
- X
- X WRITEOUT(fd,"Malloc end: ", 19);
- X (void) tostring(buffer, (int) malloc_end, 8, B_HEX, '0');
- X buffer[8] = '\n';
- X WRITEOUT(fd,buffer,9);
- X
- X WRITEOUT(fd,"Malloc data start: ", 19);
- X (void) tostring(buffer, (int) malloc_data_start, 8, B_HEX, '0');
- X buffer[8] = '\n';
- X WRITEOUT(fd,buffer,9);
- X
- X WRITEOUT(fd,"Malloc data end: ", 19);
- X (void) tostring(buffer, (int) malloc_data_end, 8, B_HEX, '0');
- X buffer[8] = '\n';
- X WRITEOUT(fd,buffer,9);
- X
- X} /* malloc_dump(... */
- X
- X
- X/*
- X * $Log: dump.c,v $
- X * Revision 1.4 90/05/11 00:13:08 cpcahil
- X * added copyright statment
- X *
- X * Revision 1.3 90/02/24 21:50:07 cpcahil
- X * lots of lint fixes
- X *
- X * Revision 1.2 90/02/24 17:27:48 cpcahil
- X * changed $header to $Id to remove full path from rcs id string
- X *
- X * Revision 1.1 90/02/22 23:17:43 cpcahil
- X * Initial revision
- X *
- X */
- SHAR_EOF
- $TOUCH -am 0511001490 dump.c &&
- chmod 0444 dump.c ||
- echo "restore of dump.c failed"
- set `wc -c dump.c`;Wc_c=$1
- if test "$Wc_c" != "3097"; then
- echo original size 3097, current size $Wc_c
- fi
- fi
- # ============= free.c ==============
- if test X"$1" != X"-c" -a -f 'free.c'; then
- echo "File already exists: skipping 'free.c'"
- else
- echo "x - extracting free.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > free.c &&
- X/*
- X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
- X * You may copy, distribute, and use this software as long as this
- X * copyright statement is not removed.
- X */
- X#include <stdio.h>
- X#include "malloc.h"
- X#include "debug.h"
- X
- X/*
- X * Function: free()
- X *
- X * Purpose: to deallocate malloced data
- X *
- X * Arguments: ptr - pointer to data area to deallocate
- X *
- X * Returns: nothing of any value
- X *
- X * Narrative:
- X * verify pointer is within malloc region
- X * get mlist pointer from passed address
- X * verify magic number
- X * verify inuse flag
- X * verify pointer connections with surrounding segments
- X * turn off inuse flag
- X * verify no data overrun into non-malloced area at end of segment
- X * IF possible join segment with next segment
- X * IF possible join segment with previous segment
- X * Clear all data in segment (to make sure it isn't reused)
- X *
- X */
- X#ifndef lint
- Xstatic
- Xchar rcs_hdr[] = "$Id: free.c,v 1.8 90/05/11 00:13:08 cpcahil Exp $";
- X#endif
- X
- Xvoid
- Xfree(cptr)
- X char * cptr;
- X{
- X char * func = "free";
- X int i;
- X extern int malloc_checking;
- X extern struct mlist * malloc_end;
- X extern int malloc_errno;
- X extern char * malloc_data_end;
- X extern char * malloc_data_start;
- X struct mlist * oldptr;
- X struct mlist * ptr;
- X
- X /*
- X * IF malloc chain checking is on, go do it.
- X */
- X if( malloc_checking )
- X {
- X (void) malloc_chain_check(1);
- X }
- X
- X /*
- X * verify that cptr is within the malloc region...
- X */
- X if( cptr < malloc_data_start || cptr > malloc_data_end )
- X {
- X malloc_errno = M_CODE_BAD_PTR;
- X malloc_warning(func);
- X return;
- X }
- X
- X /*
- X * convert pointer to mlist struct pointer. To do this we must
- X * move the pointer backwards the correct number of bytes...
- X */
- X
- X ptr = (struct mlist *) (cptr - M_SIZE);
- X
- X if( (ptr->flag&M_MAGIC) != M_MAGIC )
- X {
- X malloc_errno = M_CODE_BAD_MAGIC;
- X malloc_warning(func);
- X return;
- X }
- X
- X if( ! (ptr->flag & M_INUSE) )
- X {
- X malloc_errno = M_CODE_NOT_INUSE;
- X malloc_warning(func);
- X return;
- X }
- X
- X if( (ptr->prev && (ptr->prev->next != ptr) ) ||
- X (ptr->next && (ptr->next->prev != ptr) ) ||
- X ((ptr->next == NULL) && (ptr->prev == NULL)) )
- X {
- X malloc_errno = M_CODE_BAD_CONNECT;
- X malloc_warning(func);
- X return;
- X }
- X
- X ptr->flag &= ~M_INUSE;
- X
- X /*
- X * verify that the user did not overrun the requested number of bytes.
- X */
- X for(i=ptr->r_size; i < ptr->s.size; i++)
- X {
- X if( ptr->data[i] != M_FILL )
- X {
- X malloc_errno = M_CODE_OVERRUN;
- X malloc_warning(func);
- X break;
- X }
- X }
- X
- X DEBUG3(10,"pointers: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x",
- X ptr->prev, ptr, ptr->next);
- X
- X DEBUG3(10,"size: prev: %9d, ptr: %9d, next: %9d",
- X ptr->prev->s.size, ptr->s.size, ptr->next->s.size);
- X
- X DEBUG3(10,"flags: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x",
- X ptr->prev->flag, ptr->flag, ptr->next->flag);
- X
- X /*
- X * check to see if this block can be combined with the next and/or
- X * previous block. Since it may be joined with the previous block
- X * we will save a pointer to the previous block and test to verify
- X * if it is joined (it's next ptr will no longer point to ptr).
- X */
- X malloc_join(ptr,ptr->next,0,0);
- X
- X oldptr = ptr->prev;
- X
- X malloc_join(ptr->prev, ptr,0,0);
- X
- X if( oldptr->next != ptr )
- X {
- X DEBUG0(10,"Oldptr was changed");
- X ptr = oldptr;
- X }
- X
- X /*
- X * fill this block with '\02's to ensure that nobody is using a
- X * pointer to already freed data...
- X */
- X malloc_memset(ptr->data,M_FREE_FILL,ptr->s.size);
- X
- X}
- X
- X/*
- X * $Log: free.c,v $
- X * Revision 1.8 90/05/11 00:13:08 cpcahil
- X * added copyright statment
- X *
- X * Revision 1.7 90/02/25 11:00:18 cpcahil
- X * added support for malloc chain checking.
- X *
- X * Revision 1.6 90/02/24 21:50:18 cpcahil
- X * lots of lint fixes
- X *
- X * Revision 1.5 90/02/24 17:29:13 cpcahil
- X * changed $Header to $Id so full path wouldnt be included as part of rcs
- X * id string
- X *
- X * Revision 1.4 90/02/24 15:15:32 cpcahil
- X * 1. changed ALREADY_FREE errno to NOT_INUSE so that the same errno could
- X * be used by both free and realloc (since it was the same error).
- X * 2. fixed coding bug
- X *
- X * Revision 1.3 90/02/24 14:23:45 cpcahil
- X * fixed malloc_warning calls
- X *
- X * Revision 1.2 90/02/24 13:59:10 cpcahil
- X * added function header.
- X * Modified calls to malloc_warning/malloc_fatal to use new code error messages
- X * Added support for malloc_errno setting of error codes.
- X *
- X * Revision 1.1 90/02/22 23:17:43 cpcahil
- X * Initial revision
- X *
- X */
- SHAR_EOF
- $TOUCH -am 0511001490 free.c &&
- chmod 0444 free.c ||
- echo "restore of free.c failed"
- set `wc -c free.c`;Wc_c=$1
- if test "$Wc_c" != "4379"; then
- echo original size 4379, current size $Wc_c
- fi
- fi
- # ============= m_init.c ==============
- if test X"$1" != X"-c" -a -f 'm_init.c'; then
- echo "File already exists: skipping 'm_init.c'"
- else
- echo "x - extracting m_init.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > m_init.c &&
- X/*
- X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
- X * You may copy, distribute, and use this software as long as this
- X * copyright statement is not removed.
- X */
- X#include <stdio.h>
- X#include "malloc.h"
- X
- X/*
- X * Function: malloc_init()
- X *
- X * Purpose: to initialize the pointers and variables use by the
- X * malloc() debugging library
- X *
- X * Arguments: none
- X *
- X * Returns: nothing of any value
- X *
- X * Narrative: Just initialize all the needed variables. Use mallopt
- X * to set options taken from the environment.
- X *
- X */
- X#ifndef lint
- Xstatic
- Xchar rcs_hdr[] = "$Id: m_init.c,v 1.4 90/05/11 15:53:35 cpcahil Exp $";
- X#endif
- X
- Xvoid
- Xmalloc_init()
- X{
- X char * cptr;
- X char * getenv();
- X extern char * malloc_data_end;
- X extern char * malloc_data_start;
- X extern struct mlist * malloc_end;
- X extern struct mlist malloc_start;
- X char * sbrk();
- X
- X /*
- X * If already initialized...
- X */
- X if( malloc_data_start != (char *) 0)
- X {
- X return;
- X }
- X
- X
- X malloc_data_start = sbrk(0);
- X malloc_data_end = malloc_data_start;
- X malloc_start.s.size = 0;
- X malloc_end = &malloc_start;
- X
- X if( (cptr=getenv("MALLOC_WARN")) != NULL )
- X {
- X mallopt(MALLOC_WARN,atoi(cptr));
- X }
- X
- X if( (cptr=getenv("MALLOC_FATAL")) != NULL)
- X {
- X mallopt(MALLOC_FATAL,atoi(cptr));
- X }
- X
- X if( (cptr=getenv("MALLOC_CKCHAIN")) != NULL)
- X {
- X mallopt(MALLOC_CKCHAIN,atoi(cptr));
- X }
- X
- X if( (cptr=getenv("MALLOC_ERRFILE")) != NULL)
- X {
- X mallopt(MALLOC_ERRFILE,cptr);
- X }
- X
- X}
- X
- X/*
- X * $Log: m_init.c,v $
- X * Revision 1.4 90/05/11 15:53:35 cpcahil
- X * fixed bug in initialization code.
- X *
- X * Revision 1.3 90/05/11 00:13:08 cpcahil
- X * added copyright statment
- X *
- X * Revision 1.2 90/02/24 21:50:20 cpcahil
- X * lots of lint fixes
- X *
- X * Revision 1.1 90/02/24 17:10:53 cpcahil
- X * Initial revision
- X *
- X */
- SHAR_EOF
- $TOUCH -am 0511155390 m_init.c &&
- chmod 0444 m_init.c ||
- echo "restore of m_init.c failed"
- set `wc -c m_init.c`;Wc_c=$1
- if test "$Wc_c" != "1751"; then
- echo original size 1751, current size $Wc_c
- fi
- fi
- # ============= m_perror.c ==============
- if test X"$1" != X"-c" -a -f 'm_perror.c'; then
- echo "File already exists: skipping 'm_perror.c'"
- else
- echo "x - extracting m_perror.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > m_perror.c &&
- X/*
- X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
- X * You may copy, distribute, and use this software as long as this
- X * copyright statement is not removed.
- X */
- X
- X#ifndef lint
- Xstatic
- Xchar rcsid[] = "$Id: m_perror.c,v 1.4 90/05/11 00:13:08 cpcahil Exp $";
- X#endif
- X
- X/*
- X * malloc errno error strings...
- X */
- X
- Xchar *malloc_err_strings[] =
- X{
- X "No errors",
- X "Malloc chain is corrupted, pointers out of order",
- X "Malloc chain is corrupted, end before end pointer",
- X "Pointer is not within malloc area",
- X "Malloc region does not have valid magic number in header",
- X "Pointers between this segment and ajoining segments are invalid",
- X "Data has overrun beyond requested number of bytes",
- X "Data in free'd area has been modified",
- X "Data are is not in use (can't be freed or realloced)",
- X "Unable to get additional memory from the system",
- X (char *) 0
- X};
- X
- X/*
- X * Function: malloc_perror()
- X *
- X * Purpose: to print malloc_errno error message
- X *
- X * Arguments: str - string to print with error message
- X *
- X * Returns: nothing of any value
- X *
- X * Narrative:
- X */
- Xvoid
- Xmalloc_perror(str)
- X char * str;
- X{
- X extern int malloc_errno;
- X register char * s;
- X register char * t;
- X
- X if( str && *str)
- X {
- X for(s=str; *s; s++)
- X {
- X /* do nothing */;
- X }
- X
- X (void) write(2,str,(unsigned)(s-str));
- X (void) write(2,": ",(unsigned)2);
- X }
- X
- X t = malloc_err_strings[malloc_errno];
- X
- X for(s=t; *s; s++)
- X {
- X /* do nothing */;
- X }
- X
- X (void) write(2,t,(unsigned)(s-t));
- X
- X (void) write(2,"\n",(unsigned)1);
- X}
- X
- X/*
- X * $Log: m_perror.c,v $
- X * Revision 1.4 90/05/11 00:13:08 cpcahil
- X * added copyright statment
- X *
- X * Revision 1.3 90/02/24 21:50:21 cpcahil
- X * lots of lint fixes
- X *
- X * Revision 1.2 90/02/24 17:39:55 cpcahil
- X * 1. added function header
- X * 2. added rcs id and log strings.
- X *
- X */
- SHAR_EOF
- $TOUCH -am 0511001490 m_perror.c &&
- chmod 0444 m_perror.c ||
- echo "restore of m_perror.c failed"
- set `wc -c m_perror.c`;Wc_c=$1
- if test "$Wc_c" != "1776"; then
- echo original size 1776, current size $Wc_c
- fi
- fi
- # ============= malloc.3 ==============
- if test X"$1" != X"-c" -a -f 'malloc.3'; then
- echo "File already exists: skipping 'malloc.3'"
- else
- echo "x - extracting malloc.3 (Text)"
- sed 's/^X//' << 'SHAR_EOF' > malloc.3 &&
- X.TH MALLOC 3 "" "" "1.0"
- X.ds ]T
- X.\"/*
- X.\" * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
- X.\" * You may copy, distribute, and use this software as long as this
- X.\" * copyright statement is not removed.
- X.\" */
- X.\" $Id: malloc.3,v 1.1 90/05/11 15:53:20 cpcahil Exp $
- X.SH NAME
- Xmalloc \t- debugging malloc library
- X.SH SYNOPSIS
- X.ft B
- X.nf
- X#include <malloc.h>
- X
- Xchar * calloc(nelem,elsize);
- Xvoid free(ptr);
- Xchar * malloc(size);
- Xint malloc_chain_check(flag);
- Xvoid malloc_dump(fd);
- Xint mallopt(cmd,value)
- Xchar * realloc(ptr,size);
- X
- Xint cmd,fd,flag;
- Xunsigned elsize,nelem,size;
- Xchar * ptr;
- Xunion val value;
- X
- X.fi
- X.ft R
- X.SH DESCRIPTION
- XThis malloc library is a replacement for the standard library to be used
- Xduring software development/debugging. See the standard malloc(3) pages
- Xfor more information on the use of the following functions:
- X.nf
- X.in +.5i
- Xcalloc(), free(), malloc(), realloc()
- X.in -.5i
- X.fi
- X.sp
- XThis library differs from the standard malloc library in the
- Xfollowing ways:
- X.P
- X1. Each malloc segment contains a magic number so that free can
- Xverify that the pointer passed points to a valid malloc segment.
- X.P
- X2. Each malloc segment is filled with a non-zero pattern so that code that
- Xdepends upon malloc segments being null will fail.
- X.P
- X3. The size of each segment will be at least 1 byte larger than requested
- Xand the extra bytes will be filled with a non-zero pattern. When free is
- Xcalled, it will verify that you did not go beyond the number of bytes
- Xyou asked for.
- X.P
- X4. When a segment is freed, it will be filled with a different non-zero pattern
- Xto ensure that the program doesn't depend upon the use of already freed data.
- X.P
- X5. Whenever any of the string or memory functions (str*, b*, mem*) are
- Xcalled with a pointer that is within the malloc arena, the operation is
- Xchecked to verify that it does not overrun the malloced segment. A failure
- Xof this check is considered a "warning level error" (described later) and
- Xis handled accordingly.
- X.P
- X7. Run time checking can include verification of the malloc chain at each
- Xand every call to one of the malloc functions or manually by calling the
- Xmalloc_chain_check function.
- X.P
- X6. When a problem is found, the action taken is specified at runtime by
- Xenvironment variables or at compile time by the use of the mallopt()
- Xfunction.
- X.P
- XThere are two arbitrary levels of errors, warning and fatal, that this
- Xlibrary will detect. They are broken down as follows:
- X.P
- X.nf
- X.in +.25i
- XWarning messages include:
- X.sp
- X.in +.5i
- X.ti -.25i
- XCalling free with a bad pointer
- X.br
- X.ti -.25i
- XCalling a bstring/string/memory (3) function which will go beyond
- Xthe end of a malloc block. Note that the library function is
- Xnot modified to refuse the operation.
- X.sp
- X.in -.5i
- XFatal errors are:
- X.in +.5i
- X.ti -.25i
- XDetectable corruption to the malloc chain.
- X.in -.5i
- X.in -.25i
- X.P
- XThe error handling for each level (warning or fatal) are specified using
- Xenvironment variables or mallopt(). The coding for the error handling is
- Xas follows:
- X.sp
- X.nf
- X.in +.5i
- X.ti -.25i
- X 0 - continue operations
- X.ti -.25i
- X 1 - drop core and exit
- X.ti -.25i
- X 2 - just exit
- X.ti -.25i
- X 3 - drop core, but continue executing. Core files will
- Xbe placed into core.[PID].[counter] i.e: core.00123.001
- X.ti -.25i
- X128 - dump malloc chain and continue
- X.ti -.25i
- X129 - dump malloc chain, dump core, and exit
- X.ti -.25i
- X130 - dump malloc chain, exit
- X.ti -.25i
- X131 - dump malloc chain, dump core, continue processing
- X.in -.5i
- X.P
- XIn addition error messages can be placed into an error file.
- X.P
- X\fBmalloc_opt\fP() is used to set the malloc debugging options. The
- Xfollowing options can be set:
- X.br
- X.sp
- X.in +.5i
- XMALLOC_WARN - set the error handling for warning level errors. \fBval\fP is
- Xan integer that can contain any one of the following values:
- X.sp
- X.in +.5i
- XM_HANDLE_IGNORE - ignore error
- X.br
- XM_HANDLE_ABORT - drop core and exit
- X.br
- XM_HANDLE_EXIT - just exit (no core drop)
- X.br
- XM_HANDLE_CORE - drop core, but keep on going
- X.br
- X.in -.5i
- X.sp
- XIn addition, M_HANDLE_DUMP may be or'd in to cause a dump of the current
- Xmalloc chain.
- X.br
- X.sp
- XMALLOC_FATAL - set the error handling for fatal level errors. \fBval\fP is
- Xequivalent to \fBval\fP for MALLOC_WARN.
- X.br
- X.sp
- XMALLOC_ERRFILE - set the destination for malloc error messages. \fBval\fP is
- Xa pointer to a character string containing the name of the file to be used
- Xfor error messages.
- X.br
- X.sp
- XMALLOC_CKCHAIN - set the malloc chain checking flag. If \fBval\fP is
- Xnon-zero, chain checking at every call to malloc is turned on.
- X.br
- X.sp
- XFor example, to set up the session to generate a core file for
- Xevery malloc warning, to drop core and exit on a malloc fatal, and
- Xto log all messages to the file "malloc_log" do the following:
- X.sp
- X.nf
- X.in +.5i
- X#include <malloc.h>
- Xmalloc_opt(MALLOC_WARN,131);
- Xmalloc_opt(MALLOC_FATAL,1);
- Xmalloc_opt(MALLOC_ERRFILE,"malloc_log");
- X.in -.5i
- X.fi
- X.in -.5i
- X.sp
- X\fBmalloc_opt\fP() can be used to set/alter the debugging options at any
- Xtime.
- X.P
- X\fBmalloc_dump\fP() will dump a table of the malloc arena showing all
- Xallocated/freed segments and the first few bytes of data in each segment.
- X\fBfd\fP is the file descriptor to write the data to.
- X.P
- X\fBmalloc_chain_check\fP() will check the status of the malloc arena.
- XIf \fBflag\fP is non-zero, an error found in the chain will cause a
- Xfatal error. \fBmalloc_chain_check\fP() returns zero when there are no
- Xproblems found in the malloc chain, non-zero otherwise.
- X.SH "ENVIRONMENT VARIABLES"
- XEnvironment variables can be used to control error handling, error logging
- Xand malloc chain checking at run time. The following environment variables
- Xare used:
- X.P
- XMALLOC_WARN - specifies the error handling for warning errors
- X.br
- XMALLOC_FATAL - specifies the error handling for fatal errors
- X.br
- XMALLOC_ERRFILE - specifies the error log file for error messages.
- X.br
- XMALLOC_CKCHAIN - if 1, turns on malloc chain checking at every call to any
- Xof the malloc functions.
- X.P
- XFor example, to set up the session to generate a core file for
- Xevery malloc warning, to drop core and exit on a malloc fatal, and
- Xto log all messages to the file "malloc_log" do the following:
- X.sp
- X.nf
- X.in +.5i
- XMALLOC_WARN=131
- XMALLOC_FATAL=1
- XMALLOC_ERRFILE=malloc_log
- X
- Xexport MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE
- X.in -.5i
- X.fi
- X.SH WARNINGS
- XThis malloc library and it's associated string and memory functions are
- Xmuch less efficient than the standard functions due in part to the extra
- Xerror checking. You do not want to use this library when generating a
- Xproduction (i.e. releasable) version of your software. It should only
- Xbe used during development and testing.
- X.SH SEE ALSO
- Xstat(2)
- X.SH AUTHOR
- XConor P. Cahill
- XVirtual Technologies Incorporated
- X.sp
- Xuunet!virtech!cpcahil
- SHAR_EOF
- $TOUCH -am 0511155390 malloc.3 &&
- chmod 0444 malloc.3 ||
- echo "restore of malloc.3 failed"
- set `wc -c malloc.3`;Wc_c=$1
- if test "$Wc_c" != "6694"; then
- echo original size 6694, current size $Wc_c
- fi
- fi
- # ============= malloc.c ==============
- if test X"$1" != X"-c" -a -f 'malloc.c'; then
- echo "File already exists: skipping 'malloc.c'"
- else
- echo "x - extracting malloc.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > malloc.c &&
- X/*
- X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
- X * You may copy, distribute, and use this software as long as this
- X * copyright statement is not removed.
- X */
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include "malloc.h"
- X#include "tostring.h"
- X
- X/*
- X * Function: malloc()
- X *
- X * Purpose: memory allocator
- X *
- X * Arguments: size - size of data area needed
- X *
- X * Returns: pointer to allocated area, or NULL if unable
- X * to allocate addtional data.
- X *
- X * Narrative:
- X *
- X */
- X#ifndef lint
- Xstatic
- Xchar rcs_hdr[] = "$Id: malloc.c,v 1.6 90/05/11 00:13:09 cpcahil Exp $";
- X#endif
- X
- Xint malloc_checking;
- Xchar * malloc_data_start;
- Xchar * malloc_data_end;
- Xstruct mlist * malloc_end;
- Xint malloc_errfd = 2;
- Xint malloc_errno;
- Xint malloc_fatal_level = M_HANDLE_CORE;
- Xstruct mlist malloc_start;
- Xint malloc_warn_level;
- X
- Xchar *
- Xmalloc(size)
- X unsigned int size;
- X{
- X char * func = "malloc";
- X char * getenv();
- X void malloc_fatal();
- X void malloc_init();
- X void malloc_memset();
- X void malloc_split();
- X void malloc_warning();
- X unsigned int need;
- X struct mlist * oldptr;
- X struct mlist * ptr;
- X char * sbrk();
- X
- X /*
- X * If this is the first call to malloc...
- X */
- X if( malloc_data_start == (char *) 0 )
- X {
- X malloc_init();
- X }
- X
- X /*
- X * If malloc chain checking is on, go do it.
- X */
- X if( malloc_checking )
- X {
- X (void) malloc_chain_check(1);
- X }
- X
- X /*
- X * always make sure there is at least on extra byte in the malloc
- X * area so that we can verify that the user does not overrun the
- X * data area.
- X */
- X size++;
- X
- X /*
- X * Now look for a free area of memory of size bytes...
- X */
- X oldptr = NULL;
- X for(ptr = &malloc_start; ; ptr = ptr->next)
- X {
- X /*
- X * Since the malloc chain is a forward only chain, any
- X * pointer that we get should always be positioned in
- X * memory following the previous pointer. If this is not
- X * so, we must have a corrupted chain.
- X */
- X if( ptr )
- X {
- X if(ptr < oldptr )
- X {
- X malloc_errno = M_CODE_CHAIN_BROKE;
- X malloc_fatal(func);
- X return(NULL);
- X }
- X oldptr = ptr;
- X }
- X else if( oldptr != malloc_end )
- X {
- X /*
- X * This should never happen. If it does, then
- X * we got a real problem.
- X */
- X malloc_errno = M_CODE_NO_END;
- X malloc_fatal(func);
- X return(NULL);
- X }
- X
- X
- X /*
- X * if this element is already in use...
- X */
- X if( ptr && ((ptr->flag & M_INUSE) != 0) )
- X {
- X continue;
- X }
- X
- X /*
- X * if there isn't room for this block..
- X */
- X if( ptr && (ptr->s.size < size) )
- X {
- X continue;
- X }
- X
- X /*
- X * If ptr is null, we have run out of memory and must sbrk more
- X */
- X if( ptr == NULL )
- X {
- X need = (size + M_SIZE) * (size > 100*1024 ? 1:2);
- X if( need < M_BLOCKSIZE )
- X {
- X need = M_BLOCKSIZE;
- X }
- X else if( need & (M_BLOCKSIZE-1) )
- X {
- X need &= ~(M_BLOCKSIZE-1);
- X need += M_BLOCKSIZE;
- X }
- X ptr = (struct mlist *) sbrk((int)need);
- X if( ptr == (struct mlist *) -1 )
- X {
- X malloc_errno = M_CODE_NOMORE_MEM;
- X malloc_fatal(func);
- X }
- X malloc_data_end = sbrk((int)0);
- X
- X ptr->prev = oldptr;
- X ptr->next = (struct mlist *) 0;
- X ptr->s.size = need - M_SIZE;
- X ptr->flag = M_MAGIC;
- X
- X oldptr->next = ptr;
- X malloc_end = ptr;
- X
- X
- X } /* if( ptr ==... */
- X
- X /*
- X * Now ptr points to a memory location that can store
- X * this data, so lets go to work.
- X */
- X
- X ptr->r_size = size; /* save requested size */
- X ptr->flag |= M_INUSE;
- X
- X /*
- X * split off unneeded data area in this block, if possible...
- X */
- X malloc_split(ptr);
- X
- X /*
- X * re-adjust the requested size so that it is what the user
- X * actually requested...
- X */
- X
- X ptr->r_size--;
- X
- X /*
- X * just to make sure that noone is misusing malloced
- X * memory without initializing it, lets set it to
- X * all '\01's. We call local_memset() because memset()
- X * may be checking for malloc'd ptrs and this isn't
- X * a malloc'd ptr yet.
- X */
- X malloc_memset(ptr->data,M_FILL,(int)ptr->s.size);
- X
- X return( ptr->data);
- X
- X } /* for(... */
- X
- X} /* malloc(... */
- X
- X/*
- X * Function: malloc_split()
- X *
- X * Purpose: to split a malloc segment if there is enough room at the
- X * end of the segment that isn't being used
- X *
- X * Arguments: ptr - pointer to segment to split
- X *
- X * Returns: nothing of any use.
- X *
- X * Narrative:
- X * get the needed size of the module
- X * round the size up to appropriat boundry
- X * calculate amount of left over space
- X * if there is enough left over space
- X * create new malloc block out of remainder
- X * if next block is free
- X * join the two blocks together
- X * fill new empty block with free space filler
- X * re-adjust pointers and size of current malloc block
- X *
- X *
- X *
- X * Mod History:
- X * 90/01/27 cpcahil Initial revision.
- X */
- Xvoid
- Xmalloc_split(ptr)
- X struct mlist * ptr;
- X{
- X extern struct mlist * malloc_end;
- X void malloc_join();
- X void malloc_memset();
- X int rest;
- X int size;
- X struct mlist * tptr;
- X
- X size = ptr->r_size;
- X
- X /*
- X * roundup size to the appropriate boundry
- X */
- X
- X M_ROUNDUP(size);
- X
- X /*
- X * figure out how much room is left in the array.
- X * if there is enough room, create a new mlist
- X * structure there.
- X */
- X
- X if( ptr->s.size > size )
- X {
- X rest = ptr->s.size - size;
- X }
- X else
- X {
- X rest = 0;
- X }
- X
- X if( rest > (M_SIZE+M_RND) )
- X {
- X tptr = (struct mlist *) (ptr->data+size);
- X tptr->prev = ptr;
- X tptr->next = ptr->next;
- X tptr->flag = M_MAGIC;
- X tptr->s.size = rest - M_SIZE;
- X
- X /*
- X * If possible, join this segment with the next one
- X */
- X
- X malloc_join(tptr, tptr->next,0,0);
- X
- X if( tptr->next )
- X {
- X tptr->next->prev = tptr;
- X }
- X
- X malloc_memset(tptr->data,M_FREE_FILL, (int)tptr->s.size);
- X
- X ptr->next = tptr;
- X ptr->s.size = size;
- X
- X if( malloc_end == ptr )
- X {
- X malloc_end = tptr;
- X }
- X }
- X
- X} /* malloc_split(... */
- X
- X/*
- X * Function: malloc_join()
- X *
- X * Purpose: to join two malloc segments together (if possible)
- X *
- X * Arguments: ptr - pointer to segment to join to.
- X * nextptr - pointer to next segment to join to ptr.
- X *
- X * Returns: nothing of any values.
- X *
- X * Narrative:
- X *
- X * Mod History:
- X * 90/01/27 cpcahil Initial revision.
- X */
- Xvoid
- Xmalloc_join(ptr,nextptr, inuse_override, fill_flag)
- X struct mlist * ptr;
- X struct mlist * nextptr;
- X int inuse_override;
- X int fill_flag;
- X{
- X unsigned int newsize;
- X
- X if( ptr && ! (inuse_override || (ptr->flag & M_INUSE)) &&
- X nextptr && ! (nextptr->flag & M_INUSE) &&
- X ((ptr->data+ptr->s.size) == (char *) nextptr) )
- X {
- X if( malloc_end == nextptr )
- X {
- X malloc_end = ptr;
- X }
- X ptr->next = nextptr->next;
- X newsize = nextptr->s.size + M_SIZE;
- X
- X /*
- X * if we are to fill and this segment is in use,
- X * fill in with M_FILL newly added space...
- X */
- X
- X if(fill_flag && (ptr->flag & M_INUSE) )
- X {
- X malloc_memset(ptr->data+ptr->s.size,
- X M_FILL, (int)(nextptr->s.size + M_SIZE));
- X }
- X
- X ptr->s.size += newsize;
- X if( ptr->next )
- X {
- X ptr->next->prev = ptr;
- X }
- X }
- X
- X} /* malloc_join(... */
- X
- X
- X/*
- X * The following mess is just to ensure that the versions of these functions in
- X * the current library are included (to make sure that we don't accidentaly get
- X * the libc versions. (This is the lazy man's -u ld directive)
- X */
- X
- Xvoid free();
- Xint strcmp();
- Xint memcmp();
- Xchar * realloc();
- X
- Xvoid (*malloc_void_funcs[])() =
- X{
- X free,
- X};
- X
- Xint (*malloc_int_funcs[])() =
- X{
- X strcmp,
- X memcmp,
- X};
- X
- Xchar * (*malloc_char_star_funcs[])() =
- X{
- X realloc,
- X};
- X
- X/*
- X * This is malloc's own memset which is used without checking the parameters.
- X */
- X
- Xvoid
- Xmalloc_memset(ptr,byte,len)
- X char * ptr;
- X char byte;
- X int len;
- X{
- X
- X while(len-- > 0)
- X {
- X *ptr++ = byte;
- X }
- X
- X} /* malloc_memset(... */
- X
- X/*
- X * Function: malloc_fatal()
- X *
- X * Purpose: to display fatal error message and take approrpriate action
- X *
- X * Arguments: funcname - name of function calling this routine
- X *
- X * Returns: nothing of any value
- X *
- X * Narrative:
- X *
- X * Notes: This routine does not make use of any libc functions to build
- X * and/or disply the error message. This is due to the fact that
- X * we are probably at a point where malloc is having a real problem
- X * and we don't want to call any function that may use malloc.
- X */
- Xvoid
- Xmalloc_fatal(funcname)
- X char * funcname;
- X{
- X char errbuf[128];
- X void exit();
- X void malloc_err_handler();
- X extern char * malloc_err_strings[];
- X extern int malloc_errno;
- X extern int malloc_fatal_level;
- X char * s;
- X char * t;
- X
- X s = errbuf;
- X t = "Fatal error: ";
- X while( *s = *t++)
- X {
- X s++;
- X }
- X t = funcname;
- X while( *s = *t++)
- X {
- X s++;
- X }
- X
- X t = "(): ";
- X while( *s = *t++)
- X {
- X s++;
- X }
- X
- X t = malloc_err_strings[malloc_errno];
- X while( *s = *t++)
- X {
- X s++;
- X }
- X
- X *(s++) = '\n';
- X
- X if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf))
- X {
- X (void) write(2,"I/O error to error file\n",(unsigned)24);
- X exit(110);
- X }
- X malloc_err_handler(malloc_fatal_level);
- X
- X} /* malloc_fatal(... */
- X
- X/*
- X * Function: malloc_warning()
- X *
- X * Purpose: to display warning error message and take approrpriate action
- X *
- X * Arguments: funcname - name of function calling this routine
- X *
- X * Returns: nothing of any value
- X *
- X * Narrative:
- X *
- X * Notes: This routine does not make use of any libc functions to build
- X * and/or disply the error message. This is due to the fact that
- X * we are probably at a point where malloc is having a real problem
- X * and we don't want to call any function that may use malloc.
- X */
- Xvoid
- Xmalloc_warning(funcname)
- X char * funcname;
- X{
- X char errbuf[128];
- X void exit();
- X void malloc_err_handler();
- X extern char * malloc_err_strings[];
- X extern int malloc_errno;
- X extern int malloc_warn_level;
- X char * s;
- X char * t;
- X
- X s = errbuf;
- X t = "Warning: ";
- X while( *s = *t++)
- X {
- X s++;
- X }
- X t = funcname;
- X while( *s = *t++)
- X {
- X s++;
- X }
- X
- X t = "(): ";
- X while( *s = *t++)
- X {
- X s++;
- X }
- X
- X t = malloc_err_strings[malloc_errno];
- X while( *s = *t++)
- X {
- X s++;
- X }
- X
- X *(s++) = '\n';
- X
- X if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf))
- X {
- X (void) write(2,"I/O error to error file\n",(unsigned)24);
- X exit(110);
- X }
- X
- X malloc_err_handler(malloc_warn_level);
- X
- X} /* malloc_warning(... */
- X
- X/*
- X * Function: malloc_err_handler()
- X *
- X * Purpose: to take the appropriate action for warning and/or fatal
- X * error conditions.
- X *
- X * Arguments: level - error handling level
- X *
- X * Returns: nothing of any value
- X *
- X * Narrative:
- X *
- X * Notes: This routine does not make use of any libc functions to build
- X * and/or disply the error message. This is due to the fact that
- X * we are probably at a point where malloc is having a real problem
- X * and we don't want to call any function that may use malloc.
- X */
- Xvoid
- Xmalloc_err_handler(level)
- X{
- X void exit();
- X void malloc_dump();
- X extern int malloc_errfd;
- X
- X if( level & M_HANDLE_DUMP )
- X {
- X malloc_dump(malloc_errfd);
- X }
- X
- X switch( level & ~M_HANDLE_DUMP )
- X {
- X /*
- X * If we are to drop a core file and exit
- X */
- X case M_HANDLE_ABORT:
- X (void) abort();
- X break;
- X
- X /*
- X * If we are to exit..
- X */
- X case M_HANDLE_EXIT:
- X exit(200);
- X break;
- X
- X /*
- X * If we are to dump a core, but keep going on our merry way
- X */
- X case M_HANDLE_CORE:
- X {
- X int pid;
- X
- X /*
- X * fork so child can abort (and dump core)
- X */
- X if( (pid = fork()) == 0 )
- X {
- X (void) write(2,"Child dumping core\n",
- X (unsigned)9);
- X (void) abort();
- X }
- X
- X /*
- X * wait for child to finish dumping core
- X */
- X while( wait((int *)0) != pid)
- X {
- X }
- X
- X /*
- X * Move core file to core.pid.cnt so
- X * multiple cores don't overwrite each
- X * other.
- X */
- X if( access("core",0) == 0 )
- X {
- X static int corecnt;
- X char filenam[32];
- X filenam[0] = 'c';
- X filenam[1] = 'o';
- X filenam[2] = 'r';
- X filenam[3] = 'e';
- X filenam[4] = '.';
- X (void)tostring(filenam+5,getpid(),
- X 5, B_DEC, '0');
- X filenam[10] = '.';
- X (void)tostring(filenam+11,corecnt++,
- X 3, B_DEC, '0');
- X filenam[14] = '\0';
- X (void) unlink(filenam);
- X if( link("core",filenam) == 0)
- X {
- X (void) unlink("core");
- X }
- X }
- X }
- X
- X
- X /*
- X * If we are to just ignore the error and keep on processing
- X */
- X case M_HANDLE_IGNORE:
- X break;
- X
- X } /* switch(... */
- X
- X} /* malloc_err_handler(... */
- X
- X/*
- X * $Log: malloc.c,v $
- X * Revision 1.6 90/05/11 00:13:09 cpcahil
- X * added copyright statment
- X *
- X * Revision 1.5 90/02/25 11:01:18 cpcahil
- X * added support for malloc chain checking.
- X *
- X * Revision 1.4 90/02/24 21:50:21 cpcahil
- X * lots of lint fixes
- X *
- X * Revision 1.3 90/02/24 14:51:18 cpcahil
- X * 1. changed malloc_fatal and malloc_warn to use malloc_errno and be passed
- X * the function name as a parameter.
- X * 2. Added several function headers.
- X * 3. Changed uses of malloc_fatal/warning to conform to new usage.
- X *
- X * Revision 1.2 90/02/23 18:05:23 cpcahil
- X * fixed open of error log to use append mode.
- X *
- X * Revision 1.1 90/02/22 23:17:43 cpcahil
- X * Initial revision
- X *
- X */
- SHAR_EOF
- $TOUCH -am 0511001490 malloc.c &&
- chmod 0444 malloc.c ||
- echo "restore of malloc.c failed"
- set `wc -c malloc.c`;Wc_c=$1
- if test "$Wc_c" != "12756"; then
- echo original size 12756, current size $Wc_c
- fi
- fi
- echo "End of part 1, continue with part 2"
- exit 0
-
- exit 0 # Just in case...
-