Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch mc into mc-perf
authorGabriel Corona <gabriel.corona@loria.fr>
Fri, 7 Feb 2014 12:16:09 +0000 (13:16 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Fri, 7 Feb 2014 13:27:47 +0000 (14:27 +0100)
13 files changed:
CMakeLists.txt
buildtools/Cmake/DefinePackages.cmake
include/xbt/mmalloc.h
src/include/mc/datatypes.h
src/mc/mc_checkpoint.c
src/mc/mc_compare.c
src/mc/mc_dwarf.c
src/mc/mc_global.c
src/mc/mc_hash.c [new file with mode: 0644]
src/mc/mc_private.h
src/mc/mc_set.cpp [new file with mode: 0644]
src/simix/smx_network.c
src/xbt/mmalloc/mm_diff.c

index a21be2a..747d9fc 100644 (file)
@@ -4,7 +4,7 @@ if(WIN32)
   SET(CMAKE_RC_COMPILER "windres")
 endif()
 project(SimGrid C)
-if (enable_gtnets OR enable_ns3)
+if (enable_gtnets OR enable_ns3 OR enable_model-checking)
   enable_language(CXX)
 endif()
 if (NOT DEFINED enable_smpi OR enable_smpi) # smpi is enabled by default
index b9854a6..41b6fab 100644 (file)
@@ -525,6 +525,8 @@ set(MC_SRC
   src/mc/mc_state.c
   src/mc/memory_map.c
   src/mc/mc_pair.c
+  src/mc/mc_hash.c
+  src/mc/mc_set.cpp
   )
 
 set(headers_to_install
index 9708a76..1f37dda 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "xbt/dynar.h"
 #include "xbt/dict.h"
+#include "mc/datatypes.h"
 
 /* Datatype representing a separate heap. The whole point of the mmalloc module
  * is to allow several such heaps in the process. It thus works by redefining
@@ -38,6 +39,7 @@ void *mmalloc_no_memset(xbt_mheap_t mdp, size_t size);
 
 /* Re-allocate the previously allocated block in void*, making the new block
    SIZE bytes long.  */
+
 XBT_PUBLIC( void ) *mrealloc(xbt_mheap_t md, void *ptr, size_t size);
 
 /* Free a block allocated by `mmalloc', `mrealloc' or `mcalloc'.  */
@@ -56,10 +58,10 @@ XBT_PUBLIC( xbt_mheap_t ) mmalloc_get_default_md(void);
 void mmalloc_set_current_heap(xbt_mheap_t new_heap);
 xbt_mheap_t mmalloc_get_current_heap(void);
 
-int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dict_t all_types, xbt_dict_t other_types);
+int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, mc_object_info_t info, mc_object_info_t other_info);
 int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2);
 int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t to_ignore1, xbt_dynar_t to_ignore2);
-int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type, int pointer_level);
+int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, mc_object_info_t info, mc_object_info_t other_info, char *type, int pointer_level);
 void reset_heap_information(void);
 int get_pointed_area_size(void *area, int heap);
 
