Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : ignore stack areas in heap comparison algorithm for the comparison...
[simgrid.git] / src / xbt / mmalloc / mm_diff.c
index 3935b9f..8bc6173 100644 (file)
@@ -8,6 +8,7 @@
 #include "xbt/ex_interface.h" /* internals of backtrace setup */
 #include "xbt/str.h"
 #include "mc/mc.h"
+#include "xbt/mmalloc.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mm_diff, xbt,
                                 "Logging specific to mm_diff in mmalloc");
@@ -15,6 +16,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mm_diff, xbt,
 extern char *xbt_binary_name;
 
 xbt_dynar_t mmalloc_ignore;
+xbt_dynar_t stacks_areas;
 
 typedef struct s_heap_area_pair{
   int block1;
@@ -34,6 +36,8 @@ static void match_equals(xbt_dynar_t list);
 static int in_mmalloc_ignore(int block, int fragment);
 static size_t heap_comparison_ignore(void *address);
 
+static char* is_stack(void *address);
+
 void mmalloc_backtrace_block_display(void* heapinfo, int block){
 
   xbt_ex_t e;
@@ -91,7 +95,7 @@ size_t heaplimit, heapsize1, heapsize2;
 
 int ignore_done;
 
-int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
+int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t *stack1, xbt_dynar_t *stack2){
 
   if(heap1 == NULL && heap1 == NULL){
     XBT_DEBUG("Malloc descriptors null");
@@ -120,6 +124,8 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
   /* Start comparison */
   size_t i1, i2, j1, j2, k, current_block, current_fragment;
   void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
+  void *real_addr_block1, *real_addr_block2;
+  char *stack_name;
 
   xbt_dynar_t previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
 
@@ -172,6 +178,15 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
     addr_block1 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)heapbase1));
 
     if(heapinfo1[i1].type == 0){  /* Large block */
+      
+      real_addr_block1 = (char*)((xbt_mheap_t)s_heap)->heapbase + (((char *)addr_block1) - (char *)heapbase1);
+
+      if((stack_name = is_stack(real_addr_block1)) != NULL){
+        stack_region_t stack = xbt_new0(s_stack_region_t, 1);
+        stack->address = addr_block1;
+        stack->process_name = strdup(stack_name);
+        xbt_dynar_push(*stack1, &stack);
+      }
 
       if(heapinfo1[i1].busy_block.busy_size == 0){
         i1++;
@@ -187,7 +202,17 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
         if(heapinfo1[current_block].busy_block.busy_size == heapinfo2[current_block].busy_block.busy_size){
 
           addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)heapbase2));
+
+          real_addr_block2 = (char*)((xbt_mheap_t)s_heap)->heapbase + (((char *)addr_block2) - (char *)heapbase2);
           
+          if((stack_name = is_stack(real_addr_block2)) != NULL){
+            stack_region_t stack = xbt_new0(s_stack_region_t, 1);
+            stack->address = addr_block2;
+            stack->process_name = strdup(stack_name);
+            xbt_dynar_push(*stack2, &stack);
+          }
+
+        
           add_heap_area_pair(previous, current_block, -1, current_block, -1);
           
           if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
@@ -217,6 +242,17 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
 
       while(i2 <= heaplimit && !equal){
 
+        addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)heapbase2));
+        
+        real_addr_block2 = (char*)((xbt_mheap_t)s_heap)->heapbase + (((char *)addr_block2) - (char *)heapbase2);
+        
+        if((stack_name = is_stack(real_addr_block2)) != NULL){
+          stack_region_t stack = xbt_new0(s_stack_region_t, 1);
+          stack->address = addr_block2;
+          stack->process_name = strdup(stack_name);
+          xbt_dynar_push(*stack2, &stack);
+        }
+           
         if(i2 == current_block){
           i2++;
           continue;
@@ -242,8 +278,6 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
           continue;
         }
 
-        addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)heapbase2));
-
         /* Comparison */
         add_heap_area_pair(previous, i1, -1, i2, -1);
         
