source: git/Singular/mmcheck.c @ 141634b

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