index d13ce8c..d9095c0 100644 (file)
@@ -40,11 +40,17 @@ typedef struct s_stack_region{
 void heap_ignore_region_free(mc_heap_ignore_region_t r);
 void heap_ignore_region_free_voidp(void *r);
 
+/************ Object info *************/
+
+typedef struct s_mc_object_info s_mc_object_info_t, *mc_object_info_t;
+
 /************ DWARF structures *************/
 
 typedef int e_dw_type_type;
 
-typedef struct s_dw_type{
+typedef struct s_dw_type s_dw_type_t, *dw_type_t;
+
+struct s_dw_type{
   e_dw_type_type type;
   void *id; /* Offset in the section (in hexadecimal form) */
   char *name; /* Name of the type */
@@ -54,9 +60,10 @@ typedef struct s_dw_type{
   xbt_dynar_t members; /* if DW_TAG_structure_type, DW_TAG_union_type*/
   int is_pointer_type;
   int offset;
-}s_dw_type_t, *dw_type_t;
+  dw_type_t subtype;
+};
 
-char* get_type_description(xbt_dict_t types, char *type_name);
+char* get_type_description(mc_object_info_t info, char *type_name);
 
 SG_END_DECL()
 #endif                          /* _MC_MC_H */
index 7e8d185..035e6b5 100644 (file)
@@ -9,6 +9,7 @@
 #include <link.h>
 #include "mc_private.h"
 #include "xbt/module.h"
+#include <xbt/mmalloc.h>
 
 #include "../simix/smx_private.h"
 
@@ -72,10 +73,10 @@ void MC_free_snapshot(mc_snapshot_t snapshot){
 
 static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size)
 {
-  mc_mem_region_t new_reg = xbt_new0(s_mc_mem_region_t, 1);
+  mc_mem_region_t new_reg = xbt_new(s_mc_mem_region_t, 1);
   new_reg->start_addr = start_addr;
   new_reg->size = size;
-  new_reg->data = xbt_malloc0(size);
+  new_reg->data = xbt_malloc(size);
   memcpy(new_reg->data, start_addr, size);
 
   XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu", type, new_reg->data, start_addr, size);
@@ -239,8 +240,45 @@ void MC_init_memory_map_info(){
 
 }
 
+/** \brief Fill/llokup the "subtype" field.
+ */
+static void MC_resolve_subtype(mc_object_info_t info, dw_type_t type) {
+
+  if(type->dw_type_id==NULL)
+    return;
+  type->subtype = xbt_dict_get_or_null(info->types, type->dw_type_id);
+  if(type->subtype==NULL)
+    return;
+  if(type->subtype->byte_size != 0)
+    return;
+  if(type->subtype->name==NULL)
+    return;
+  // Try to find a more complete description of the type:
+  // We need to fix in order to support C++.
+
+  dw_type_t subtype = xbt_dict_get_or_null(info->types_by_name, type->subtype->name);
+  if(subtype!=NULL) {
+    type->subtype = subtype;
+  }
+
+  // TODO, support "switch type" (looking up the type in another lib) when possible
+}
+
 static void MC_post_process_types(mc_object_info_t info) {
-  // Nothing here
+  xbt_dict_cursor_t cursor = NULL;
+  char *origin;
+  dw_type_t type;
+
+  // Lookup "subtype" field:
+  xbt_dict_foreach(info->types, cursor, origin, type){
+    MC_resolve_subtype(info, type);
+
+    dw_type_t member;
+    unsigned int i = 0;
+    if(type->members!=NULL) xbt_dynar_foreach(type->members, i, member) {
+      MC_resolve_subtype(info, member);
+    }
+  }
 }
 
 /** \brief Finds informations about a given shared object/executable */
@@ -295,102 +333,6 @@ static void MC_find_object_address(memory_map_t maps, mc_object_info_t result) {
 /************************************* Take Snapshot ************************************/
 /****************************************************************************************/
 
-static void MC_get_hash_global(char *snapshot_hash, void *data1, void *data2){
-  
-  /* unsigned int cursor = 0; */
-  /* size_t offset;  */
-  /* global_variable_t current_var;  */
-  /* void *addr_pointed = NULL; */
-  /* void *res = NULL; */
-
-  /* xbt_strbuff_t clear = xbt_strbuff_new(); */
-  
-  /* xbt_dynar_foreach(mc_global_variables, cursor, current_var){ */
-  /*   if(current_var->address < start_data_libsimgrid){ /\* binary *\/ */
-  /*     offset = (char *)current_var->address - (char *)start_data_binary; */
-  /*     addr_pointed = *((void **)((char *)data2 + offset)); */
-  /*     if(((addr_pointed >= start_plt_binary && addr_pointed <= end_plt_binary)) || ((addr_pointed >= std_heap && (char *)addr_pointed <= (char *)std_heap + STD_HEAP_SIZE ))) */
-  /*       continue; */
-  /*     res = xbt_malloc0(current_var->size + 1); */
-  /*     memset(res, 0, current_var->size + 1); */
-  /*     memcpy(res, (char*)data2 + offset, current_var->size); */
-  /*   }else{ /\* libsimgrid *\/ */
-  /*     offset = (char *)current_var->address - (char *)start_data_libsimgrid; */
-  /*     addr_pointed = *((void **)((char *)data1 + offset)); */
-  /*     if((addr_pointed >= start_plt_libsimgrid && addr_pointed <= end_plt_libsimgrid) || (addr_pointed >= std_heap && (char *)addr_pointed <= (char *)std_heap + STD_HEAP_SIZE )) */
-  /*       continue; */
-  /*     res = xbt_malloc0(current_var->size + 1); */
-  /*     memset(res, 0, current_var->size + 1); */
-  /*     memcpy(res, (char*)data1 + offset, current_var->size); */
-  /*   } */
-  /*   if(res != NULL){ */
-  /*     xbt_strbuff_append(clear, (const char*)res); */
-  /*     xbt_free(res); */
-  /*     res = NULL; */
-  /*   } */
-  /* } */
-
-  /* xbt_sha(clear->data, snapshot_hash); */
-
-  /* xbt_strbuff_free(clear); */
-
-}
-
-static void MC_get_hash_local(char *snapshot_hash, xbt_dynar_t stacks){
-
-  /* xbt_dynar_t tokens = NULL, s_tokens = NULL; */
-  /* unsigned int cursor1 = 0, cursor2 = 0; */
-  /* mc_snapshot_stack_t current_stack; */
-  /* char *frame_name = NULL; */
-  /* void *addr; */
-
-  /* xbt_strbuff_t clear = xbt_strbuff_new(); */
-
-  /* while(cursor1 < xbt_dynar_length(stacks)){ */
-  /*   current_stack = xbt_dynar_get_as(stacks, cursor1, mc_snapshot_stack_t); */
-  /*   tokens = xbt_str_split(current_stack->local_variables->data, NULL); */
-  /*   cursor2 = 0; */
-  /*   while(cursor2 < xbt_dynar_length(tokens)){ */
-  /*     s_tokens = xbt_str_split(xbt_dynar_get_as(tokens, cursor2, char *), "="); */
-  /*     if(xbt_dynar_length(s_tokens) > 1){ */
-  /*       if(strcmp(xbt_dynar_get_as(s_tokens, 0, char *), "frame_name") == 0){ */
-  /*         xbt_free(frame_name); */
-  /*         frame_name = xbt_strdup(xbt_dynar_get_as(s_tokens, 1, char *)); */
-  /*         xbt_strbuff_append(clear, (const char*)xbt_dynar_get_as(tokens, cursor2, char *)); */
-  /*         cursor2++; */
-  /*         xbt_dynar_free(&s_tokens); */
-  /*         continue; */
-  /*       } */
-  /*       addr = (void *) strtoul(xbt_dynar_get_as(s_tokens, 1, char *), NULL, 16); */
-  /*       if(addr > std_heap && (char *)addr <= (char *)std_heap + STD_HEAP_SIZE){ */
-  /*         cursor2++; */
-  /*         xbt_dynar_free(&s_tokens); */
-  /*         continue; */
-  /*       } */
-  /*       if(is_stack_ignore_variable(frame_name, xbt_dynar_get_as(s_tokens, 0, char *))){ */
-  /*         cursor2++; */
-  /*         xbt_dynar_free(&s_tokens); */
-  /*         continue; */
-  /*       } */
-  /*       xbt_strbuff_append(clear, (const char *)xbt_dynar_get_as(tokens, cursor2, char *)); */
-  /*     } */
-  /*     xbt_dynar_free(&s_tokens); */
-  /*     cursor2++; */
-  /*   } */
-  /*   xbt_dynar_free(&tokens); */
-  /*   cursor1++; */
-  /* } */
-
-  /* xbt_free(frame_name); */
-
-  /* xbt_sha(clear->data, snapshot_hash); */
-
-  /* xbt_strbuff_free(clear); */
-
-}
-
-
-
 static xbt_dynar_t MC_get_local_variables_values(void *stack_context){
   
   unw_cursor_t c;
@@ -409,8 +351,7 @@ static xbt_dynar_t MC_get_local_variables_values(void *stack_context){
 
   unsigned int cursor = 0;
   dw_variable_t current_variable;
-  dw_location_entry_t entry = NULL;
-  int frame_found = 0, region_type;
+  int region_type;
   void *frame_pointer_address = NULL;
   long true_ip;
   int stop = 0;
@@ -438,27 +379,8 @@ static xbt_dynar_t MC_get_local_variables_values(void *stack_context){
     }
     
     true_ip = (long)frame->low_pc + (long)off;
-    frame_pointer_address = NULL;
-
-    /* Get frame pointer */
-    switch(frame->frame_base->type){
-    case e_dw_loclist:
-      cursor = 0;
-      while(cursor < xbt_dynar_length(frame->frame_base->location.loclist) && !frame_found){
-        entry = xbt_dynar_get_as(frame->frame_base->location.loclist, cursor, dw_location_entry_t);
-        if((true_ip >= entry->lowpc) && (true_ip < entry->highpc)){
-          frame_found = 1;
-          frame_pointer_address =  (void*) MC_dwarf_resolve_location(&c, entry->location, NULL);
-        }
-        cursor++;
-      }
-      break;
-    default :
-      frame_pointer_address = NULL; /* FIXME : implement other cases (with optimizations enabled)*/
-      break;
-    }
+    frame_pointer_address = mc_find_frame_base(true_ip, frame, &c);
 
-    frame_found = 0;
     cursor = 0;
 
     xbt_dynar_foreach(frame->variables, cursor, current_variable){
@@ -584,6 +506,11 @@ mc_snapshot_t MC_take_snapshot(int num_state){
 
   mc_snapshot_t snapshot = xbt_new0(s_mc_snapshot_t, 1);
   snapshot->nb_processes = xbt_swag_size(simix_global->process_list);
+  if(MC_USE_SNAPSHOT_HASH) {
+    snapshot->hash = mc_hash_processes_state(num_state);
+  } else {
+    snapshot->hash = 0;
+  }
 
   /* Save the std heap and the writable mapped pages of libsimgrid and binary */
   MC_get_memory_regions(snapshot);
@@ -592,8 +519,6 @@ mc_snapshot_t MC_take_snapshot(int num_state){
 
   if(_sg_mc_visited > 0 || strcmp(_sg_mc_property_file,"")){
     snapshot->stacks = MC_take_snapshot_stacks(&snapshot, snapshot->regions[0]->data);
-    //MC_get_hash_global(snapshot->hash_global, snapshot->regions[1]->data, snapshot->regions[2]->data);
-    //MC_get_hash_local(snapshot->hash_local, snapshot->stacks);
   }
 
   if(num_state > 0)
index 9543f09..6918459 100644 (file)
@@ -4,6 +4,8 @@
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
+#include <inttypes.h>
+
 #include "mc_private.h"
 
 #include "xbt/mmalloc.h"
@@ -122,9 +124,8 @@ static void add_compared_pointers(void *p1, void *p2){
 
 }
 
-static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, xbt_dict_t other_types, char *type_id, int region_size, int region_type, void *start_data, int pointer_level){
+static int compare_areas_with_type(void *area1, void *area2, mc_object_info_t info, mc_object_info_t other_info, dw_type_t type, int region_size, int region_type, void *start_data, int pointer_level){
 
-  dw_type_t type = xbt_dict_get_or_null(types, type_id);;
   unsigned int cursor = 0;
   dw_type_t member, subtype, subsubtype;
   int elm_size, i, res, switch_types = 0;
@@ -139,10 +140,10 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x
   case DW_TAG_typedef:
   case DW_TAG_volatile_type:
   case DW_TAG_const_type:
-    return compare_areas_with_type(area1, area2, types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level);
+    return compare_areas_with_type(area1, area2, info, other_info, type->subtype, region_size, region_type, start_data, pointer_level);
     break;
   case DW_TAG_array_type:
-    subtype = xbt_dict_get_or_null(types, type->dw_type_id);
+    subtype = type->subtype;
     switch(subtype->type){
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
@@ -150,9 +151,11 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
       if(subtype->byte_size == 0){ /*declaration of the type, need the complete description */
-        subtype = xbt_dict_get_or_null(types, get_type_description(types, subtype->name));
-        if(subtype == NULL){
-          subtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name));
+        dw_type_t full_type = xbt_dict_get_or_null(other_info->types_by_name, subtype->name);
+        if(full_type) {
+          type = full_type;
+        } else {
+          subtype = xbt_dict_get_or_null(other_info->types_by_name, subtype->name);
           switch_types = 1;
         }
       }
@@ -161,13 +164,10 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x
     case DW_TAG_const_type:
     case DW_TAG_typedef:
     case DW_TAG_volatile_type:
-      subsubtype = xbt_dict_get_or_null(types, subtype->dw_type_id);
+      subsubtype = subtype->subtype;
       if(subsubtype->byte_size == 0){ /*declaration of the type, need the complete description */
-        subsubtype = xbt_dict_get_or_null(types, get_type_description(types, subsubtype->name));
-        if(subsubtype == NULL){
-          subsubtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subsubtype->name));
+          subsubtype = xbt_dict_get_or_null(other_info->types_by_name, subsubtype->name);
           switch_types = 1;
-        }
       }
       elm_size = subsubtype->byte_size;
       break;
@@ -177,15 +177,15 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x
     }
     for(i=0; i<type->element_count; i++){
       if(switch_types)
-        res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), other_types, types, type->dw_type_id, region_size, region_type, start_data, pointer_level);
+        res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), other_info, info, type->subtype, region_size, region_type, start_data, pointer_level);
       else
-        res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level);
+        res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), info, other_info, type->subtype, region_size, region_type, start_data, pointer_level);
       if(res == 1)
         return res;
     }
     break;
   case DW_TAG_pointer_type:
