Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
split memory snapshooting and diffing functions out in their own file
[simgrid.git] / src / xbt / mmalloc / mm_diff.c
1 /* mm_diff - Memory snapshooting and comparison                             */
2
3 /* Copyright (c) 2008-2012. The SimGrid Team. All rights reserved.          */
4
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. */
7
8
9 int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr){
10
11   if(mdp1 == NULL && mdp2 == NULL){
12     XBT_DEBUG("Malloc descriptors null");
13     return 0;
14   }
15
16   /* Heapstats */
17
18   int errors = mmalloc_compare_mdesc(mdp1, mdp2, std_heap_addr);
19
20   return (errors > 0);
21
22 }
23
24 int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap_addr){
25
26   int errors = 0;
27
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");
31       errors++;
32     }else{
33       return 1;
34     }
35   }
36
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");
40       errors++;
41     }else{
42       return 1;
43     }
44   }
45
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");
49       errors++;
50     }else{
51       return 1;
52     }
53   }
54
55   if(mdp1->flags != mdp2->flags){
56     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
57       XBT_DEBUG("Different flags");
58       errors++;
59     }else{
60       return 1;
61     }
62   }
63
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");
67       errors++;
68     }else{
69       return 1;
70     }
71   }
72
73   //XBT_DEBUG("Heap size : %zu", mdp1->heapsize);
74
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");
78       errors++;
79     }else{
80       return 1;
81     }
82   }
83
84
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);
88       errors++;
89     }else{
90       return 1;
91     }
92   }
93
94   //XBT_DEBUG("Heap index : %zu", mdp1->heapindex);
95
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");
99       errors++;
100     }else{
101       return 1;
102     }
103   }
104
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");
108       errors++;
109     }else{
110       return 1;
111     }
112   }
113
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");
117       errors++;
118     }else{
119       return 1;
120     }
121   }
122
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");
126       errors++;
127     }else{
128       return 1;
129     }
130   }
131
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");
135       errors++;
136     }else{
137       return 1;
138     }
139   }
140
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");
144       errors++;
145     }else{
146       return 1;
147     }
148   }
149
150
151   size_t block_free1, block_free2 , next_block_free, first_block_free, block_free ;
152   size_t i, j;
153   void *addr_block1, *addr_block2;
154   size_t frag_size;
155
156
157   /* Search index of the first free block */
158
159   block_free1 = mdp1->heapindex;
160   block_free2 = mdp2->heapindex;
161
162   while(mdp1->heapinfo[block_free1].free_block.prev != 0){
163     block_free1 = mdp1->heapinfo[block_free1].free_block.prev;
164   }
165
166   while(mdp2->heapinfo[block_free2].free_block.prev != 0){
167     block_free2 = mdp1->heapinfo[block_free2].free_block.prev;
168   }
169
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");
173       errors++;
174     }else{
175       return 1;
176     }
177   }
178
179   first_block_free = block_free1;
180
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");
184       errors++;
185     }else{
186       return 1;
187     }
188   }
189
190   /* Check busy blocks (circular checking)*/
191
192   i = first_block_free + mdp1->heapinfo[first_block_free].free_block.size;
193
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");
197       errors++;
198     }else{
199       return 1;
200     }
201   }
202
203   block_free = first_block_free;
204   next_block_free = mdp1->heapinfo[first_block_free].free_block.next;
205
206   if(next_block_free == 0)
207     next_block_free = mdp1->heaplimit;
208
209   while(i != first_block_free){
210
211     while(i<next_block_free){
212
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");
216           errors++;
217         }else{
218           return 1;
219         }
220       }else{
221
222         addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
223         addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
224
225         switch(mdp1->heapinfo[i].type){ //FIXME deal with type<0 == free
226         case 0 :
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");
230               errors++;
231             }else{
232               return 1;
233             }
234           }else{
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);
238                 errors++;
239               }else{
240                 return 1;
241               }
242             }
243           }
244           i = i+mdp1->heapinfo[i].busy_block.size;
245
246           break;
247         default :
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);
251               errors++;
252             }else{
253               return 1;
254             }
255           }else{
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);
259                 errors++;
260               }else{
261                 return 1;
262               }
263             }else{
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);
269                     errors++;
270                   }else{
271                     return 1;
272                   }
273                 }
274               }
275             }
276           }
277
278           i++;
279
280           break;
281         }
282
283       }
284     }
285
286     if( i != first_block_free){
287
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");
291           errors++;
292         }else{
293           return 1;
294         }
295       }
296
297       block_free = mdp1->heapinfo[block_free].free_block.next;
298       next_block_free = mdp1->heapinfo[block_free].free_block.next;
299
300       i = block_free + mdp1->heapinfo[block_free].free_block.size;
301
302       if((next_block_free == 0) && (i != mdp1->heaplimit)){
303
304         while(i < mdp1->heaplimit){
305
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");
309               errors++;
310             }else{
311               return 1;
312             }
313           }else{
314
315             addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
316             addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
317
318             switch(mdp1->heapinfo[i].type){
319             case 0 :
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");
323                   errors++;
324                 }else{
325                   return 1;
326                 }
327               }else{
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);
331                     errors++;
332                   }else{
333                     return 1;
334                   }
335                 }
336               }
337
338               i = i+mdp1->heapinfo[i].busy_block.size;
339
340               break;
341             default :
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);
345                   errors++;
346                 }else{
347                   return 1;
348                 }
349               }else{
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);
353                     errors++;
354                   }else{
355                     return 1;
356                   }
357                 }else{
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);
363                         errors++;
364                       }else{
365                         return 1;
366                       }
367                     }
368                   }
369                 }
370               }
371
372               i++;
373
374               break;
375             }
376           }
377         }
378
379       }
380
381     }
382   }
383
384   return (errors>0);
385 }
386
387
388 void mmalloc_display_info_heap(xbt_mheap_t h){
389
390 }
391
392
393