@@ -714,3 +748,142 @@ static void match_equals(xbt_dynar_t list){
 
 }
 
+#ifndef max
+       #define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
+#endif
+
+int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
+
+  if(heap1 == NULL && heap1 == NULL){
+    XBT_DEBUG("Malloc descriptors null");
+    return 0;
+  }
+
+  if(heap1->heaplimit != heap2->heaplimit){
+    XBT_DEBUG("Different limit of valid info table indices");
+    return 1;
+  }
+
+  /* Heap information */
+  heaplimit = ((struct mdesc *)heap1)->heaplimit;
+
+  s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
+
+  heapbase1 = (char *)heap1 + BLOCKSIZE;
+  heapbase2 = (char *)heap2 + BLOCKSIZE;
+
+  heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)heap1->heapinfo - (char *)s_heap)));
+  heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)heap2->heapinfo - (char *)s_heap)));
+
+  heapsize1 = heap1->heapsize;
+  heapsize2 = heap2->heapsize;
+
+  /* Start comparison */
+  size_t i, j, k;
+  void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
+
+  int distance = 0;
+
+  /* Check busy blocks*/
+
+  i = 1;
+
+  while(i <= heaplimit){
+
+    addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
+    addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
+
+    if(heapinfo1[i].type != heapinfo2[i].type){
+  
+      distance += BLOCKSIZE;
+      XBT_DEBUG("Different type of blocks (%zu) : %d - %d -> distance = %d", i, heapinfo1[i].type, heapinfo2[i].type, distance);
+      i++;
+    
+    }else{
+
+      if(heapinfo1[i].type == -1){ /* Free block */
+        i++;
+        continue;
+      }
+
+      if(heapinfo1[i].type == 0){ /* Large block */
+       
+        if(heapinfo1[i].busy_block.size != heapinfo2[i].busy_block.size){
+          distance += BLOCKSIZE * max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
+          i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
+          XBT_DEBUG("Different larger of cluster at block %zu : %zu - %zu -> distance = %d", i, heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size, distance);
+          continue;
+        }
+
+        /*if(heapinfo1[i].busy_block.busy_size != heapinfo2[i].busy_block.busy_size){
+          distance += max(heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size);
+          i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
+          XBT_DEBUG("Different size used oin large cluster at block %zu : %zu - %zu -> distance = %d", i, heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size, distance);
+          continue;
+          }*/
+
+        k = 0;
+
+        //while(k < (heapinfo1[i].busy_block.busy_size)){
+        while(k < heapinfo1[i].busy_block.size * BLOCKSIZE){
+          if(memcmp((char *)addr_block1 + k, (char *)addr_block2 + k, 1) != 0){
+            distance ++;
+          }
+          k++;
+        } 
+
+        i++;
+
+      }else { /* Fragmented block */
+
+        for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
+
+          addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
+          addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
+
+          if(heapinfo1[i].busy_frag.frag_size[j] == 0 && heapinfo2[i].busy_frag.frag_size[j] == 0){
+            continue;
+          }
+          
+          
+          /*if(heapinfo1[i].busy_frag.frag_size[j] != heapinfo2[i].busy_frag.frag_size[j]){
+            distance += max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j]);
+            XBT_DEBUG("Different size used in fragment %zu in block %zu : %d - %d -> distance = %d", j, i, heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j], distance); 
+            continue;
+            }*/
+   
+          k=0;
+
+          //while(k < max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j])){
+          while(k < (BLOCKSIZE / (BLOCKSIZE >> heapinfo1[i].type))){
+            if(memcmp((char *)addr_frag1 + k, (char *)addr_frag2 + k, 1) != 0){
+              distance ++;
+            }
+            k++;
+          }
+
+        }
+
+        i++;
+
+      }
+      
+    }
+
+  }
+
+  return distance;
+  
+}
+
+static char * is_stack(void *address){
+  unsigned int cursor = 0;
+  stack_region_t stack;
+
+  xbt_dynar_foreach(stacks_areas, cursor, stack){
+    if(address == stack->address)
+      return stack->process_name;
+  }
+
+  return NULL;
+}