-    if(type->dw_type_id && ((dw_type_t)xbt_dict_get_or_null(types, type->dw_type_id))->type == DW_TAG_subroutine_type){
+    if(type->dw_type_id && ((dw_type_t)xbt_dict_get_or_null(info->types, type->dw_type_id))->type == DW_TAG_subroutine_type){
       addr_pointed1 = *((void **)(area1)); 
       addr_pointed2 = *((void **)(area2));
       return (addr_pointed1 != addr_pointed2);
@@ -210,7 +210,7 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x
       if(addr_pointed1 > std_heap && (char *)addr_pointed1 < (char*) std_heap + STD_HEAP_SIZE){
         if(!(addr_pointed2 > std_heap && (char *)addr_pointed2 < (char*) std_heap + STD_HEAP_SIZE))
           xbt_die("Die");
-        return compare_heap_area(addr_pointed1, addr_pointed2, NULL, types, other_types, type->dw_type_id, pointer_level); 
+        return compare_heap_area(addr_pointed1, addr_pointed2, NULL, info, other_info, type->dw_type_id, pointer_level);
       }
 
       // The pointers are both in the current object R/W segment:
@@ -220,7 +220,7 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x
         if(type->dw_type_id == NULL)
           return  (addr_pointed1 != addr_pointed2);
         else
-          return  compare_areas_with_type(addr_pointed1, addr_pointed2, types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level); 
+          return  compare_areas_with_type(addr_pointed1, addr_pointed2, info, other_info, type->subtype, region_size, region_type, start_data, pointer_level);
       }
 
       else{
@@ -230,7 +230,8 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x
     break;
   case DW_TAG_structure_type:
     xbt_dynar_foreach(type->members, cursor, member){
-      res = compare_areas_with_type((char *)area1 + member->offset, (char *)area2 + member->offset, types, other_types, member->dw_type_id, region_size, region_type, start_data, pointer_level);
+      XBT_DEBUG("Compare member %s", member->name);
+      res = compare_areas_with_type((char *)area1 + member->offset, (char *)area2 + member->offset, info, other_info, member->subtype, region_size, region_type, start_data, pointer_level);
       if(res == 1)
         return res;
     }
@@ -256,7 +257,6 @@ static int compare_global_variables(int region_type, mc_mem_region_t r1, mc_mem_
   }
 
   xbt_dynar_t variables;
-  xbt_dict_t types, other_types;
   int res;
   unsigned int cursor = 0;
   dw_variable_t current_var;
@@ -277,8 +277,6 @@ static int compare_global_variables(int region_type, mc_mem_region_t r1, mc_mem_
     start_data = start_data_libsimgrid;
   }
   variables = object_info->global_variables;
-  types = object_info->types;
-  other_types = other_object_info->types;
 
   xbt_dynar_foreach(variables, cursor, current_var){
 
@@ -291,7 +289,8 @@ static int compare_global_variables(int region_type, mc_mem_region_t r1, mc_mem_
 
     offset = (char *)current_var->address - (char *)object_info->start_rw;
 
-    res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, types, other_types, current_var->type_origin, r1->size, region_type, start_data, 0);
+    dw_type_t bvariable_type = xbt_dict_get_or_null(object_info->types, current_var->type_origin);
+    res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, object_info, other_object_info, bvariable_type, r1->size, region_type, start_data, 0);
     if(res == 1){
       XBT_VERB("Global variable %s (%p - %p) is different between snapshots", current_var->name, (char *)r1->data + offset, (char *)r2->data + offset);
       xbt_dynar_free(&compared_pointers);
@@ -338,10 +337,16 @@ static int compare_local_variables(mc_snapshot_stack_t stack1, mc_snapshot_stack
       }
       offset1 = (char *)current_var1->address - (char *)std_heap;
       offset2 = (char *)current_var2->address - (char *)std_heap;
-      if(current_var1->region == 1)
-        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_libsimgrid_info->types, mc_binary_info->types, current_var1->type, 0, 1, start_data_libsimgrid, 0);
-      else
-        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_binary_info->types, mc_libsimgrid_info->types, current_var1->type, 0, 2, start_data_binary, 0);
+      XBT_DEBUG("Compare local variable %s of frame %s", current_var1->name, current_var1->frame);
+
+
+      if(current_var1->region == 1) {
+        dw_type_t subtype = xbt_dict_get_or_null(mc_libsimgrid_info->types, current_var1->type);
+        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_libsimgrid_info, mc_binary_info, subtype, 0, 1, start_data_libsimgrid, 0);
+      } else {
+        dw_type_t subtype = xbt_dict_get_or_null(mc_binary_info->types, current_var1->type);
+        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_binary_info, mc_libsimgrid_info, subtype, 0, 2, start_data_binary, 0);
+      }
       if(res == 1){
         XBT_VERB("Local variable %s (%p - %p) in frame %s  is different between snapshots", current_var1->name,(char *)heap1 + offset1, (char *)heap2 + offset2, current_var1->frame);
         xbt_dynar_free(&compared_pointers);
@@ -390,10 +395,21 @@ int snapshot_compare(void *state1, void *state2){
     xbt_os_walltimer_start(timer);
   #endif
 
-  /* Compare size of stacks */
+  if(MC_USE_SNAPSHOT_HASH) {
+    if(s1->hash != s2->hash) {
+      XBT_VERB("(%d - %d) Different hash : 0x%" PRIx64 "--0x%" PRIx64, num1, num2, s1->hash, s2->hash);
+      return 1;
+    } else {
+      XBT_VERB("(%d - %d) Same hash : 0x%" PRIx64, num1, num2, s1->hash);
+    }
+  }
+
   int i = 0;
   size_t size_used1, size_used2;
   int is_diff = 0;
+
+
+  /* Compare size of stacks */
   while(i < xbt_dynar_length(s1->stacks)){
     size_used1 = s1->stack_sizes[i];
     size_used2 = s2->stack_sizes[i];
@@ -429,62 +445,6 @@ int snapshot_compare(void *state1, void *state2){
     xbt_os_walltimer_start(timer);
   #endif
 
-  /* Compare hash of global variables */
-  if(s1->hash_global != NULL && s2->hash_global != NULL){
-    if(strcmp(s1->hash_global, s2->hash_global) != 0){
-      #ifdef MC_DEBUG
-        xbt_os_walltimer_stop(timer);
-        mc_comp_times->hash_global_variables_comparison_time = xbt_os_timer_elapsed(timer);
-        XBT_DEBUG("Different hash of global variables : %s - %s", s1->hash_global, s2->hash_global); 
-        errors++; 
-      #else
-        #ifdef MC_VERBOSE
-          XBT_VERB("Different hash of global variables : %s - %s", s1->hash_global, s2->hash_global); 
-        #endif
-
-        xbt_os_walltimer_stop(timer);
-        xbt_os_timer_free(timer);
-        xbt_os_walltimer_stop(global_timer);
-        mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
-        xbt_os_timer_free(global_timer);
-
-        return 1;
-      #endif
-    }
-  }
-
-  #ifdef MC_DEBUG
-    xbt_os_walltimer_start(timer);
-  #endif
-
-  /* Compare hash of local variables */
-  if(s1->hash_local != NULL && s2->hash_local != NULL){
-    if(strcmp(s1->hash_local, s2->hash_local) != 0){
-      #ifdef MC_DEBUG
-        xbt_os_walltimer_stop(timer);
-        mc_comp_times->hash_local_variables_comparison_time = xbt_os_timer_elapsed(timer);
-        XBT_DEBUG("Different hash of local variables : %s - %s", s1->hash_local, s2->hash_local); 
-        errors++; 
-      #else
-        #ifdef MC_VERBOSE
-          XBT_VERB("Different hash of local variables : %s - %s", s1->hash_local, s2->hash_local); 
-        #endif
-
-        xbt_os_walltimer_stop(timer);
-        xbt_os_timer_free(timer);
-        xbt_os_walltimer_stop(global_timer);
-        mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
-        xbt_os_timer_free(global_timer);
-
-        return 1;
-      #endif
-    }
-  }
-
-  #ifdef MC_DEBUG
-    xbt_os_walltimer_start(timer);
-  #endif
-
   /* Init heap information used in heap comparison algorithm */
   res_init = init_heap_information((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data, s1->to_ignore, s2->to_ignore);
   if(res_init == -1){
@@ -597,8 +557,8 @@ int snapshot_compare(void *state1, void *state2){
   /* Compare heap */
     if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[0]->data,
                             (xbt_mheap_t)s2->regions[0]->data,
-                            mc_libsimgrid_info->types,
-                            mc_binary_info->types) > 0){
+                            mc_libsimgrid_info,
+                            mc_binary_info) > 0){
 
     #ifdef MC_DEBUG
       xbt_os_walltimer_stop(timer);
@@ -642,6 +602,10 @@ int snapshot_compare(void *state1, void *state2){
     print_comparison_times();
   #endif
 
+#ifdef MC_VERBOSE
+   if(errors==0)
+     XBT_VERB("(%d - %d) No difference found", num1, num2);
+#endif
   return errors > 0;
   
 }
index 84e4260..3ff5e98 100644 (file)
@@ -1,6 +1,5 @@
 /* Copyright (c) 2008-2013. The SimGrid Team.
  * All rights reserved.                                                     */
-
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
@@ -634,6 +633,10 @@ static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die* die, Dwar
 
   char* key = bprintf("%" PRIx64, (uint64_t) type->id);
   xbt_dict_set(info->types, key, type, NULL);
+
+  if(type->name && type->byte_size!=0) {
+    xbt_dict_set(info->types_by_name, type->name, type, NULL);
+  }
 }
 
 /** \brief Convert libdw location expresion elment into native one (or NULL in some cases) */
@@ -947,7 +950,16 @@ void MC_dwarf_get_variables(mc_object_info_t info) {
   size_t length;
   while (dwarf_nextcu (dwarf, offset, &next_offset, &length, NULL, NULL, NULL) == 0) {
     Dwarf_Die die;
+
     if(dwarf_offdie(dwarf, offset+length, &die)!=NULL) {
+
+      // Skip C++ for now (we will add support for it soon):
+      int lang = dwarf_srclang(&die);
+      if((lang==DW_LANG_C_plus_plus) || (lang==DW_LANG_ObjC_plus_plus)) {
+        offset = next_offset;
+        continue;
+      }
+
       MC_dwarf_handle_die(info, &die, &die, NULL);
     }
     offset = next_offset;
index e0a8bdd..c9cb9fd 100644 (file)
@@ -115,8 +115,6 @@ mc_object_info_t mc_libsimgrid_info = NULL;
 mc_object_info_t mc_binary_info = NULL;
 
 /* Ignore mechanism */
-xbt_dynar_t mc_stack_comparison_ignore;
-xbt_dynar_t mc_data_bss_comparison_ignore;
 extern xbt_dynar_t mc_heap_comparison_ignore;
 extern xbt_dynar_t stacks_areas;
 
@@ -180,6 +178,7 @@ mc_object_info_t MC_new_object_info(void) {
   res->local_variables = xbt_dict_new_homogeneous(NULL);
   res->global_variables = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp);
   res->types = xbt_dict_new_homogeneous(NULL);
+  res->types_by_name = xbt_dict_new_homogeneous(NULL);
   return res;
 }
 
@@ -188,6 +187,7 @@ void MC_free_object_info(mc_object_info_t* info) {
   xbt_dict_free(&(*info)->local_variables);
   xbt_dynar_free(&(*info)->global_variables);
   xbt_dict_free(&(*info)->types);
+  xbt_dict_free(&(*info)->types_by_name);
   xbt_free(info);
   *info = NULL;
 }
@@ -433,6 +433,7 @@ void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame, dw_vari
     MC_dwarf_register_non_global_variable(info, frame, variable);
 }
 
+
 /*******************************  Ignore mechanism *******************************/
 /*********************************************************************************/
 
@@ -443,10 +444,6 @@ typedef struct s_mc_stack_ignore_variable{
   char *frame;
 }s_mc_stack_ignore_variable_t, *mc_stack_ignore_variable_t;
 
-typedef struct s_mc_data_bss_ignore_variable{
-  char *name;
-}s_mc_data_bss_ignore_variable_t, *mc_data_bss_ignore_variable_t;
-
 /**************************** Free functions ******************************/
 
 static void stack_ignore_variable_free(mc_stack_ignore_variable_t v){
@@ -467,15 +464,6 @@ void heap_ignore_region_free_voidp(void *r){
   heap_ignore_region_free((mc_heap_ignore_region_t) * (void **) r);
 }
 
-static void data_bss_ignore_variable_free(mc_data_bss_ignore_variable_t v){
-  xbt_free(v->name);
-  xbt_free(v);
-}
-
-static void data_bss_ignore_variable_free_voidp(void *v){
-  data_bss_ignore_variable_free((mc_data_bss_ignore_variable_t) * (void **) v);
-}
-
 static void checkpoint_ignore_region_free(mc_checkpoint_ignore_region_t r){
   xbt_free(r);
 }
@@ -590,7 +578,7 @@ void MC_ignore_global_variable(const char *name){
 
   MC_SET_RAW_MEM;
 
-  if(mc_libsimgrid_info){
+  xbt_assert(mc_libsimgrid_info, "MC subsystem not initialized");
 
     unsigned int cursor = 0;
     dw_variable_t current_var;
@@ -610,49 +598,6 @@ void MC_ignore_global_variable(const char *name){
         end = cursor - 1;
       } 
     }
-   
-  }else{
-
-    if(mc_data_bss_comparison_ignore == NULL)
-      mc_data_bss_comparison_ignore = xbt_dynar_new(sizeof(mc_data_bss_ignore_variable_t), data_bss_ignore_variable_free_voidp);
-
-    mc_data_bss_ignore_variable_t var = NULL;
-    var = xbt_new0(s_mc_data_bss_ignore_variable_t, 1);
-    var->name = strdup(name);
-
-    if(xbt_dynar_is_empty(mc_data_bss_comparison_ignore)){
-
-      xbt_dynar_insert_at(mc_data_bss_comparison_ignore, 0, &var);
-
-    }else{
-    
-      unsigned int cursor = 0;
-      int start = 0;
-      int end = xbt_dynar_length(mc_data_bss_comparison_ignore) - 1;
-      mc_data_bss_ignore_variable_t current_var = NULL;
-
-      while(start <= end){
-        cursor = (start + end) / 2;
-        current_var = (mc_data_bss_ignore_variable_t)xbt_dynar_get_as(mc_data_bss_comparison_ignore, cursor, mc_data_bss_ignore_variable_t);
-        if(strcmp(current_var->name, name) == 0){
-          data_bss_ignore_variable_free(var);
-          if(!raw_mem_set)
-            MC_UNSET_RAW_MEM;
-          return;
-        }else if(strcmp(current_var->name, name) < 0){
-          start = cursor + 1;
-        }else{
-          end = cursor - 1;
-        }
-      }
-
-      if(strcmp(current_var->name, name) < 0)
-        xbt_dynar_insert_at(mc_data_bss_comparison_ignore, cursor + 1, &var);
-      else
-        xbt_dynar_insert_at(mc_data_bss_comparison_ignore, cursor, &var);
-
-    }
-  }
 
   if(!raw_mem_set)
     MC_UNSET_RAW_MEM;
@@ -664,7 +609,6 @@ void MC_ignore_local_variable(const char *var_name, const char *frame_name){
 
   MC_SET_RAW_MEM;
 
-  if(mc_libsimgrid_info){
     unsigned int cursor = 0;
     dw_variable_t current_var;
     int start, end;
@@ -725,61 +669,6 @@ void MC_ignore_local_variable(const char *var_name, const char *frame_name){
         } 
       }
     } 
-  }else{
-
-    if(mc_stack_comparison_ignore == NULL)
-      mc_stack_comparison_ignore = xbt_dynar_new(sizeof(mc_stack_ignore_variable_t), stack_ignore_variable_free_voidp);
-  
-    mc_stack_ignore_variable_t var = NULL;
-    var = xbt_new0(s_mc_stack_ignore_variable_t, 1);
-    var->var_name = strdup(var_name);
-    var->frame = strdup(frame_name);
-  
-    if(xbt_dynar_is_empty(mc_stack_comparison_ignore)){
-
-      xbt_dynar_insert_at(mc_stack_comparison_ignore, 0, &var);
-
-    }else{
-    
-      unsigned int cursor = 0;
-      int start = 0;
-      int end = xbt_dynar_length(mc_stack_comparison_ignore) - 1;
-      mc_stack_ignore_variable_t current_var = NULL;
-
-      while(start <= end){
-        cursor = (start + end) / 2;
-        current_var = (mc_stack_ignore_variable_t)xbt_dynar_get_as(mc_stack_comparison_ignore, cursor, mc_stack_ignore_variable_t);
-        if(strcmp(current_var->frame, frame_name) == 0){
-          if(strcmp(current_var->var_name, var_name) == 0){
-            stack_ignore_variable_free(var);
-            if(!raw_mem_set)
-              MC_UNSET_RAW_MEM;
-            return;
-          }else if(strcmp(current_var->var_name, var_name) < 0){
-            start = cursor + 1;
-          }else{
-            end = cursor - 1;
-          }
-        }else if(strcmp(current_var->frame, frame_name) < 0){
-          start = cursor + 1;
-        }else{
-          end = cursor - 1;
-        }
-      }
-
-      if(strcmp(current_var->frame, frame_name) == 0){
-        if(strcmp(current_var->var_name, var_name) < 0){
-          xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor + 1, &var);
-        }else{
-          xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor, &var);
-        }
-      }else if(strcmp(current_var->frame, frame_name) < 0){
-        xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor + 1, &var);
-      }else{
-        xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor, &var);
-      }
-    }
-  }
 
   if(!raw_mem_set)
     MC_UNSET_RAW_MEM;
