Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Use process addresses in mc_compare
authorGabriel Corona <gabriel.corona@loria.fr>
Mon, 16 Jun 2014 12:50:42 +0000 (14:50 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Mon, 16 Jun 2014 13:02:20 +0000 (15:02 +0200)
This is necessary in order to work work with per-page snapshots.

src/mc/mc_compare.c
src/mc/mc_private.h
src/mc/mc_snapshot.c

index 69176ea..77533e7 100644 (file)
@@ -106,18 +106,15 @@ static int add_compared_pointers(void *p1, void *p2)
   return 1;
 }
 
-static int compare_areas_with_type(void *area1, void *area2,
-                                   mc_snapshot_t snapshot1,
-                                   mc_snapshot_t snapshot2, dw_type_t type,
-                                   int region_size, int region_type,
-                                   void *start_data, int pointer_level)
+static int compare_areas_with_type(void* real_area1, mc_snapshot_t snapshot1, mc_mem_region_t region1,
+                                   void* real_area2, mc_snapshot_t snapshot2, mc_mem_region_t region2,
+                                   dw_type_t type, int pointer_level)
 {
-
   unsigned int cursor = 0;
   dw_type_t member, subtype, subsubtype;
   int elm_size, i, res;
-  void *addr_pointed1, *addr_pointed2;
 
+  top:
   switch (type->type) {
   case DW_TAG_unspecified_type:
     return 1;
@@ -125,15 +122,20 @@ static int compare_areas_with_type(void *area1, void *area2,
   case DW_TAG_base_type:
   case DW_TAG_enumeration_type:
   case DW_TAG_union_type:
-    return (memcmp(area1, area2, type->byte_size) != 0);
+  {
+    void* data1 =
+      mc_snapshot_read_region(real_area1, region1, alloca(type->byte_size), type->byte_size);
+    void* data2 =
+      mc_snapshot_read_region(real_area2, region1, alloca(type->byte_size), type->byte_size);
+    return (memcmp(data1, data2, type->byte_size) != 0);
     break;
+  }
   case DW_TAG_typedef:
   case DW_TAG_volatile_type:
   case DW_TAG_const_type:
-    return compare_areas_with_type(area1, area2, snapshot1, snapshot2,
-                                   type->subtype, region_size, region_type,
-                                   start_data, pointer_level);
-    break;
+    // Poor man's TCO:
+    type = type->subtype;
+    goto top;
   case DW_TAG_array_type:
     subtype = type->subtype;
     switch (subtype->type) {
@@ -165,11 +167,11 @@ static int compare_areas_with_type(void *area1, void *area2,
       break;
     }
     for (i = 0; i < type->element_count; i++) {
-      res =
-          compare_areas_with_type((char *) area1 + (i * elm_size),
-                                  (char *) area2 + (i * elm_size), snapshot1,
-                                  snapshot2, type->subtype, region_size,
-                                  region_type, start_data, pointer_level);
+      size_t off = i * elm_size;
+      res = compare_areas_with_type(
+            (char*) real_area1 + off, snapshot1, region1,
+            (char*) real_area2 + off, snapshot2, region2,
+            type->subtype, pointer_level);
       if (res == 1)
         return res;
     }
@@ -177,9 +179,10 @@ static int compare_areas_with_type(void *area1, void *area2,
   case DW_TAG_pointer_type:
   case DW_TAG_reference_type:
   case DW_TAG_rvalue_reference_type:
-
-    addr_pointed1 = *((void **) (area1));
-    addr_pointed2 = *((void **) (area2));
+  {
+    void* temp;
+    void* addr_pointed1 = *(void**) mc_snapshot_read_region(real_area1, region1, &temp, sizeof(void**));
+    void* addr_pointed2 = *(void**) mc_snapshot_read_region(real_area2, region2, &temp, sizeof(void**));
 
     if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) {
       return (addr_pointed1 != addr_pointed2);
@@ -208,24 +211,18 @@ static int compare_areas_with_type(void *area1, void *area2,
                                  snapshot2, NULL, type->subtype, pointer_level);
       }
       // The pointers are both in the current object R/W segment:
-      else if (addr_pointed1 > start_data
-               && (char *) addr_pointed1 <= (char *) start_data + region_size) {
+      else if (addr_pointed1 > region1->start_addr
+               && (char *) addr_pointed1 <= (char *) region1->start_addr + region1->size) {
         if (!
-            (addr_pointed2 > start_data
-             && (char *) addr_pointed2 <= (char *) start_data + region_size))
+            (addr_pointed2 > region2->start_addr
+             && (char *) addr_pointed2 <= (char *) region2->start_addr + region2->size))
           return 1;
         if (type->dw_type_id == NULL)
           return (addr_pointed1 != addr_pointed2);
         else {
-          void *translated_addr_pointer1 =
-              mc_translate_address((uintptr_t) addr_pointed1, snapshot1);
-          void *translated_addr_pointer2 =
-              mc_translate_address((uintptr_t) addr_pointed2, snapshot2);
-          return compare_areas_with_type(translated_addr_pointer1,
-                                         translated_addr_pointer2, snapshot1,
-                                         snapshot2, type->subtype, region_size,
-                                         region_type, start_data,
-                                         pointer_level);
+          return compare_areas_with_type(addr_pointed1, snapshot1, region1,
+                                         addr_pointed2, snapshot2, region2,
+                                         type->subtype, pointer_level);
         }
       }
 
@@ -234,17 +231,20 @@ static int compare_areas_with_type(void *area1, void *area2,
       }
     }
     break;
+  }
   case DW_TAG_structure_type:
   case DW_TAG_class_type:
     xbt_dynar_foreach(type->members, cursor, member) {
       void *member1 =
-          mc_member_snapshot_resolve(area1, type, member, snapshot1);
+        mc_member_resolve(real_area1, type, member, snapshot1);
       void *member2 =
-          mc_member_snapshot_resolve(area2, type, member, snapshot2);
+        mc_member_resolve(real_area2, type, member, snapshot2);
+      mc_mem_region_t subregion1 = mc_get_region_hinted(member1, snapshot1, region1);
+      mc_mem_region_t subregion2 = mc_get_region_hinted(member2, snapshot2, region2);
       res =
-          compare_areas_with_type(member1, member2, snapshot1, snapshot2,
-                                  member->subtype, region_size, region_type,
-                                  start_data, pointer_level);
+          compare_areas_with_type(member1, snapshot1, subregion1,
+                                  member2, snapshot2, subregion2,
+                                  member->subtype, pointer_level);
       if (res == 1)
         return res;
     }
@@ -276,18 +276,12 @@ static int compare_global_variables(int region_type, mc_mem_region_t r1,
   int res;
   unsigned int cursor = 0;
   dw_variable_t current_var;
-  size_t offset;
-  void *start_data;
-  void *start_data_binary = mc_binary_info->start_rw;
-  void *start_data_libsimgrid = mc_libsimgrid_info->start_rw;
 
   mc_object_info_t object_info = NULL;
   if (region_type == 2) {
     object_info = mc_binary_info;
-    start_data = start_data_binary;
   } else {
     object_info = mc_libsimgrid_info;
-    start_data = start_data_libsimgrid;
   }
   variables = object_info->global_variables;
 
@@ -300,18 +294,14 @@ static int compare_global_variables(int region_type, mc_mem_region_t r1,
         || (char *) current_var->address > (char *) object_info->end_rw)
       continue;
 
-    offset = (char *) current_var->address - (char *) object_info->start_rw;
-
     dw_type_t bvariable_type = current_var->type;
     res =
-        compare_areas_with_type((char *) r1->data + offset,
-                                (char *) r2->data + offset, snapshot1,
-                                snapshot2, bvariable_type, r1->size,
-                                region_type, start_data, 0);
+        compare_areas_with_type((char *) current_var->address, snapshot1, r1,
+                                (char *) current_var->address, snapshot2, r2,
+                                bvariable_type, 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_VERB("Global variable %s (%p) is different between snapshots",
+               current_var->name, (char *) current_var->address);
       xbt_dynar_free(&compared_pointers);
       compared_pointers = NULL;
       return 1;
@@ -332,9 +322,6 @@ static int compare_local_variables(mc_snapshot_t snapshot1,
                                    mc_snapshot_stack_t stack2, void *heap1,
                                    void *heap2)
 {
-  void *start_data_binary = mc_binary_info->start_rw;
-  void *start_data_libsimgrid = mc_libsimgrid_info->start_rw;
-
   if (!compared_pointers) {
     compared_pointers =
         xbt_dynar_new(sizeof(pointers_pair_t), pointers_pair_free_voidp);
@@ -375,21 +362,13 @@ static int compare_local_variables(mc_snapshot_t snapshot1,
       offset2 = (char *) current_var2->address - (char *) std_heap;
       // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
 
-      if (current_var1->region == 1) {
+
         dw_type_t subtype = current_var1->type;
         res =
-            compare_areas_with_type((char *) heap1 + offset1,
-                                    (char *) heap2 + offset2, snapshot1,
-                                    snapshot2, subtype, 0, 1,
-                                    start_data_libsimgrid, 0);
-      } else {
-        dw_type_t subtype = current_var2->type;
-        res =
-            compare_areas_with_type((char *) heap1 + offset1,
-                                    (char *) heap2 + offset2, snapshot1,
-                                    snapshot2, subtype, 0, 2, start_data_binary,
-                                    0);
-      }
+            compare_areas_with_type(current_var1->address, snapshot1, mc_get_snapshot_region(current_var1->address, snapshot1),
+                                    current_var2->address, snapshot2, mc_get_snapshot_region(current_var2->address, snapshot2),
+                                    subtype, 0);
+
       if (res == 1) {
         // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
         XBT_VERB
index 96fe0a0..d5d01de 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "simgrid_config.h"
 #include <stdio.h>
+#include <stdbool.h>
 #ifndef WIN32
 #include <sys/mman.h>
 #endif
@@ -28,6 +29,7 @@
 #include "msg/datatypes.h"
 #include "xbt/strbuff.h"
 #include "xbt/parmap.h"
+#include "mc_mmu.h"
 
 typedef struct s_dw_frame s_dw_frame_t, *dw_frame_t;
 typedef struct s_mc_function_index_item s_mc_function_index_item_t, *mc_function_index_item_t;
@@ -47,6 +49,12 @@ typedef struct s_mc_mem_region{
   size_t* page_numbers;
 } s_mc_mem_region_t, *mc_mem_region_t;
 
+static inline bool mc_region_contain(mc_mem_region_t region, void* p)
+{
+  return p >= region->start_addr &&
+    p < (void*)((char*) region->start_addr + region->size);
+}
+
 /** Ignored data
  *
  *  Some parts of the snapshot are ignored by zeroing them out: the real
@@ -71,6 +79,16 @@ typedef struct s_mc_snapshot{
   xbt_dynar_t ignored_data;
 } s_mc_snapshot_t, *mc_snapshot_t;
 
+mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot);
+
+static inline mc_mem_region_t mc_get_region_hinted(void* addr, mc_snapshot_t snapshot, mc_mem_region_t region)
+{
+  if (mc_region_contain(region, addr))
+    return region;
+  else
+    return mc_get_snapshot_region(addr, snapshot);
+}
+
 /** Information about a given stack frame
  *
  */
@@ -132,6 +150,10 @@ void mc_softdirty_reset();
 typedef struct s_mc_pages_store s_mc_pages_store_t, * mc_pages_store_t;
 mc_pages_store_t mc_pages_store_new();
 
+static inline bool mc_snapshot_region_linear(mc_mem_region_t region) {
+  return !region || !region->data;
+}
+
 void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target, size_t size);
 void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, void* target, size_t size);
 
index 2d59319..cef4e98 100644 (file)
@@ -7,7 +7,7 @@
 #include "mc_private.h"
 #include "mc_mmu.h"
 
-static mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot)
+mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot)
 {
   for (size_t i = 0; i != NB_REGIONS; ++i) {
     mc_mem_region_t region = snapshot->regions[i];
@@ -121,7 +121,7 @@ void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target,
 {
   uintptr_t offset = (uintptr_t) addr - (uintptr_t) region->start_addr;
 
-  if (addr < region->start_addr || offset+size > region->size) {
+  if (addr < region->start_addr || (char*) addr+size >= (char*)region->start_addr+region->size) {
     xbt_die("Trying to read out of the region boundary.");
   }