Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : comment debug printf
[simgrid.git] / src / mc / mc_checkpoint.c
index dd6eccc..41b3738 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <string.h>
 #include <link.h>
+#include <dirent.h>
 
 #include "internal_config.h"
 #include "mc_private.h"
@@ -65,7 +66,7 @@ static void local_variable_free_voidp(void *v)
 
 void MC_region_destroy(mc_mem_region_t reg)
 {
-  if (reg)
+  if (!reg)
     return;
 
   //munmap(reg->data, reg->size);
@@ -102,7 +103,7 @@ void MC_free_snapshot(mc_snapshot_t snapshot)
 /*******************************  Snapshot regions ********************************/
 /*********************************************************************************/
 
-  static mc_mem_region_t mc_region_new_dense(int type, void *start_addr, void* permanent_addr, size_t size, mc_mem_region_t ref_reg)
+static mc_mem_region_t mc_region_new_dense(int type, void *start_addr, void* permanent_addr, size_t size, mc_mem_region_t ref_reg)
 {
   mc_mem_region_t new_reg = xbt_new(s_mc_mem_region_t, 1);
   new_reg->start_addr = start_addr;
@@ -163,7 +164,7 @@ static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type,
 {
   mc_mem_region_t ref_reg =
     mc_model_checker->parent_snapshot ? mc_model_checker->parent_snapshot->regions[type] : NULL;
-  mc_mem_region_t new_reg = MC_region_new(type, start_addr, start_addr, size, ref_reg);
+  mc_mem_region_t new_reg = MC_region_new(type, start_addr, permanent_addr, size, ref_reg);
   snapshot->regions[type] = new_reg;
   return;
 }
@@ -171,8 +172,8 @@ static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type,
 static void MC_get_memory_regions(mc_snapshot_t snapshot)
 {
 
-  void *start_heap = ((xbt_mheap_t) std_heap)->base;
-  void *end_heap = ((xbt_mheap_t) std_heap)->breakval;
+  void *start_heap = std_heap->base;
+  void *end_heap = std_heap->breakval;
   MC_snapshot_add_region(snapshot, 0, start_heap, start_heap,
                          (char *) end_heap - (char *) start_heap);
   snapshot->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
@@ -193,9 +194,9 @@ static void MC_get_memory_regions(mc_snapshot_t snapshot)
       mc_mem_region_t ref_reg =
         mc_model_checker->parent_snapshot ? mc_model_checker->parent_snapshot->privatization_regions[i] : NULL;
       snapshot->privatization_regions[i] =
-        MC_region_new(-1, mc_binary_info->start_rw, mappings[i], size_data_exe, ref_reg);
+        MC_region_new(-1, mc_binary_info->start_rw, smpi_privatisation_regions[i].address, size_data_exe, ref_reg);
     }
-    snapshot->privatization_index = loaded_page;
+    snapshot->privatization_index = smpi_loaded_page;
     snapshot->regions[2] = NULL;
   } else
 #endif
@@ -245,50 +246,6 @@ void MC_init_memory_map_info()
 
 }
 
