|
@@ -186,6 +186,42 @@ static inline void valgrind_make_blocks_noaccess ( void ) {
|
186
|
186
|
VALGRIND_MAKE_MEM_NOACCESS ( &free_blocks, sizeof ( free_blocks ) );
|
187
|
187
|
}
|
188
|
188
|
|
|
189
|
+/**
|
|
190
|
+ * Check integrity of the blocks in the free list
|
|
191
|
+ *
|
|
192
|
+ */
|
|
193
|
+static inline void check_blocks ( void ) {
|
|
194
|
+ struct memory_block *block;
|
|
195
|
+ struct memory_block *prev = NULL;
|
|
196
|
+
|
|
197
|
+ if ( ! ASSERTING )
|
|
198
|
+ return;
|
|
199
|
+
|
|
200
|
+ list_for_each_entry ( block, &free_blocks, list ) {
|
|
201
|
+
|
|
202
|
+ /* Check that list structure is intact */
|
|
203
|
+ list_check ( &block->list );
|
|
204
|
+
|
|
205
|
+ /* Check that block size is not too small */
|
|
206
|
+ assert ( block->size >= sizeof ( *block ) );
|
|
207
|
+ assert ( block->size >= MIN_MEMBLOCK_SIZE );
|
|
208
|
+
|
|
209
|
+ /* Check that block does not wrap beyond end of address space */
|
|
210
|
+ assert ( ( ( void * ) block + block->size ) >
|
|
211
|
+ ( ( void * ) block ) );
|
|
212
|
+
|
|
213
|
+ /* Check that blocks remain in ascending order, and
|
|
214
|
+ * that adjacent blocks have been merged.
|
|
215
|
+ */
|
|
216
|
+ if ( prev ) {
|
|
217
|
+ assert ( ( ( void * ) block ) > ( ( void * ) prev ) );
|
|
218
|
+ assert ( ( ( void * ) block ) >
|
|
219
|
+ ( ( ( void * ) prev ) + prev->size ) );
|
|
220
|
+ }
|
|
221
|
+ prev = block;
|
|
222
|
+ }
|
|
223
|
+}
|
|
224
|
+
|
189
|
225
|
/**
|
190
|
226
|
* Discard some cached data
|
191
|
227
|
*
|
|
@@ -242,6 +278,7 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
|
242
|
278
|
assert ( ( align == 0 ) || ( ( align & ( align - 1 ) ) == 0 ) );
|
243
|
279
|
|
244
|
280
|
valgrind_make_blocks_defined();
|
|
281
|
+ check_blocks();
|
245
|
282
|
|
246
|
283
|
/* Round up size to multiple of MIN_MEMBLOCK_SIZE and
|
247
|
284
|
* calculate alignment mask.
|
|
@@ -314,6 +351,7 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
|
314
|
351
|
}
|
315
|
352
|
|
316
|
353
|
done:
|
|
354
|
+ check_blocks();
|
317
|
355
|
valgrind_make_blocks_noaccess();
|
318
|
356
|
return ptr;
|
319
|
357
|
}
|
|
@@ -338,6 +376,7 @@ void free_memblock ( void *ptr, size_t size ) {
|
338
|
376
|
return;
|
339
|
377
|
|
340
|
378
|
valgrind_make_blocks_defined();
|
|
379
|
+ check_blocks();
|
341
|
380
|
|
342
|
381
|
/* Round up size to match actual size that alloc_memblock()
|
343
|
382
|
* would have used.
|
|
@@ -346,11 +385,29 @@ void free_memblock ( void *ptr, size_t size ) {
|
346
|
385
|
size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
|
347
|
386
|
freeing = ptr;
|
348
|
387
|
VALGRIND_MAKE_MEM_DEFINED ( freeing, sizeof ( *freeing ) );
|
349
|
|
- freeing->size = size;
|
350
|
388
|
DBGC2 ( &heap, "Freeing [%p,%p)\n",
|
351
|
389
|
freeing, ( ( ( void * ) freeing ) + size ) );
|
352
|
390
|
|
|
391
|
+ /* Check that this block does not overlap the free list */
|
|
392
|
+ if ( ASSERTING ) {
|
|
393
|
+ list_for_each_entry ( block, &free_blocks, list ) {
|
|
394
|
+ if ( ( ( ( void * ) block ) <
|
|
395
|
+ ( ( void * ) freeing + size ) ) &&
|
|
396
|
+ ( ( void * ) freeing <
|
|
397
|
+ ( ( void * ) block + block->size ) ) ) {
|
|
398
|
+ assert ( 0 );
|
|
399
|
+ DBGC ( &heap, "Double free of [%p,%p) "
|
|
400
|
+ "overlapping [%p,%p) detected from %p\n",
|
|
401
|
+ freeing,
|
|
402
|
+ ( ( ( void * ) freeing ) + size ), block,
|
|
403
|
+ ( ( void * ) block + block->size ),
|
|
404
|
+ __builtin_return_address ( 0 ) );
|
|
405
|
+ }
|
|
406
|
+ }
|
|
407
|
+ }
|
|
408
|
+
|
353
|
409
|
/* Insert/merge into free list */
|
|
410
|
+ freeing->size = size;
|
354
|
411
|
list_for_each_entry_safe ( block, tmp, &free_blocks, list ) {
|
355
|
412
|
/* Calculate gaps before and after the "freeing" block */
|
356
|
413
|
gap_before = ( ( ( void * ) freeing ) -
|
|
@@ -392,6 +449,7 @@ void free_memblock ( void *ptr, size_t size ) {
|
392
|
449
|
/* Update free memory counter */
|
393
|
450
|
freemem += size;
|
394
|
451
|
|
|
452
|
+ check_blocks();
|
395
|
453
|
valgrind_make_blocks_noaccess();
|
396
|
454
|
}
|
397
|
455
|
|