1 /*
2  * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
3  * You may copy, distribute, and use this software as long as this
4  * copyright statement is not removed.
5  */
6 #include <stdio.h>
7 #include <fcntl.h>
8 #include "malloc.h"
9 
10 /*
11  * Function:	malloc_chain_check()
12  *
13  * Purpose:	to verify malloc chain is intact
14  *
15  * Arguments:	todo	- 0 - just check and return status
16  *			  1 - call malloc_warn if error detected
17  *
18  * Returns:	0	- malloc chain intact & no overflows
19  *		other	- problems detected in malloc chain
20  *
21  * Narrative:
22  *
23  * Notes:	If todo is non-zero the malloc_warn function, when called
24  *		may not return (i.e. it may exit)
25  *
26  */
27 #ifndef lint
28 static
29 char rcs_hdr[] = "$Id: mlc_chn.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $";
30 #endif
31 
32 
33 int
malloc_chain_check(todo)34 malloc_chain_check(todo)
35 	int		  todo;
36 {
37 	char			* func = "malloc_chain_check";
38 	int			  i;
39 	extern char		* malloc_data_start;
40 	extern char		* malloc_data_end;
41 	extern struct mlist 	* malloc_end;
42 	extern int		  malloc_errno;
43 	extern struct mlist	  malloc_start;
44 	struct mlist		* oldptr;
45 	struct mlist		* ptr;
46 	int			  rtn = 0;
47 
48 	oldptr = &malloc_start;
49 	for(ptr = malloc_start.next; ; ptr = ptr->next)
50 	{
51 		/*
52 		 * Since the malloc chain is a forward only chain, any
53 		 * pointer that we get should always be positioned in
54 		 * memory following the previous pointer.  If this is not
55 		 * so, we must have a corrupted chain.
56 		 */
57 		if( ptr )
58 		{
59 			if(ptr < oldptr )
60 			{
61 				malloc_errno = M_CODE_CHAIN_BROKE;
62 				if( todo )
63 				{
64 					malloc_fatal(func);
65 				}
66 				rtn++;
67 				break;
68 			}
69 			oldptr = ptr;
70 		}
71 		else
72 		{
73 			if( oldptr != malloc_end )
74 			{
75 				/*
76 				 * This should never happen.  If it does, then
77 				 * we got a real problem.
78 				 */
79 				malloc_errno = M_CODE_NO_END;
80 				if( todo )
81 				{
82 					malloc_fatal(func);
83 				}
84 				rtn++;
85 			}
86 			break;
87 		}
88 
89 		/*
90 		 * verify that ptr is within the malloc region...
91 		 * since we started within the malloc chain this should never
92 		 * happen.
93 		 */
94 
95 		if( ((char *)ptr < malloc_data_start) ||
96 		    ((char *)ptr > malloc_data_end) )
97 		{
98 			malloc_errno = M_CODE_BAD_PTR;
99 			if( todo )
100 			{
101 				malloc_fatal(func);
102 			}
103 			rtn++;
104 			break;
105 		}
106 
107 		/*
108 		 * verify magic flag is set
109 		 */
110 
111 		if( (ptr->flag&M_MAGIC) != M_MAGIC )
112 		{
113 			malloc_errno = M_CODE_BAD_MAGIC;
114 			if( todo )
115 			{
116 				malloc_warning(func);
117 			}
118 			rtn++;
119 			continue;
120 		}
121 
122 		/*
123 		 * verify segments are correctly linked together
124 		 */
125 
126 		if( (ptr->prev && (ptr->prev->next != ptr) ) ||
127 		    (ptr->next && (ptr->next->prev != ptr) ) ||
128 		    ((ptr->next == NULL) && (ptr->prev == NULL)) )
129 		{
130 			malloc_errno = M_CODE_BAD_CONNECT;
131 			if( todo )
132 			{
133 				malloc_warning(func);
134 			}
135 			rtn++;
136 			continue;
137 		}
138 
139 		/*
140 		 * If this segment is allocated
141 		 */
142 
143 		if( (ptr->flag & M_INUSE) != 0 )
144 		{
145 			/*
146 			 * verify no overflow of data area
147 			 */
148 
149 			for(i=ptr->r_size; i < ptr->s.size; i++)
150 			{
151 				if( ptr->data[i] != M_FILL )
152 				{
153 					malloc_errno = M_CODE_OVERRUN;
154 					if( todo )
155 					{
156 						malloc_warning(func);
157 					}
158 					rtn++;
159 					break;
160 				}
161 			}
162 		}
163 		else /* it's not allocated so */
164 		{
165 			/*
166 			 * verify no reuse of freed data blocks
167 			 */
168 
169 			for(i=0; i < ptr->s.size; i++)
170 			{
171 				if( ptr->data[i] != M_FREE_FILL )
172 				{
173 					malloc_errno = M_CODE_REUSE;
174 					if( todo )
175 					{
176 						malloc_warning(func);
177 					}
178 					rtn++;
179 					break;
180 				}
181 			}
182 		}
183 
184 	} /* for(... */
185 
186 	return(rtn);
187 
188 } /* malloc_chain_check(... */
189