-/** \brief Fill/lookup 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->full_types_by_name, type->subtype->name);
-  if (subtype != NULL) {
-    type->subtype = subtype;
-  }
-
-}
-
-void MC_post_process_types(mc_object_info_t info)
-{
-  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 Fills the position of the segments (executable, read-only, read/write).
  *
  * TODO, use dl_iterate_phdr to be more robust
@@ -389,12 +346,22 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame,
     if (current_variable->address != NULL) {
       new_var->address = current_variable->address;
     } else if (current_variable->locations.size != 0) {
-      new_var->address =
-          (void *) mc_dwarf_resolve_locations(&current_variable->locations,
+      s_mc_location_t location;
+      mc_dwarf_resolve_locations(&location, &current_variable->locations,
                                               current_variable->object_info,
                                               &(stack_frame->unw_cursor),
                                               (void *) stack_frame->frame_base,
                                               NULL, process_index);
+
+      switch(mc_get_location_type(&location)) {
+      case MC_LOCATION_TYPE_ADDRESS:
+        new_var->address = location.memory_location;
+        break;
+      case MC_LOCATION_TYPE_REGISTER:
+      default:
+        xbt_die("Cannot handle non-address variable");
+      }
+
     } else {
       xbt_die("No address");
     }
@@ -599,13 +566,68 @@ static void MC_snapshot_ignore_restore(mc_snapshot_t snapshot)
 int mc_important_snapshot(mc_snapshot_t snapshot)
 {
   // We need this snapshot in order to know which
-  // pages needs to be stored in the next snapshot:
+  // pages needs to be stored in the next snapshot.
+  // This field is only non-NULL when using soft-dirty
+  // page tracking.
   if (snapshot == mc_model_checker->parent_snapshot)
     return true;
 
   return false;
 }
 
+static void MC_get_current_fd(mc_snapshot_t snapshot){
+  
+ struct dirent *fd_number;
+ DIR *fd_dir;
+ char *command;
+ size_t n;
+ char *line = NULL;
+ FILE *fp;
+ int fd_value;
+
+ snapshot->total_fd = 0;
+
+ fd_dir = opendir ("/proc/self/fd");
+ if (fd_dir == NULL) {
+   printf ("Cannot open directory '/proc/self/fd'\n");
+   return;
+ }
+
+ while ((fd_number = readdir(fd_dir)) != NULL) {
+   
+   fd_value = atoi(fd_number->d_name);
+
+   if(fd_value < 3)
+     continue;
+  
+   command = bprintf("readlink /proc/self/fd/%s", fd_number->d_name);
+   fp = popen(command, "r");
+   if(fp == NULL){
+     perror("popen failed");
+     xbt_abort();
+   }
+   xbt_getline(&line, &n, fp); 
+   if(line && strncmp(line, "pipe:", 5) != 0 && strncmp(line, "socket:", 7) != 0){
+     fd_infos_t fd = xbt_new0(s_fd_infos_t, 1);
+     fd->filename = strdup(line);
+     fd->filename[strlen(line)-1] = '\0';
+     fd->number = fd_value;
+     fd->flags = fcntl(fd_value, F_GETFD);
+     fd->current_position = lseek(fd_value, 0, SEEK_CUR);
+     snapshot->current_fd = xbt_realloc(snapshot->current_fd, (snapshot->total_fd + 1) * sizeof(fd_infos_t));
+     snapshot->current_fd[snapshot->total_fd] = fd;
+     snapshot->total_fd++;
+   }
+   
+   xbt_free(command);
+   pclose(fp);
+ }
+
+ xbt_free(line);
+ closedir (fd_dir);
+
+}
+
 mc_snapshot_t MC_take_snapshot(int num_state)
 {
 
@@ -618,6 +640,8 @@ mc_snapshot_t MC_take_snapshot(int num_state)
 
   MC_snapshot_handle_ignore(snapshot);
 
+  MC_get_current_fd(snapshot);
+
   /* Save the std heap and the writable mapped pages of libsimgrid and binary */
   MC_get_memory_regions(snapshot);
   if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
@@ -649,6 +673,7 @@ void MC_restore_snapshot(mc_snapshot_t snapshot)
 {
   mc_snapshot_t parent_snapshot = mc_model_checker->parent_snapshot;
 
+  int new_fd;
   unsigned int i;
   for (i = 0; i < NB_REGIONS; i++) {
     // For privatized, variables we decided it was not necessary to take the snapshot:
@@ -667,10 +692,28 @@ void MC_restore_snapshot(mc_snapshot_t snapshot)
           parent_snapshot ? parent_snapshot->privatization_regions[i] : NULL);
       }
     }
-    switch_data_segment(snapshot->privatization_index);
+  }
+  if(snapshot->privatization_index >= 0) {
+    // We just rewrote the global variables.
+    // The privatisation segment SMPI thinks
+    // is mapped might be inconsistent with the segment which
+    // is really mapped in memory (kernel state).
+    // We ask politely SMPI to map the segment anyway,
+    // even if it thinks it is the current one:
+    smpi_really_switch_data_segment(snapshot->privatization_index);
   }
 #endif
 
+  for(i=0; i < snapshot->total_fd; i++){
+    
+    new_fd = open(snapshot->current_fd[i]->filename, snapshot->current_fd[i]->flags);
+    if(new_fd != -1 && new_fd != snapshot->current_fd[i]->number){
+      dup2(new_fd, snapshot->current_fd[i]->number);
+      //fprintf(stderr, "%p\n", fdopen(snapshot->current_fd[i]->number, "rw"));
+      lseek(snapshot->current_fd[i]->number, snapshot->current_fd[i]->current_position, SEEK_SET);
+    };
+  }
+
   if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
     mc_softdirty_reset();
   }
@@ -679,9 +722,10 @@ void MC_restore_snapshot(mc_snapshot_t snapshot)
   if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
     mc_model_checker->parent_snapshot = snapshot;
   }
+
 }
 
-mc_snapshot_t SIMIX_pre_mc_snapshot(smx_simcall_t simcall)
+mc_snapshot_t simcall_HANDLER_mc_snapshot(smx_simcall_t simcall)
 {
   return MC_take_snapshot(1);
 }