@@ -871,40 +760,6 @@ void MC_ignore(void *addr, size_t size){
 /*******************************  Initialisation of MC *******************************/
 /*********************************************************************************/
 
-static void MC_dump_ignored_local_variables(void){
-
-  if(mc_stack_comparison_ignore == NULL || xbt_dynar_is_empty(mc_stack_comparison_ignore))
-    return;
-
-  unsigned int cursor = 0;
-  mc_stack_ignore_variable_t current_var;
-
-  xbt_dynar_foreach(mc_stack_comparison_ignore, cursor, current_var){
-    MC_ignore_local_variable(current_var->var_name, current_var->frame);
-  }
-
-  xbt_dynar_free(&mc_stack_comparison_ignore);
-  mc_stack_comparison_ignore = NULL;
-}
-
-static void MC_dump_ignored_global_variables(void){
-
-  if(mc_data_bss_comparison_ignore == NULL || xbt_dynar_is_empty(mc_data_bss_comparison_ignore))
-    return;
-
-  unsigned int cursor = 0;
-  mc_data_bss_ignore_variable_t current_var;
-
-  xbt_dynar_foreach(mc_data_bss_comparison_ignore, cursor, current_var){
-    MC_ignore_global_variable(current_var->name);
-  } 
-
-  xbt_dynar_free(&mc_data_bss_comparison_ignore);
-  mc_data_bss_comparison_ignore = NULL;
-
-}
-
 static void MC_init_debug_info();
 static void MC_init_debug_info() {
   XBT_INFO("Get debug information ...");
@@ -933,10 +788,6 @@ void MC_init(){
   MC_init_memory_map_info();
   MC_init_debug_info();
 
-  /* Remove variables ignored before getting list of variables */
-  MC_dump_ignored_local_variables();
-  MC_dump_ignored_global_variables();
-
    /* Init parmap */
   parmap = xbt_parmap_mc_new(xbt_os_get_numcores(), XBT_PARMAP_DEFAULT);
 
@@ -965,6 +816,7 @@ void MC_init(){
   MC_ignore_global_variable("counter"); /* Static variable used for tracing */
   MC_ignore_global_variable("maestro_stack_start");
   MC_ignore_global_variable("maestro_stack_end");
+  MC_ignore_global_variable("smx_total_comms");
 
   MC_ignore_heap(&(simix_global->process_to_run), sizeof(simix_global->process_to_run));
   MC_ignore_heap(&(simix_global->process_that_ran), sizeof(simix_global->process_that_ran));
diff --git a/src/mc/mc_hash.c b/src/mc/mc_hash.c
new file mode 100644 (file)
index 0000000..4f74676
--- /dev/null
@@ -0,0 +1,371 @@
+/* Copyright (c) 2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "mc_private.h"
+#include "mc/datatypes.h"
+#include <mc/mc.h>
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_hash, mc,
+                                "Logging specific to mc_hash");
+
+// This is djb2:
+typedef uint64_t mc_hash_t;
+#define MC_HASH_INIT ((uint64_t)5381)
+
+// #define MC_HASH(hash, value) hash = (((hash << 5) + hash) + (uint64_t) value)
+#define MC_HASH(hash, value) \
+  { hash = (((hash << 5) + hash) + (uint64_t) value);\
+  XBT_DEBUG("%s:%i: %"PRIx64" -> %"PRIx64, __FILE__, __LINE__, (uint64_t) value, hash); }
+
+// ***** Hash state
+
+typedef struct s_mc_hashing_state {
+  // Set of pointers/addresses already processed (avoid loops):
+  mc_address_set_t handled_addresses;
+} mc_hashing_state;
+
+void mc_hash_state_init(mc_hashing_state* state);
+void mc_hash_state_destroy(mc_hashing_state* state);
+
+void mc_hash_state_init(mc_hashing_state* state) {
+  state->handled_addresses = mc_address_set_new();
+}
+
+void mc_hash_state_destroy(mc_hashing_state* state) {
+   mc_address_set_free(&state->handled_addresses);
+}
+
+// TODO, detect and avoid loops
+
+static bool mc_ignored(const void* address, size_t size) {
+  mc_heap_ignore_region_t region;
+  unsigned int cursor = 0;
+  const void* end = (char*) address + size;
+  xbt_dynar_foreach(mc_heap_comparison_ignore, cursor, region) {
+   void* istart = region->address;
+   void* iend   = (char*) region->address + region->size;
+
+   if(address>=istart && address<iend && end>=istart && end<iend)
+     return true;
+  }
+
+  return false;
+}
+
+static void mc_hash_binary(mc_hash_t *hash, const void* s, size_t len) {
+  const char* p = (const void*) s;
+  int i;
+  for(i=0; i!=len; ++i) {
+    MC_HASH(*hash, p[i]);
+  }
+}
+
+/** \brief Compute a hash for a given value of a given type
+ *
+ *  We try to be very conservative (do not hash too ambiguous things).
+ *
+ *  \param address address of the variable
+ *  \param type type of the variable
+ * */
+static void mc_hash_value(mc_hash_t* hash, mc_hashing_state* state, mc_object_info_t info, const void* address, dw_type_t type) {
+  top:
+
+  switch(type->type){
+  // Simple case, hash this has binary:
+  case DW_TAG_base_type:
+  case DW_TAG_enumeration_type:
+  {
+    if(mc_ignored(address, 1))
+      return;
+    mc_hash_binary(hash, address, type->byte_size);
+    return;
+  }
+
+  case DW_TAG_array_type:
+  {
+    if(mc_ignored(address, type->byte_size))
+      return;
+
+    long element_count = type->element_count;
+    dw_type_t subtype = type->subtype;
+    if(subtype==NULL) {
+      XBT_DEBUG("Hash array without subtype");
+      return;
+    }
+    int i;
+    for(i=0; i!=element_count; ++i) {
+      XBT_DEBUG("Hash array element %i", i);
+      void* subaddress = ((char*)address)+i*subtype->byte_size;
+      mc_hash_value(hash, state, info, subaddress, subtype);
+    }
+    return;
+  }
+
+  // Get the raw type:
+  case DW_TAG_typedef:
+  case DW_TAG_volatile_type:
+  case DW_TAG_const_type:
+  case DW_TAG_restrict_type:
+  {
+    type = type->subtype;
+    if(type==NULL)
+      return;
+    else
+      goto top;
+  }
+
+  case DW_TAG_structure_type:
+  case DW_TAG_class_type:
+  {
+    if(mc_ignored(address, type->byte_size))
+      return;
+
+    unsigned int cursor = 0;
+    dw_type_t member;
+    xbt_dynar_foreach(type->members, cursor, member){
+      XBT_DEBUG("Hash struct member %s", member->name);
+      if(type->subtype==NULL)
+        return;
+       mc_hash_value(hash, state, info, ((char*)address) + member->offset, type->subtype);
+    }
+    return;
+  }
+
+  // Pointer, we hash a single value but it might be an array.
+  case DW_TAG_pointer_type:
+  case DW_TAG_reference_type:
+  case DW_TAG_rvalue_reference_type:
+  {
+    if(mc_ignored(address, 1))
+      return;
+
+    void* pointed = *(void**)address;
+    if(pointed==NULL) {
+      XBT_DEBUG("Hashed pinter is NULL");
+      return;
+    }
+
+    // Avoid loops:
+    if(mc_address_test(state->handled_addresses, pointed)) {
+      XBT_DEBUG("Hashed pointed data %p already hashed", pointed);
+      return;
+    }
+    mc_address_add(state->handled_addresses, pointed);
+
+    // Anything outside the R/W segments and the heap is not hashed:
+    bool valid_pointer = (pointed >= (void*) mc_binary_info->start_rw && pointed <= (void*) mc_binary_info->end_rw)
+        || (pointed >= (void*) mc_libsimgrid_info->start_rw && pointed <= (void*) mc_libsimgrid_info->end_rw)
+        || (pointed >= std_heap && pointed < (void*) ((const char*)std_heap + STD_HEAP_SIZE));
+    if(!valid_pointer) {
+      XBT_DEBUG("Hashed pointed data %p is in an ignored range", pointed);
+      return;
+    }
+
+    if(type->subtype==NULL) {
+      XBT_DEBUG("Missing type for %p (type=%s)", pointed, type->dw_type_id);
+      return;
+    }
+
+    address = pointed;
+    type = type->subtype;
+    goto top;
+  }
+
+  // Skip this:
+  case DW_TAG_union_type:
+  case DW_TAG_subroutine_type:
+  default:
+    return;
+  }
+}
+
+
+static void mc_hash_object_globals(mc_hash_t *hash, mc_hashing_state* state, mc_object_info_t info) {
+  unsigned int cursor = 0;
+  dw_variable_t variable;
+  xbt_dynar_foreach(info->global_variables, cursor, variable) {
+    XBT_DEBUG("Hash global variable %s", variable->name);
+
+    if(variable->type_origin == NULL) {
+      // Nothing
+      continue;
+    }
+
+    dw_type_t type = xbt_dict_get_or_null(info->types, variable->type_origin);
+    if(type==NULL) {
+      // Nothing
+      continue;
+    }
+
+    const char* address = variable->address;
+    bool valid_pointer = (address >= mc_binary_info->start_rw && address <= mc_binary_info->end_rw)
+        || (address >= mc_libsimgrid_info->start_rw && address <= mc_libsimgrid_info->end_rw)
+        || (address >= (const char*) std_heap && address < (const char *)std_heap + STD_HEAP_SIZE);
+    if(!valid_pointer) continue;
+
+    mc_hash_value(hash, state, info, variable->address, type);
+  }
+}
+
+static void mc_hash_stack_frame(
+  mc_hash_t *hash,
+    mc_object_info_t info, unw_cursor_t* unw_cursor, dw_frame_t frame, char* frame_pointer, mc_hashing_state* state
+    ) {
+
+  // return; // TEMP
+
+  unsigned int cursor = 0;
+  dw_variable_t variable;
+  xbt_dynar_foreach(frame->variables, cursor, variable){
+
+    if(variable->type_origin==NULL) {
+      XBT_DEBUG("Hash local variable %s without type", variable->name);
+      continue;
+    }
+    if(variable->location == NULL) {
+      XBT_DEBUG("Hash local variable %s without location", variable->name);
+      continue;
+    }
+
+    XBT_DEBUG("Hash local variable %s", variable->name);
+
+    void* variable_address = (void*) MC_dwarf_resolve_location(unw_cursor, variable->location, frame_pointer);
+
+    dw_type_t type = xbt_dict_get_or_null(info->types, variable->type_origin);
+    if(type==NULL) {
+      XBT_DEBUG("Hash local variable %s without loctypeation", variable->name);
+      continue;
+    }
+
+    mc_hash_value(hash, state, info, variable_address, type);
+  }
+}
+
+/** \brief Find the frame base of a given frame
+ *
+ *  \param ip         Instruction pointer
+ *  \param frame
+ *  \param unw_cursor
+ */
+void* mc_find_frame_base(unw_word_t ip, dw_frame_t frame, unw_cursor_t* unw_cursor) {
+  switch(frame->frame_base->type) {
+  case e_dw_loclist:
+  {
+    int loclist_cursor;
+    for(loclist_cursor=0; loclist_cursor < xbt_dynar_length(frame->frame_base->location.loclist); loclist_cursor++){
+      dw_location_entry_t entry = xbt_dynar_get_as(frame->frame_base->location.loclist, loclist_cursor, dw_location_entry_t);
+      if((ip >= entry->lowpc) && (ip < entry->highpc)){
+        return (void*) MC_dwarf_resolve_location(unw_cursor, entry->location, NULL);
+      }
+    }
+    return NULL;
+  }
+  // Not handled:
+  default:
+    return NULL;
+  }
+}
+
+static void mc_hash_stack(mc_hash_t *hash, stack_region_t stack, mc_hashing_state* state) {
+
+  unw_cursor_t cursor;
+  if(unw_init_local(&cursor, (unw_context_t *)stack->context)){
+    xbt_die("unw_init_local failed");
+  }
+
+  MC_HASH(*hash, (long)stack->address);
+
+  long count = 0;
+
+  int ret;
+  for(ret=1; ret >= 0; ret = unw_step(&cursor)) {
+
+    // Find the frame name:
+    unw_word_t off;
+    char frame_name[256];
+    if(unw_get_proc_name(&cursor, frame_name, sizeof (frame_name), &off)!=0) {
+      continue;
+    }
+
+    XBT_DEBUG("Frame #%i %s", (int) count, frame_name);
+
+    // Stop before context switch with maestro
+    if(!strcmp(frame_name, "smx_ctx_sysv_wrapper")) {
+      break;
+    }
+
+    ++count;
+
+    unw_word_t ip, sp;
+    if(unw_get_reg(&cursor, UNW_REG_IP, &ip))
+      continue;
+    if(unw_get_reg(&cursor, UNW_REG_SP, &sp))
+      continue;
+
+    MC_HASH(*hash, ip);
+
+    // Find the object info:
+    mc_object_info_t info;
+    if((long)ip >= (long) mc_libsimgrid_info->start_exec && (long)ip < (long) mc_libsimgrid_info->end_exec)
+      info = mc_libsimgrid_info;
+    else if((long)ip >= (long) mc_binary_info->start_exec && (long)ip < (long) mc_binary_info->end_exec)
+      info = mc_binary_info;
+    else
+      continue;
+
+    // Find the frame:
+    dw_frame_t frame = xbt_dict_get_or_null(info->local_variables, frame_name);
+    if(frame==NULL)
+      continue;
+
+    long true_ip = (long)frame->low_pc + (long)off;
+
+    // Find the fame base:
+    void* frame_base = mc_find_frame_base(true_ip, frame, &cursor);
+    if(frame_base==NULL)
+      continue;
+
+    mc_hash_stack_frame(hash, info, &cursor, frame, frame_base, state);
+  }
+
+  MC_HASH(*hash, count);
+}
+
+static void mc_hash_stacks(mc_hash_t *hash, mc_hashing_state* state) {
+  unsigned int cursor = 0;
+  stack_region_t current_stack;
+
+  MC_HASH(*hash, xbt_dynar_length(stacks_areas));
+
+  int i=0;
+  xbt_dynar_foreach(stacks_areas, cursor, current_stack){
+    XBT_DEBUG("Stack %i", i);
+    mc_hash_stack(hash, current_stack, state);
+    ++i;
+  }
+}
+
+uint64_t mc_hash_processes_state(int num_state) {
+  XBT_DEBUG("START hash %i", num_state);
+
+  mc_hashing_state state;
+  mc_hash_state_init(&state);
+
+  mc_hash_t hash = MC_HASH_INIT;
+
+  MC_HASH(hash, xbt_swag_size(simix_global->process_list)); // process count
+  mc_hash_object_globals(&hash, &state, mc_binary_info);
+  // mc_hash_object_globals(&hash, &state, mc_libsimgrid_info);
+  mc_hash_stacks(&hash, &state);
+
+  mc_hash_state_destroy(&state);
+
+  XBT_DEBUG("END hash %i", num_state);
+  return hash;
+}
index 206d531..38de8cc 100644 (file)
@@ -45,8 +45,7 @@ typedef struct s_mc_snapshot{
   size_t *stack_sizes;
   xbt_dynar_t stacks;
   xbt_dynar_t to_ignore;
-  char hash_global[41];
-  char hash_local[41];
+  uint64_t hash;
 } s_mc_snapshot_t, *mc_snapshot_t;
 
 typedef struct s_mc_snapshot_stack{
@@ -236,8 +235,6 @@ typedef struct s_mc_comparison_times{
   double libsimgrid_global_variables_comparison_time;
   double heap_comparison_time;
   double stacks_comparison_time;
-  double hash_global_variables_comparison_time;
-  double hash_local_variables_comparison_time;
 }s_mc_comparison_times_t, *mc_comparison_times_t;
 
 extern __thread mc_comparison_times_t mc_comp_times;
@@ -282,8 +279,6 @@ extern xbt_fifo_t mc_stack_liveness;
 extern mc_global_t initial_state_liveness;
 extern xbt_automaton_t _mc_property_automaton;
 extern int compare;
-extern xbt_dynar_t mc_stack_comparison_ignore;
-extern xbt_dynar_t mc_data_bss_comparison_ignore;
 
 typedef struct s_mc_pair{
   int num;
@@ -321,7 +316,7 @@ void MC_dump_stack_liveness(xbt_fifo_t stack);
 
 /********************************** Variables with DWARF **********************************/
 
-typedef struct s_mc_object_info {
+struct s_mc_object_info {
   char* file_name;
   char *start_exec, *end_exec; // Executable segment
   char *start_rw, *end_rw; // Read-write segment
@@ -329,7 +324,8 @@ typedef struct s_mc_object_info {
   xbt_dict_t local_variables; // xbt_dict_t<frame_name, dw_frame_t>
   xbt_dynar_t global_variables; // xbt_dynar_t<dw_variable_t>
   xbt_dict_t types; // xbt_dict_t<origin as hexadecimal string, dw_type_t>
-} s_mc_object_info_t, *mc_object_info_t;
+  xbt_dict_t types_by_name; // xbt_dict_t<name, dw_type_t> (full defined type only)
+};
 
 mc_object_info_t MC_new_object_info(void);
 mc_object_info_t MC_find_object_info(memory_map_t maps, char* name);
@@ -439,6 +435,7 @@ void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame, dw_vari
 /********************************** DWARF **********************************/
 
 Dwarf_Off MC_dwarf_resolve_location(unw_cursor_t* c, dw_location_t location, void* frame_pointer_address);
+void* mc_find_frame_base(unw_word_t ip, dw_frame_t frame, unw_cursor_t* unw_cursor);
 
 /********************************** Miscellaneous **********************************/
 
@@ -470,5 +467,20 @@ extern xbt_dynar_t communications_pattern;
 
 void get_comm_pattern(xbt_dynar_t communications_pattern, smx_simcall_t request, int call);
 
+/* *********** Sets *********** */
+
+typedef struct s_mc_address_set *mc_address_set_t;
+
+mc_address_set_t mc_address_set_new();
+mc_address_set_t mc_address_set_free(mc_address_set_t* p);
+void mc_address_add(mc_address_set_t p, const void* value);
+bool mc_address_test(mc_address_set_t p, const void* value);
+
+/* *********** Hash *********** */
+
+uint64_t mc_hash_processes_state(int num_state);
+
+#define MC_USE_SNAPSHOT_HASH 1
+
 #endif
 
diff --git a/src/mc/mc_set.cpp b/src/mc/mc_set.cpp
new file mode 100644 (file)
index 0000000..b04c1ff
--- /dev/null
@@ -0,0 +1,36 @@
+/* Copyright (c) 2007-2013. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stddef.h>
+#include <set>
+
+typedef std::set<const void*>*  mc_address_set_t;
+
+extern "C" {
+
+mc_address_set_t mc_address_set_new();
+mc_address_set_t mc_address_set_free(mc_address_set_t* p);
+void mc_address_add(mc_address_set_t p, const void* value);
+bool mc_address_test(mc_address_set_t p, const void* value);
+
+mc_address_set_t mc_address_set_new() {
+  return new std::set<const void*>();
+}
+
+mc_address_set_t mc_address_set_free(mc_address_set_t* p) {
+  delete *p;
+  *p = NULL;
+}
+
+void mc_address_add(mc_address_set_t p, const void* value) {
+  p->insert(value);
+}
+
+bool mc_address_test(mc_address_set_t p, const void* value) {
+  return p->find(value) != p->end();
+}
+
+};
index 7f9689a..428ef6a 100644 (file)
@@ -31,8 +31,6 @@ static void SIMIX_comm_start(smx_action_t action);
 void SIMIX_network_init(void)
 {
   rdv_points = xbt_dict_new_homogeneous(SIMIX_rdv_free);
-  if(MC_is_active())
-    MC_ignore_global_variable("smx_total_comms");
 }
 
 void SIMIX_network_exit(void)
index c9154e0..02f333d 100644 (file)
@@ -11,6 +11,7 @@
 #include "mc/mc.h"
 #include "xbt/mmalloc.h"
 #include "mc/datatypes.h"
+#include "mc/mc_private.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mm_diff, xbt,
                                 "Logging specific to mm_diff in mmalloc");
@@ -408,7 +409,7 @@ void reset_heap_information(){
 
 }
 
-int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dict_t all_types, xbt_dict_t other_types){
+int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, mc_object_info_t info, mc_object_info_t other_info){
 
   if(heap1 == NULL && heap2 == NULL){
     XBT_DEBUG("Malloc descriptors null");
@@ -464,7 +465,7 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dict_t all_ty
 
           addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
         
-          res_compare = compare_heap_area(addr_block1, addr_block2, NULL, all_types, other_types, NULL, 0);
+          res_compare = compare_heap_area(addr_block1, addr_block2, NULL, info, other_info, NULL, 0);
         
           if(res_compare != 1){
             for(k=1; k < heapinfo2[i1].busy_block.size; k++)
@@ -500,7 +501,7 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dict_t all_ty
           continue;
         }
           
-        res_compare = compare_heap_area(addr_block1, addr_block2, NULL, all_types, other_types, NULL, 0);
+        res_compare = compare_heap_area(addr_block1, addr_block2, NULL, info, other_info, NULL, 0);
         
         if(res_compare != 1 ){
           for(k=1; k < heapinfo2[i2].busy_block.size; k++)
@@ -547,7 +548,7 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dict_t all_ty
             addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
             addr_frag2 = (void*) ((char *)addr_block2 + (j1 << ((xbt_mheap_t)s_heap)->heapinfo[i1].type));
 
-            res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, all_types, other_types, NULL, 0);
+            res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, info, other_info, NULL, 0);
 
             if(res_compare !=  1)
               equal = 1;
@@ -576,7 +577,7 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dict_t all_ty
             addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
             addr_frag2 = (void*) ((char *)addr_block2 + (j2 <<((xbt_mheap_t)s_heap)->heapinfo[i2].type));
 
-            res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, all_types, other_types, NULL, 0);
+            res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, info, other_info, NULL, 0);
             
             if(res_compare != 1){
               equal = 1;
@@ -700,7 +701,7 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dict_t all_ty
   return ((nb_diff1 > 0) || (nb_diff2 > 0));
 }
 
-static int compare_heap_area_without_type(void *real_area1, void *real_area2, void *area1, void *area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, int size, int check_ignore){
+static int compare_heap_area_without_type(void *real_area1, void *real_area2, void *area1, void *area2, xbt_dynar_t previous, mc_object_info_t info, mc_object_info_t other_info, int size, int check_ignore){
 
   int i = 0;
   void *addr_pointed1, *addr_pointed2;
@@ -735,7 +736,7 @@ static int compare_heap_area_without_type(void *real_area1, void *real_area2, vo
         continue;
       }else if((addr_pointed1 > s_heap) && ((char *)addr_pointed1 < (char *)s_heap + STD_HEAP_SIZE) 
                && (addr_pointed2 > s_heap) && ((char *)addr_pointed2 < (char *)s_heap + STD_HEAP_SIZE)){
-        res_compare = compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, NULL, 0); 
+        res_compare = compare_heap_area(addr_pointed1, addr_pointed2, previous, info, other_info, NULL, 0);
         if(res_compare == 1){
           return res_compare;
         }
@@ -757,7 +758,7 @@ static int compare_heap_area_without_type(void *real_area1, void *real_area2, vo
 
 // area_size is either a byte_size or an elements_count?&
 static int compare_heap_area_with_type(void *real_area1, void *real_area2, void *area1, void *area2, 
-                                       xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type_id, 
+                                       xbt_dynar_t previous, mc_object_info_t info, mc_object_info_t other_info, char *type_id,
                                        int area_size, int check_ignore, int pointer_level){
 
   if(is_stack(real_area1) && is_stack(real_area2))
@@ -769,13 +770,12 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
     return 0;
   }
   
-  dw_type_t type = xbt_dict_get_or_null(all_types, type_id);
+  dw_type_t type = xbt_dict_get_or_null(info->types, type_id);
   dw_type_t subtype, subsubtype;
   int res, elm_size, i, switch_types = 0;
   unsigned int cursor = 0;
   dw_type_t member;
   void *addr_pointed1, *addr_pointed2;;
-  char *type_desc;
 
   switch(type->type){
   case DW_TAG_base_type:
@@ -801,10 +801,10 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
   case DW_TAG_typedef:
   case DW_TAG_const_type:
   case DW_TAG_volatile_type:
-    return compare_heap_area_with_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->dw_type_id, area_size, check_ignore, pointer_level);
+    return compare_heap_area_with_type(real_area1, real_area2, area1, area2, previous, info, other_info, type->dw_type_id, area_size, check_ignore, pointer_level);
     break;
   case DW_TAG_array_type:
-    subtype = xbt_dict_get_or_null(all_types, type->dw_type_id);
+    subtype = xbt_dict_get_or_null(info->types, type->dw_type_id);
     switch(subtype->type){
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
@@ -812,13 +812,8 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
       if(subtype->byte_size == 0){ /*declaration of the type, need the complete description */
-        type_desc = get_type_description(all_types, subtype->name);
-        if(type_desc){
-          subtype = xbt_dict_get_or_null(all_types, type_desc);
-        }else{
-          subtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name));
+          subtype = xbt_dict_get_or_null(other_info->types_by_name, subtype->name);
           switch_types = 1;
-        }
       }
       elm_size = subtype->byte_size;
       break;
@@ -826,15 +821,10 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
     case DW_TAG_const_type:
     case DW_TAG_typedef:
     case DW_TAG_volatile_type:
-      subsubtype = xbt_dict_get_or_null(all_types, subtype->dw_type_id);
+      subsubtype = subtype->subtype;
       if(subsubtype->byte_size == 0){ /*declaration of the type, need the complete description */
-        type_desc = get_type_description(all_types, subsubtype->name);
-        if(type_desc){
-          subsubtype = xbt_dict_get_or_null(all_types, type_desc);
-        }else{
-          subsubtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name));
+          subsubtype = xbt_dict_get_or_null(other_info->types_by_name, subtype->name);
           switch_types = 1;
-        }
       }
       elm_size = subsubtype->byte_size;
       break;
@@ -845,15 +835,15 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
     for(i=0; i<type->element_count; i++){
       // TODO, add support for variable stride (DW_AT_byte_stride)
       if(switch_types)
-        res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, other_types, all_types, type->dw_type_id, subtype->byte_size, check_ignore, pointer_level);
+        res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, other_info, info, type->dw_type_id, subtype->byte_size, check_ignore, pointer_level);
       else
-        res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, all_types, other_types, type->dw_type_id, subtype->byte_size, check_ignore, pointer_level);
+        res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, info, other_info, type->dw_type_id, subtype->byte_size, check_ignore, pointer_level);
       if(res == 1)
         return res;
     }
     break;
   case DW_TAG_pointer_type:
