... | ... |
@@ -632,7 +632,59 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size) |
632 | 632 |
} |
633 | 633 |
|
634 | 634 |
|
635 |
+void qm_check(struct qm_block* qm) |
|
636 |
+{ |
|
637 |
+ struct qm_frag* f; |
|
638 |
+ long fcount = 0; |
|
639 |
+ |
|
640 |
+ LOG(memlog, "DEBUG: qm_check()\n"); |
|
641 |
+ f = qm->first_frag; |
|
642 |
+ while ((char*)f < (char*)qm->last_frag_end) { |
|
643 |
+ fcount++; |
|
644 |
+ /* check struct qm_frag */ |
|
645 |
+#ifdef DBG_QM_MALLOC |
|
646 |
+ if (f->check!=ST_CHECK_PATTERN){ |
|
647 |
+ LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p) " |
|
648 |
+ "beginning overwritten(%lx)!\n", |
|
649 |
+ f, (char*)f + sizeof(struct qm_frag), |
|
650 |
+ f->check); |
|
651 |
+ qm_status(qm); |
|
652 |
+ abort(); |
|
653 |
+ }; |
|
654 |
+#endif |
|
655 |
+ if (f + sizeof(struct qm_frag) + f->size + sizeof(struct qm_frag_end) > qm->first_frag + qm->size) { |
|
656 |
+ LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p) " |
|
657 |
+ "bad size: %lu (frag end: %p > end of block: %p)\n", |
|
658 |
+ f, (char*)f + sizeof(struct qm_frag) + sizeof(struct qm_frag_end), f->size, |
|
659 |
+ f + sizeof(struct qm_frag) + f->size, qm->first_frag + qm->size); |
|
660 |
+ qm_status(qm); |
|
661 |
+ abort(); |
|
662 |
+ } |
|
663 |
+ /* check struct qm_frag_end */ |
|
664 |
+ if (FRAG_END(f)->size != f->size) { |
|
665 |
+ LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p) " |
|
666 |
+ "size in qm_frag and qm_frag_end does not match: frag->size=%lu, frag_end->size=%lu)\n", |
|
667 |
+ f, (char*)f + sizeof(struct qm_frag), |
|
668 |
+ f->size, FRAG_END(f)->size); |
|
669 |
+ qm_status(qm); |
|
670 |
+ abort(); |
|
671 |
+ } |
|
672 |
+#ifdef DBG_QM_MALLOC |
|
673 |
+ if ((FRAG_END(f)->check1 != END_CHECK_PATTERN1) || |
|
674 |
+ (FRAG_END(f)->check2 != END_CHECK_PATTERN2)) { |
|
675 |
+ LOG(L_CRIT, "BUG: qm_*: fragm. %p (address %p)" |
|
676 |
+ " end overwritten(%lx, %lx)!\n", |
|
677 |
+ f, (char*)f + sizeof(struct qm_frag), |
|
678 |
+ FRAG_END(f)->check1, FRAG_END(f)->check2); |
|
679 |
+ qm_status(qm); |
|
680 |
+ abort(); |
|
681 |
+ } |
|
682 |
+#endif |
|
683 |
+ f = FRAG_NEXT(f); |
|
684 |
+ } |
|
635 | 685 |
|
686 |
+ LOG(memlog, "DEBUG: qm_check: %lu fragments OK\n", fcount); |
|
687 |
+} |
|
636 | 688 |
|
637 | 689 |
void qm_status(struct qm_block* qm) |
638 | 690 |
{ |
... | ... |
@@ -148,6 +148,7 @@ void* qm_realloc(struct qm_block*, void* p, unsigned long size); |
148 | 148 |
#endif |
149 | 149 |
|
150 | 150 |
void qm_status(struct qm_block*); |
151 |
+void qm_check(struct qm_block*); |
|
151 | 152 |
void qm_info(struct qm_block*, struct mem_info*); |
152 | 153 |
|
153 | 154 |
unsigned long qm_available(struct qm_block* qm); |