1 /* mm_diff - Memory snapshooting and comparison */
3 /* Copyright (c) 2008-2012. The SimGrid Team. All rights reserved. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
9 int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr){
11 if(mdp1 == NULL && mdp2 == NULL){
12 XBT_DEBUG("Malloc descriptors null");
18 int errors = mmalloc_compare_mdesc(mdp1, mdp2, std_heap_addr);
24 int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap_addr){
28 if(mdp1->headersize != mdp2->headersize){
29 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
30 XBT_DEBUG("Different size of the file header for the mapped files");
37 if(mdp1->refcount != mdp2->refcount){
38 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
39 XBT_DEBUG("Different number of processes that attached the heap");
46 if(strcmp(mdp1->magic, mdp2->magic) != 0){
47 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
48 XBT_DEBUG("Different magic number");
55 if(mdp1->flags != mdp2->flags){
56 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
57 XBT_DEBUG("Different flags");
64 if(mdp1->heapsize != mdp2->heapsize){
65 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
66 XBT_DEBUG("Different number of info entries");
73 //XBT_DEBUG("Heap size : %zu", mdp1->heapsize);
75 if(mdp1->heapbase != mdp2->heapbase){
76 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
77 XBT_DEBUG("Different first block of the heap");
85 if(mdp1->heapindex != mdp2->heapindex){
86 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
87 XBT_DEBUG("Different index for the heap table : %zu - %zu", mdp1->heapindex, mdp2->heapindex);
94 //XBT_DEBUG("Heap index : %zu", mdp1->heapindex);
96 if(mdp1->base != mdp2->base){
97 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
98 XBT_DEBUG("Different base address of the memory region");
105 if(mdp1->breakval != mdp2->breakval){
106 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
107 XBT_DEBUG("Different current location in the memory region");
114 if(mdp1->top != mdp2->top){
115 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
116 XBT_DEBUG("Different end of the current location in the memory region");
123 if(mdp1->heaplimit != mdp2->heaplimit){
124 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
125 XBT_DEBUG("Different limit of valid info table indices");
132 if(mdp1->fd != mdp2->fd){
133 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
134 XBT_DEBUG("Different file descriptor for the file to which this malloc heap is mapped");
141 if(mdp1->version != mdp2->version){
142 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
143 XBT_DEBUG("Different version of the mmalloc package");
151 size_t block_free1, block_free2 , next_block_free, first_block_free, block_free ;
153 void *addr_block1, *addr_block2;
157 /* Search index of the first free block */
159 block_free1 = mdp1->heapindex;
160 block_free2 = mdp2->heapindex;
162 while(mdp1->heapinfo[block_free1].free_block.prev != 0){
163 block_free1 = mdp1->heapinfo[block_free1].free_block.prev;
166 while(mdp2->heapinfo[block_free2].free_block.prev != 0){
167 block_free2 = mdp1->heapinfo[block_free2].free_block.prev;
170 if(block_free1 != block_free2){
171 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
172 XBT_DEBUG("Different first free block");
179 first_block_free = block_free1;
181 if(mdp1->heapinfo[first_block_free].free_block.size != mdp2->heapinfo[first_block_free].free_block.size){
182 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
183 XBT_DEBUG("Different size (in blocks) of the first free cluster");
190 /* Check busy blocks (circular checking)*/
192 i = first_block_free + mdp1->heapinfo[first_block_free].free_block.size;
194 if(mdp1->heapinfo[first_block_free].free_block.next != mdp2->heapinfo[first_block_free].free_block.next){
195 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
196 XBT_DEBUG("Different next block free");
203 block_free = first_block_free;
204 next_block_free = mdp1->heapinfo[first_block_free].free_block.next;
206 if(next_block_free == 0)
207 next_block_free = mdp1->heaplimit;
209 while(i != first_block_free){
211 while(i<next_block_free){
213 if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
214 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
215 XBT_DEBUG("Different type of busy block");
222 addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
223 addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
225 switch(mdp1->heapinfo[i].type){ //FIXME deal with type<0 == free
227 if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
228 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
229 XBT_DEBUG("Different size of a large cluster");
235 if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
236 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
237 XBT_DEBUG("Different data in block %zu (size = %zu) (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, mdp1->heapinfo[i].busy_block.size, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
244 i = i+mdp1->heapinfo[i].busy_block.size;
248 if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
249 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
250 XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
256 if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
257 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
258 XBT_DEBUG("Different first free fragments in the block %zu", i);
264 frag_size = pow(2,mdp1->heapinfo[i].type);
265 for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
266 if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
267 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
268 XBT_DEBUG("Different data in fragment %zu (addr_frag1 = %p - addr_frag2 = %p) of block %zu", j + 1, (char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), i);
286 if( i != first_block_free){
288 if(mdp1->heapinfo[block_free].free_block.next != mdp2->heapinfo[block_free].free_block.next){
289 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
290 XBT_DEBUG("Different next block free");
297 block_free = mdp1->heapinfo[block_free].free_block.next;
298 next_block_free = mdp1->heapinfo[block_free].free_block.next;
300 i = block_free + mdp1->heapinfo[block_free].free_block.size;
302 if((next_block_free == 0) && (i != mdp1->heaplimit)){
304 while(i < mdp1->heaplimit){
306 if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
307 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
308 XBT_DEBUG("Different type of busy block");
315 addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
316 addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
318 switch(mdp1->heapinfo[i].type){
320 if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
321 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
322 XBT_DEBUG("Different size of a large cluster");
328 if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
329 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
330 XBT_DEBUG("Different data in block %zu (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
338 i = i+mdp1->heapinfo[i].busy_block.size;
342 if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
343 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
344 XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
350 if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
351 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
352 XBT_DEBUG("Different first free fragments in the block %zu", i);
358 frag_size = pow(2,mdp1->heapinfo[i].type);
359 for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
360 if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
361 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
362 XBT_DEBUG("Different data in fragment %zu (addr_frag1 = %p - addr_frag2 = %p) of block %zu", j + 1, (char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), i);
388 void mmalloc_display_info_heap(xbt_mheap_t h){