-    if(type->dw_type_id && ((dw_type_t)xbt_dict_get_or_null(all_types, type->dw_type_id))->type == DW_TAG_subroutine_type){
+    if(type->dw_type_id && ((dw_type_t)xbt_dict_get_or_null(info->types, type->dw_type_id))->type == DW_TAG_subroutine_type){
       addr_pointed1 = *((void **)(area1)); 
       addr_pointed2 = *((void **)(area2));
       return (addr_pointed1 != addr_pointed2);;
@@ -864,7 +854,7 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
           addr_pointed1 = *((void **)((char *)area1 + (i*sizeof(void *)))); 
           addr_pointed2 = *((void **)((char *)area2 + (i*sizeof(void *)))); 
           if(addr_pointed1 > s_heap && (char *)addr_pointed1 < (char*) s_heap + STD_HEAP_SIZE && addr_pointed2 > s_heap && (char *)addr_pointed2 < (char*) s_heap + STD_HEAP_SIZE)
-            res =  compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, type->dw_type_id, pointer_level); 
+            res =  compare_heap_area(addr_pointed1, addr_pointed2, previous, info, other_info, type->dw_type_id, pointer_level);
           else
             res =  (addr_pointed1 != addr_pointed2);
           if(res == 1)
@@ -874,7 +864,7 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
         addr_pointed1 = *((void **)(area1)); 
         addr_pointed2 = *((void **)(area2));
         if(addr_pointed1 > s_heap && (char *)addr_pointed1 < (char*) s_heap + STD_HEAP_SIZE && addr_pointed2 > s_heap && (char *)addr_pointed2 < (char*) s_heap + STD_HEAP_SIZE)
-          return compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, type->dw_type_id, pointer_level); 
+          return compare_heap_area(addr_pointed1, addr_pointed2, previous, info, other_info, type->dw_type_id, pointer_level);
         else
           return  (addr_pointed1 != addr_pointed2);
       }
