source: git/Singular/mmcheck.c @ d77d70

fieker-DuValspielwiese
Last change on this file since d77d70 was d77d70, checked in by Hans Schönemann <hannes@…>, 25 years ago
fixed return code git-svn-id: file:///usr/local/Singular/svn/trunk@2783 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 9.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: mmcheck.c,v 1.2 1999-01-05 12:18:39 Singular Exp $ */
5
6/*
7* ABSTRACT:
8*/
9
10#define _POSIX_SOURCE 1
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include "mod2.h"
16
17#ifdef MDEBUG
18
19#include "mmemory.h"
20#include "mmprivate.h"
21#include "mmpage.h"
22#include "mmheap.h"
23
24
25
26DBMCB mm_theDBused;
27DBMCB mm_theDBfree;
28
29void * mm_maxAddr = NULL;
30void * mm_minAddr = NULL;
31
32/* int mm_MDEBUG = MDEBUG; */
33int mm_MDEBUG = 0;
34
35/**********************************************************************
36 *
37 * Auxillary routines
38 *
39 **********************************************************************/
40
41static int mmPrintDBMCB ( DBMCB * what, char* msg , int given_size)
42{
43  (void)fprintf( stderr, "warning: %s\n", msg );
44  (void)fprintf( stderr, "block %x allocated in: %s:%d\n",
45     (int)&(what->data), what->fname, what->lineno );
46  if (strcmp(msg,"size")==0)
47    (void)fprintf( stderr, "size is: %d, but check said %d \n",
48      (int)what->size, given_size );
49  else
50    (void)fprintf( stderr, "size is: %d\n", (int)what->size );
51  return 0;
52}
53
54void mmPrintUsedList( )
55{
56  DBMCB * what;
57  what=mm_theDBused.next;
58  fprintf(stderr,"list of used blocks:\n");
59  while (what!=NULL)
60  {
61    (void)fprintf( stderr, "%d bytes at %p in: %s:%d\n",
62      (int)what->size, what, what->fname, what->lineno);
63    what=what->next;
64  }
65}
66   
67void mmPrintFL( const char* fname, const int lineno )
68{
69  (void)fprintf( stderr, "occured in %s:%d\n", fname, lineno );
70}
71
72/**********************************************************************
73 *
74 * Init routines
75 *
76 **********************************************************************/
77
78#define MM_USED_PATTERN 255
79#define MM_FREE_PATTERN 251
80#define MM_FRONT_PATTERN 247
81#define MM_BACK_PATTERN  249
82
83void mmFillDBMCB(DBMCB* what, size_t size, memHeap heap, 
84                 int flags, char* fname, int lineno)
85{
86  void* addr = &(what->data);
87
88  what->heap = heap;
89  what->size = size;
90  what->fname = fname;
91  what->lineno = lineno;
92  what->flags = flags;
93 
94  if (flags & MM_FREEFLAG)
95    memset(addr, MM_FREE_PATTERN, size);
96
97  memset(what->front_pattern, MM_FRONT_PATTERN, MM_NUMBER_OF_FRONT_PATTERNS);
98  memset((char*) addr + size, MM_BACK_PATTERN, DebugOffsetBack);
99}
100
101/**********************************************************************
102 *
103 * Check routines
104 *
105 **********************************************************************/
106
107static int mmCheckPattern(char* ptr, char pattern, size_t size)
108{
109  int i;
110 
111  for (i = 0; i<size; i++)
112    if (ptr[i] != pattern) return 0;
113  return 1;
114}
115
116#ifdef unix
117extern int _end;
118#endif
119static int mmCheckSingleDBMCB ( DBMCB * what, int size , int flags)
120{
121  char * patptr;
122  int i;
123  int ok=1;
124
125  if ( ((int)what % 4 ) != 0 )
126  {
127    fprintf( stderr, "warning: odd address\n" );
128    assume(0);
129    return 0;
130  }
131  if ( (void*)what > mm_maxAddr )
132  {
133    fprintf( stderr, "warning: address too high\n" );
134    assume(0);
135    return 0;
136  }
137  if ( (void*)what < mm_minAddr )
138  {
139    fprintf( stderr, "warning: address too low\n" );
140    assume(0);
141    return 0;
142  }
143  if (! mmIsNotAddrOnFreePage(what))
144  {
145    fprintf(stderr, "warning: address on freed page\n");
146    assume(0);
147    return 0;
148  }
149 
150  if ( ((long)what->fname<1000)
151  #ifdef unix
152       ||((long)what->fname>(int)&(_end))
153  #endif
154  )
155  { /* fname should be in the text segment */
156    fprintf(stderr, "warning: fname (%lx) out of range\n", (long)what->fname );
157    assume(0);
158    what->fname="???";
159    ok=0;
160  }
161  if ( (what->lineno< -9999) ||(what->lineno>9999) )
162  {
163    fprintf( stderr, "warning: lineno %d out of range\n",what->lineno );
164    assume(0);
165    what->lineno=0;
166    ok=0;
167  }
168  #ifdef unix
169  if ( (what->next!=NULL)
170       && (((long)what->next>(long)mm_maxAddr)
171           || ((long)what->next<(long)mm_minAddr) )
172       && (((long)what->next>(long)&_end)
173           || ((long)what->next<1000))
174  )
175  {
176    fprintf( stderr, "warning: next (%lx) out of range\n", (long)what->next );
177    assume(0);
178    what->next=NULL;
179    ok=0;
180  }
181  if ( (what->prev!=NULL)
182       && (((long)what->prev>(long)mm_maxAddr)
183           || ((long)what->prev<(long)mm_minAddr) )
184       && (((long)what->prev>(long)&_end)
185           || ((long)what->prev<1000)))
186  {
187    fprintf( stderr, "warning: prev (%lx) out of range\n", (long)what->prev );
188    assume(0);
189    what->prev=NULL;
190    ok=0;
191  }
192  #endif
193
194  if ( ( what->flags & flags ) != flags )
195    return mmPrintDBMCB( what, "flags", 0 );
196
197
198  if ( what->size != size )
199    return mmPrintDBMCB( what, "size", size );
200
201  i = mmGetIndex(size);
202
203  if (! mmCheckPattern(what->front_pattern, MM_FRONT_PATTERN,
204                       MM_NUMBER_OF_FRONT_PATTERNS))
205    return mmPrintDBMCB(what , "front pattern", 0);
206  if ((what->flags & MM_FREEFLAG)  && 
207      ! mmCheckPattern((char*)&(what->data), MM_FREE_PATTERN, 0))
208    return mmPrintDBMCB(what, "free pattern", 0);
209  if (! mmCheckPattern((char*) &(what->data) + size, 
210                       MM_BACK_PATTERN, DebugOffsetBack))
211    return mmPrintDBMCB(what, "back pattern", 0);
212
213  if ( ( what->next != NULL ) && ( what->next->prev != what ) )
214  {
215    mmPrintDBMCB( what->next, "next", 0 );
216    what->next->prev=what;
217    return mmPrintDBMCB( what, "chain:n", 0 );
218  }
219  if ( ( what->prev != NULL ) && ( what->prev->next != what ) )
220  {
221    mmPrintDBMCB( what->prev, "prev", 0 );
222    what->prev->next=what;
223    return mmPrintDBMCB( what, "chain:p", 0 );
224  }
225  if(ok==0)
226  {
227    return mmPrintDBMCB( what, "see above", 0 );
228  }
229
230  return 1;
231}
232
233static int mmCheckDBMCBList(DBMCB * list, int flags)
234{
235  assume(flags == MM_FREEFLAG || flags == MM_USEDFLAG);
236
237  if (mmGListHasCycle(list,
238                      (void*) &(mm_theDBfree.next) -
239                      (void*) &(mm_theDBfree)))
240  {
241    fprintf(stderr, "%s list contains cycles\n",
242            (flags == MM_FREEFLAG ? "Free" : "Used"));
243    assume(0);
244    return 0;
245  }
246
247  while (list != NULL)
248  {
249    if (! mmCheckSingleDBMCB(list, list->size, flags))
250    {
251      fprintf(stderr, "while check of %s list\n",
252            (flags == MM_FREEFLAG ? "free" : "used"));
253      return 0;
254    }
255    list = list->next;
256  }
257
258  return 1;
259}
260
261int mmTestMemory()
262{
263  if (mmCheckDBMCBList(mm_theDBused.next, MM_USEDFLAG))
264    return mmCheckDBMCBList(mm_theDBfree.next, MM_FREEFLAG);
265  return 0;
266}
267
268int mmTestHeaps()
269{
270  int i = -1;
271
272  do
273  {
274    i++;
275    if (! mmCheckHeap(&mm_theList[i])) return 0;
276  }
277  while (mmGetSize(i) < MAX_BLOCK_SIZE);
278
279  return 1;
280}
281 
282static int   mmIsAddrOnDList(DBMCB *what, DBMCB* list, int s)
283{
284  while (list != NULL)
285  {
286    if (list == what) return 1;
287    list = list->next;
288  }
289  return 0;
290}
291
292static int mmCheckListContainment(DBMCB * what, int flags)
293{
294  if ( mmIsAddrOnDList((void*) what, mm_theDBused.next,
295                       (void*) &(mm_theDBused.next) -
296                       (void*) &(mm_theDBused)))
297  {
298    if (flags == MM_FREEFLAG)
299      return mmPrintDBMCB(what, "Free flag and in used list", 0);
300  }
301  else
302  {
303    if (flags == MM_USEDFLAG)
304      return mmPrintDBMCB(what, "Used flag but not in used list", 0);
305  }
306 
307  if ( mmIsAddrOnDList((void*) what, mm_theDBfree.next,
308                       (void*) &(mm_theDBfree.next) -
309                       (void*) &(mm_theDBfree)))
310  {
311    if (flags == MM_USEDFLAG)
312      return mmPrintDBMCB(what, "Used flag and in free list", 0);
313  }
314  else
315  {
316    if (flags == MM_FREEFLAG)
317      return mmPrintDBMCB(what,"Free flag but not in free list", 0);
318  }
319  return 1;
320}
321 
322int mmCheckDBMCB ( DBMCB * what, int size , int flags)
323{
324
325  assume(flags == MM_FREEFLAG || flags == MM_USEDFLAG);
326  if (! mmCheckSingleDBMCB(what, size, flags))
327    return 0;
328
329  if (mm_MDEBUG > 1 && ! mmTestMemory()) return 0;
330 
331  if (mm_MDEBUG > 0 && ! mmCheckListContainment(what, flags)) return 0;
332
333  return 1;
334}
335
336/**********************************************************************
337 *
338 * Test routines
339 *
340 **********************************************************************/
341static BOOLEAN mmDBTestHeapBlockS(const void* adr, const memHeap heap,
342                                  const size_t size,
343                                  const char * fname, const int lineno )
344{
345  DBMCB * what;
346
347  if ( adr == NULL || size == 0) 
348    return TRUE;
349
350  if (mm_MDEBUG > 2 && ! mmTestHeaps())
351  {
352    mmPrintFL( fname, lineno );
353    return FALSE;
354  }
355   
356  what = (DBMCB*)((char*)(adr) - DebugOffsetFront);
357
358  if ( ! mmCheckDBMCB( what, size, MM_USEDFLAG) )
359  {
360    mmPrintFL( fname, lineno );
361    return FALSE;
362  }
363
364  if (what->heap != heap)
365  {
366    mmPrintDBMCB(what, "Not from specified heap", 0);
367    mmPrintFL( fname, lineno );
368    return FALSE;
369  }
370
371#ifdef HEAP_DEBUG
372  return
373    mmDebugCheckHeapAddr(what, heap, MM_HEAP_ADDR_USED_FLAG, fname, lineno);
374#else
375  return TRUE;
376#endif
377}
378
379BOOLEAN mmDBTestHeapBlock(const void* adr, const memHeap heap,
380                          const char * fname, const int lineno )
381{
382  return mmDBTestHeapBlockS(adr, heap,
383                            SizeFromRealSize(mmGetHeapBlockSize(heap)),
384                            fname, lineno);
385}
386                           
387BOOLEAN mmDBTestBlock(const void* adr, const size_t size, 
388                      const char * fname, const int lineno)
389{
390  int i;
391  DBMCB * what;
392 
393  if ( ( adr == NULL ) || ( size == 0 ) ) return TRUE;
394
395  i = mmGetIndex(size);
396  if (i < 0)
397  {
398    what = (DBMCB*)((char*)(adr) - DebugOffsetFront);
399    if ( ! mmCheckDBMCB( what, size, MM_USEDFLAG) ) 
400    {
401      mmPrintFL( fname, lineno );
402      return FALSE;
403    }
404    return TRUE;
405  }
406  else
407  {
408    return mmDBTestHeapBlockS(adr, &(mm_theList[i]), size, fname, lineno);
409  }
410}
411
412
413BOOLEAN mmDBTest( const void* adr, const char * fname, const int lineno )
414{
415  if (adr!=NULL)
416  {
417    size_t l;
418    adr = (size_t*)adr-1;
419#ifdef ALIGN_8
420    l= (adr<=mm_maxAddr) ? (*(size_t*)((int)adr&(~7))) :0;
421#else
422    l= (adr<=mm_maxAddr) ? (*(size_t*)((int)adr&(~3))) :0;
423#endif
424    return mmDBTestBlock( adr,l, fname, lineno );
425  }
426  return TRUE;
427}
428
429#endif /* MDEBUG */
430
431
432
Note: See TracBrowser for help on using the repository browser.