source: git/Singular/mmcheck.c @ 393249

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