@@ -882,11 +872,11 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
     break;
   case DW_TAG_structure_type:
     if(type->byte_size == 0){ /*declaration of the structure, need the complete description */
-      type_desc = get_type_description(all_types, type->name);
-      if(type_desc){
-        type = xbt_dict_get_or_null(all_types, type_desc);
+      dw_type_t full_type = xbt_dict_get_or_null(info->types_by_name, type->name);
+      if(full_type){
+        type = full_type;
       }else{
-        type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
+        type = xbt_dict_get_or_null(other_info->types_by_name, type->name);
         switch_types = 1;
       }
     }
@@ -894,9 +884,9 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
       if(area_size>type->byte_size && area_size%type->byte_size == 0){
         for(i=0; i<(area_size/type->byte_size); i++){
           if(switch_types)
-            res = compare_heap_area_with_type((char *)real_area1 + (i*type->byte_size), (char *)real_area2 + (i*type->byte_size), (char *)area1 + (i*type->byte_size), (char *)area2 + (i*type->byte_size), previous, other_types, all_types, type_id, -1, check_ignore, 0);
+            res = compare_heap_area_with_type((char *)real_area1 + (i*type->byte_size), (char *)real_area2 + (i*type->byte_size), (char *)area1 + (i*type->byte_size), (char *)area2 + (i*type->byte_size), previous, other_info, info, type_id, -1, check_ignore, 0);
           else
-            res = compare_heap_area_with_type((char *)real_area1 + (i*type->byte_size), (char *)real_area2 + (i*type->byte_size), (char *)area1 + (i*type->byte_size), (char *)area2 + (i*type->byte_size), previous, all_types, other_types, type_id, -1, check_ignore, 0);
+            res = compare_heap_area_with_type((char *)real_area1 + (i*type->byte_size), (char *)real_area2 + (i*type->byte_size), (char *)area1 + (i*type->byte_size), (char *)area2 + (i*type->byte_size), previous, info, other_info, type_id, -1, check_ignore, 0);
           if(res == 1)
             return res;
         }
@@ -907,9 +897,9 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
       cursor = 0;
       xbt_dynar_foreach(type->members, cursor, member){ 
         if(switch_types)
-          res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, other_types, all_types, member->dw_type_id, -1, check_ignore, 0);
+          res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, other_info, info, member->dw_type_id, -1, check_ignore, 0);
         else
-          res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, all_types, other_types, member->dw_type_id, -1, check_ignore, 0);  
+          res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, info, other_info, member->dw_type_id, -1, check_ignore, 0);
         if(res == 1){
           return res;
         }
