Advanced Strategic Command
memorycheck.cpp
Go to the documentation of this file.
1 
8 /***************************************************************************
9  memorycheck.cpp - description
10  -------------------
11  begin : Wed Nov 29 2000
12  copyright : (C) 2000 by Martin Bickel
13  email : bickel@asc-hq.org
14  ***************************************************************************/
15 
16 /***************************************************************************
17  * *
18  * This program is free software; you can redistribute it and/or modify *
19  * it under the terms of the GNU General Public License as published by *
20  * the Free Software Foundation; either version 2 of the License, or *
21  * (at your option) any later version. *
22  * *
23  ***************************************************************************/
24 
25 
26 #ifdef MEMCHK
27 
28  int blockNum = 0;
29  int operationID = 0;
30  int errorNum = 0;
31  int breakOnFree = 0;
32  const int infoblocksize = 3;
33 
34  bool memchk_initialized = false;
35 
36 
37  bool memchk_reallyComplete = false; // this variable is intended to be set by the debugger
38  int memchk_breakOnOp = -1; // this variable is intended to be set by the debugger
39 
40  void memchkError ( )
41  {
42  errorNum++;
43  fprintf(stderr, "memchkError !\n");
44  }
45 
46  class Block {
47  public:
48  int start;
49  int stop;
50  int userStart;
51  int size;
52  int allocated;
53  int freed;
54  int allocatedOP;
55  int freedOP;
56  };
57 
58 
59  Block blocks[1000000];
60 
61  void* verifyblock ( int tp, Block* b )
62  {
63  int error = 0;
64  int* tmpi = (int*) b->start;
65 
66  if ( tp != -1 )
67  if ( tmpi[0] != tp )
68  error++; // for example: allocated with new ; freed with delete[]
69 /*
70  if ( tmpi[1] != (int) tmpi) {
71  memchkError();
72  #ifdef logging
73  logtofile ( "memory check: verifyblock : error A at address %x", p );
74  #endif
75  }
76 */
77  int amt = tmpi[2];
78 
79  for ( int i = 0; i < 25; i++ ) {
80  if ( tmpi[infoblocksize + i] != 0x12345678) {
81  memchkError();
82  #ifdef logging
83  logtofile ( "memory check: verifyblock : error C at address %x", p );
84  #endif
85  }
86 
87  if ( tmpi[infoblocksize + i + (amt+3)/4 + 25] != 0x87654321 ) {
88  memchkError();
89  #ifdef logging
90  logtofile ( "memory check: verifyblock : error D at address %x", p );
91  #endif
92  }
93  }
94  return tmpi;
95  }
96 
97  void verifyallblocks ( void )
98  {
99  for ( int i = 0; i < blockNum; i++ )
100  if ( !blocks[i].freed )
101  verifyblock ( -1, &blocks[i] );
102  }
103 
104  void* memchkAlloc ( int tp, size_t amt )
105  {
106  if ( ! memchk_initialized ) {
107  memset ( blocks, 0, sizeof ( blocks ));
108  memchk_initialized = true;
109  }
110 
111  if ( memchk_reallyComplete )
112  verifyallblocks();
113 
114  Block& b = blocks[ blockNum++ ];
115  if ( blockNum >= 1000000 )
116  memchkError();
117 
118  b.size = amt + (50+infoblocksize) * 4;
119  b.allocated++;
120 
121  if ( operationID == memchk_breakOnOp )
122  memchkError();
123 
124  b.allocatedOP = operationID++;
125 
126  void* tmp = malloc ( b.size+4 );
127 
128 
129  b.start = (int) tmp;
130  b.stop = b.start + b.size;
131 
132  for ( int i = 0; i < blockNum-1; i++ ) {
133  if ( !blocks[i].freed ) {
134  if ( b.start >= blocks[i].start && b.start < blocks[i].stop )
135  memchkError();
136  if ( b.stop >= blocks[i].start && b.stop < blocks[i].stop )
137  memchkError();
138  if ( blocks[i].start < b.start && blocks[i].stop > b.stop )
139  memchkError();
140  }
141  }
142 
143 
144  int* tmpi = (int*) tmp;
145  /*
146  if ( (int) tmpi == 0x1bb2138 || (int) tmpi == 0x1bcf178 )
147  error++;
148  */
149  tmpi[0] = tp;
150 
151  if ( 4 < infoblocksize )
152  tmpi[4] = (int) tmp;
153 
154  if ( 2 < infoblocksize )
155  tmpi[2] = amt;
156 
157  if ( 3 < infoblocksize )
158  tmpi[3] = b.allocatedOP;
159 
160  if ( 1 < infoblocksize )
161  tmpi[1] = blockNum-1;
162 
163  for ( int i = 0; i < 25; i++ ) {
164  tmpi[infoblocksize + i] = 0x12345678;
165  tmpi[infoblocksize + i + (amt+3)/4 + 25] = 0x87654321;
166  }
167  void* p = &tmpi[25+infoblocksize];
168  b.userStart = (int) p;
169  return p;
170  }
171 
172  void memchkFree ( int tp, void* buf )
173  {
174  if ( breakOnFree == (int) buf )
175  memchkError();
176 
177  Block* b = NULL;
178  for ( int i = blockNum-1; i>= 0 ; i-- )
179  if ( blocks[i].userStart == (int) buf ) {
180  b = &blocks[i];
181  break;
182  }
183 
184  if ( b ) {
185 
186  if ( memchk_reallyComplete )
187  verifyallblocks();
188 
189  void* tmpi = verifyblock ( tp, b );
190 
191  if ( b->freed > 0 )
192  memchkError();
193 
194  if ( b->allocated <= 0 )
195  memchkError();
196 
197  if ( operationID == memchk_breakOnOp )
198  memchkError();
199 
200 
201  b->freed++;
202  b->freedOP = operationID++;
203 
204  free ( tmpi );
205  } else
206  free ( buf );
207  }
208 
209 
210 
211 
212 
213  void *operator new( size_t amt )
214  {
215  return( memchkAlloc( 100, amt ) );
216  }
217 
218  void operator delete( void *p )
219  {
220  if ( p )
221  memchkFree( 100, p );
222  }
223 
224  void *operator new []( size_t amt )
225  {
226  return( memchkAlloc( 102, amt ) );
227  }
228 
229  void operator delete []( void *p )
230  {
231  if ( p )
232  memchkFree( 102, p );
233  }
234 
235  void* asc_malloc ( size_t size )
236  {
237  void* tmp = memchkAlloc ( 104, size );
238  return tmp;
239  }
240 
241  void asc_free ( void* p )
242  {
243  memchkFree ( 104, p );
244  }
245 
246 #else
247 
248  void* asc_malloc ( size_t size )
249  {
250  void* tmp = malloc ( size );
251  #ifdef _DOS_
252  if ( tmp == NULL )
253  new_new_handler();
254  #else
255  if ( tmp == NULL )
256  fatalError("Out of memory!");
257  #endif
258  return tmp;
259  }
260 
261  void asc_free ( void* p )
262  {
263  free ( p );
264  }
265 
266 
267 #endif
void asc_free(void *p)
if(!yyg->yy_init)
Definition: scanner.cpp:695
char * malloc(int)
void * asc_malloc(size_t size)
void fatalError(const ASCString &string)