@@ -917,7 +907,7 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
     }
     break;
   case DW_TAG_union_type:
-    return compare_heap_area_without_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->byte_size, check_ignore);
+    return compare_heap_area_without_type(real_area1, real_area2, area1, area2, previous, info, other_info, type->byte_size, check_ignore);
     break;
   default:
     break;
@@ -927,30 +917,29 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void
 
 }
 
-static char* get_offset_type(char* type_id, int offset, xbt_dict_t all_types, xbt_dict_t other_types, int area_size, int *switch_type){
-  dw_type_t type = xbt_dict_get_or_null(all_types, type_id);
+static char* get_offset_type(char* type_id, int offset, mc_object_info_t info, mc_object_info_t other_info, int area_size, int *switch_type){
+  dw_type_t type = xbt_dict_get_or_null(info->types, type_id);
   if(type == NULL){
-    type = xbt_dict_get_or_null(other_types, type_id);
+    type = xbt_dict_get_or_null(other_info->types, type_id);
     *switch_type = 1;
   }
-  char* type_desc;
   switch(type->type){
   case DW_TAG_structure_type :
     if(type->byte_size == 0){ /*declaration of the structure, need the complete description */
       if(*switch_type == 0){
-        type_desc = get_type_description(all_types, type->name);
-        if(type_desc){
-          type = xbt_dict_get_or_null(all_types, type_desc);
+        dw_type_t full_type = xbt_dict_get_or_null(info->types_by_name, type->name);
+        if(full_type){
+          type = full_type;
         }else{
-          type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
+          type = xbt_dict_get_or_null(other_info->types_by_name, type->name);
           *switch_type = 1;
         }
       }else{
-        type_desc = get_type_description(other_types, type->name);
-        if(type_desc){
-          type = xbt_dict_get_or_null(other_types, type_desc);
+        dw_type_t full_type = xbt_dict_get_or_null(other_info->types_by_name, type->name);
+        if(full_type){
+          type = full_type;
         }else{
-          type = xbt_dict_get_or_null(all_types, get_type_description(other_types, type->name));
+          type = xbt_dict_get_or_null(info->types_by_name, type->name);
           *switch_type = 0;
         }
       }
@@ -978,7 +967,7 @@ static char* get_offset_type(char* type_id, int offset, xbt_dict_t all_types, xb
   }
 }
 
-int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type_id, int pointer_level){
+int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, mc_object_info_t info, mc_object_info_t other_info, char *type_id, int pointer_level){
 
   int res_compare;
   ssize_t block1, frag1, block2, frag2;
@@ -988,7 +977,6 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t
   void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2, *real_addr_block1, *real_addr_block2,  *real_addr_frag1, *real_addr_frag2;
   void *area1_to_compare, *area2_to_compare;
   dw_type_t type = NULL;
-  char *type_desc;
   int type_size = -1;
   int offset1 =0, offset2 = 0;
   int new_size1 = -1, new_size2 = -1;
@@ -1028,16 +1016,16 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t
   real_addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
 
   if(type_id){
-    type = xbt_dict_get_or_null(all_types, type_id);
+    type = xbt_dict_get_or_null(info->types, type_id);
     if(type->byte_size == 0){
-      if(type->dw_type_id == NULL){
-        type_desc = get_type_description(all_types, type->name);
-        if(type_desc)
-          type = xbt_dict_get_or_null(all_types, type_desc);
+      if(type->subtype == NULL){
+        dw_type_t full_type = xbt_dict_get_or_null(info->types_by_name, type->name);
+        if(full_type)
+          type = full_type;
         else
-          type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
+          type = xbt_dict_get_or_null(other_info->types_by_name, type->name);
       }else{
-        type = xbt_dict_get_or_null(all_types, type->dw_type_id);
+        type = type->subtype;
       }
     }
     if((type->byte_size == DW_TAG_pointer_type) || ((type->type == DW_TAG_base_type) && type->name!=NULL && (!strcmp(type->name, "char"))))
@@ -1190,14 +1178,14 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t
       offset1 = (char *)area1 - (char *)real_addr_frag1;
       offset2 = (char *)area2 - (char *)real_addr_frag2;
       if(types1[block1][frag1] != NULL && types2[block2][frag2] != NULL){
-        new_type_id1 = get_offset_type(types1[block1][frag1], offset1, all_types, other_types, size, &switch_type);
-        new_type_id2 = get_offset_type(types2[block2][frag2], offset1, all_types, other_types, size, &switch_type);
+        new_type_id1 = get_offset_type(types1[block1][frag1], offset1, info, other_info, size, &switch_type);
+        new_type_id2 = get_offset_type(types2[block2][frag2], offset1, info, other_info, size, &switch_type);
       }else if(types1[block1][frag1] != NULL){
-        new_type_id1 = get_offset_type(types1[block1][frag1], offset1, all_types, other_types, size, &switch_type);
-        new_type_id2 = get_offset_type(types1[block1][frag1], offset2, all_types, other_types, size, &switch_type);       
+        new_type_id1 = get_offset_type(types1[block1][frag1], offset1, info, other_info, size, &switch_type);
+        new_type_id2 = get_offset_type(types1[block1][frag1], offset2, info, other_info, size, &switch_type);
       }else if(types2[block2][frag2] != NULL){
-        new_type_id1 = get_offset_type(types2[block2][frag2], offset1, all_types, other_types, size, &switch_type);
-        new_type_id2 = get_offset_type(types2[block2][frag2], offset2, all_types, other_types, size, &switch_type);
+        new_type_id1 = get_offset_type(types2[block2][frag2], offset1, info, other_info, size, &switch_type);
+        new_type_id2 = get_offset_type(types2[block2][frag2], offset2, info, other_info, size, &switch_type);
       }else{
         if(match_pairs){
           match_equals(previous);
@@ -1208,22 +1196,22 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t
 
       if(new_type_id1 !=  NULL && new_type_id2 !=  NULL && !strcmp(new_type_id1, new_type_id2)){
         if(switch_type){
-          type = xbt_dict_get_or_null(other_types, new_type_id1);
+          type = xbt_dict_get_or_null(other_info->types, new_type_id1);
           while(type->byte_size == 0 && type->dw_type_id != NULL)
-            type = xbt_dict_get_or_null(other_types, type->dw_type_id);
+            type = xbt_dict_get_or_null(other_info->types, type->dw_type_id);
           new_size1 = type->byte_size;
-          type = xbt_dict_get_or_null(other_types, new_type_id2);
+          type = xbt_dict_get_or_null(other_info->types, new_type_id2);
           while(type->byte_size == 0 && type->dw_type_id != NULL)
-            type = xbt_dict_get_or_null(other_types, type->dw_type_id);
+            type = xbt_dict_get_or_null(other_info->types, type->dw_type_id);
           new_size2 = type->byte_size;
         }else{
-          type = xbt_dict_get_or_null(all_types, new_type_id1);
+          type = xbt_dict_get_or_null(info->types, new_type_id1);
           while(type->byte_size == 0 && type->dw_type_id != NULL)
-            type = xbt_dict_get_or_null(all_types, type->dw_type_id);
+            type = xbt_dict_get_or_null(info->types, type->dw_type_id);
           new_size1 = type->byte_size;
-          type = xbt_dict_get_or_null(all_types, new_type_id2);
+          type = xbt_dict_get_or_null(info->types, new_type_id2);
           while(type->byte_size == 0 && type->dw_type_id != NULL)
-            type = xbt_dict_get_or_null(all_types, type->dw_type_id);
+            type = xbt_dict_get_or_null(info->types, type->dw_type_id);
           new_size2 = type->byte_size;
         }
       }else{
@@ -1277,9 +1265,9 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t
   /* Start comparison*/
   if(type_id != NULL){
     if(switch_type)
-      res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, other_types, all_types, type_id, size, check_ignore, pointer_level);
+      res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, other_info, info, type_id, size, check_ignore, pointer_level);
     else
-      res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, type_id, size, check_ignore, pointer_level);
+      res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, info, other_info, type_id, size, check_ignore, pointer_level);
     if(res_compare == 1){
       if(match_pairs)
         xbt_dynar_free(&previous);
@@ -1287,9 +1275,9 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t
     }
   }else{
     if(switch_type)
-      res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, other_types, all_types, size, check_ignore);
+      res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, other_info, info, size, check_ignore);
     else
-      res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, size, check_ignore);
+      res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, info, other_info, size, check_ignore);
     if(res_compare == 1){
       if(match_pairs)
         xbt_dynar_free(&previous);
@@ -1335,13 +1323,13 @@ int get_pointed_area_size(void *area, int heap){
 
 }
 
-char *get_type_description(xbt_dict_t types, char *type_name){
+char *get_type_description(mc_object_info_t info, char *type_name){
 
   xbt_dict_cursor_t dict_cursor;
   char *type_origin;
   dw_type_t type;
 
-  xbt_dict_foreach(types, dict_cursor, type_origin, type){
+  xbt_dict_foreach(info->types, dict_cursor, type_origin, type){
     if(type->name && (strcmp(type->name, type_name) == 0) && type->byte_size > 0){
       xbt_dict_cursor_free(&dict_cursor);
       return type_origin;