Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Fix broken mc_snapshot_get_heap_end()
[simgrid.git] / src / mc / mc_checkpoint.c
index fe602a4..b2a0538 100644 (file)
@@ -34,6 +34,8 @@
 #include "mc_object_info.h"
 #include "mc_mmu.h"
 #include "mc_unw.h"
+#include "mc_protocol.h"
+#include "mc_smx.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc,
                                 "Logging specific to mc_checkpoint");
@@ -189,20 +191,11 @@ static void MC_region_restore(mc_mem_region_t region, mc_mem_region_t ref_region
   }
 }
 
-// FIXME, multiple privatisation regions
-// FIXME, cross-process
-static inline
-void* MC_privatization_address(mc_process_t process, int process_index)
-{
-  xbt_assert(process_index >= 0);
-  return smpi_privatisation_regions[process_index].address;
-}
-
 static mc_mem_region_t MC_region_new_privatized(
     mc_region_type_t region_type, void *start_addr, void* permanent_addr, size_t size,
     mc_mem_region_t ref_reg)
 {
-  size_t process_count = smpi_process_count();
+  size_t process_count = MC_smpi_process_count();
   mc_mem_region_t region = xbt_new(s_mc_mem_region_t, 1);
   region->region_type = region_type;
   region->storage_type = MC_REGION_STORAGE_TYPE_PRIVATIZED;
@@ -212,13 +205,22 @@ static mc_mem_region_t MC_region_new_privatized(
   region->privatized.regions_count = process_count;
   region->privatized.regions = xbt_new(mc_mem_region_t, process_count);
 
+  // Read smpi_privatisation_regions from MCed:
+  smpi_privatisation_region_t remote_smpi_privatisation_regions;
+  MC_process_read_variable(&mc_model_checker->process,
+    "smpi_privatisation_regions",
+    &remote_smpi_privatisation_regions, sizeof(remote_smpi_privatisation_regions));
+  s_smpi_privatisation_region_t privatisation_regions[process_count];
+  MC_process_read_simple(&mc_model_checker->process, &privatisation_regions,
+    remote_smpi_privatisation_regions, sizeof(privatisation_regions));
+
   for (size_t i = 0; i < process_count; i++) {
     mc_mem_region_t ref_subreg = NULL;
     if (ref_reg && ref_reg->storage_type == MC_REGION_STORAGE_TYPE_PRIVATIZED)
       ref_subreg = ref_reg->privatized.regions[i];
     region->privatized.regions[i] =
       MC_region_new(region_type, start_addr,
-        MC_privatization_address(&mc_model_checker->process, i), size,
+        privatisation_regions[i].address, size,
         ref_subreg);
   }
 
@@ -240,7 +242,7 @@ static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, mc_region_
 
   mc_mem_region_t region;
   const bool privatization_aware = MC_object_info_is_privatized(object_info);
-  if (privatization_aware && smpi_process_count())
+  if (privatization_aware && MC_smpi_process_count())
     region = MC_region_new_privatized(type, start_addr, permanent_addr, size, ref_reg);
   else
     region = MC_region_new(type, start_addr, permanent_addr, size, ref_reg);
@@ -275,9 +277,11 @@ static void MC_get_memory_regions(mc_process_t process, mc_snapshot_t snapshot)
     MC_process_get_malloc_info(process));
 
 #ifdef HAVE_SMPI
-  if (smpi_privatize_global_variables && smpi_process_count()) {
-    // FIXME, cross-process
-    snapshot->privatization_index = smpi_loaded_page;
+  if (smpi_privatize_global_variables && MC_smpi_process_count()) {
+    // snapshot->privatization_index = smpi_loaded_page
+    MC_process_read_variable(&mc_model_checker->process,
+      "smpi_loaded_page", &snapshot->privatization_index,
+      sizeof(snapshot->privatization_index));
   } else
 #endif
   {
@@ -400,12 +404,12 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame,
       new_var->address = current_variable->address;
     } else if (current_variable->locations.size != 0) {
       s_mc_location_t location;
-      // FIXME, cross-process support
-      mc_dwarf_resolve_locations(&location, &current_variable->locations,
-                                              current_variable->object_info,
-                                              &(stack_frame->unw_cursor),
-                                              (void *) stack_frame->frame_base,
-                                              NULL, process_index);
+      mc_dwarf_resolve_locations(
+        &location, &current_variable->locations,
+        current_variable->object_info,
+        &(stack_frame->unw_cursor),
+        (void *) stack_frame->frame_base,
+        (mc_address_space_t) &mc_model_checker->process, process_index);
 
       switch(mc_get_location_type(&location)) {
       case MC_LOCATION_TYPE_ADDRESS:
@@ -532,11 +536,14 @@ static xbt_dynar_t MC_take_snapshot_stacks(mc_snapshot_t * snapshot)
   xbt_dynar_foreach(stacks_areas, cursor, current_stack) {
     mc_snapshot_stack_t st = xbt_new(s_mc_snapshot_stack_t, 1);
 
-    unw_context_t* original_context = (unw_context_t*) current_stack->context;
+    // Read the context from remote process:
+    unw_context_t context;
+    MC_process_read_simple(&mc_model_checker->process,
+      &context, (unw_context_t*) current_stack->context, sizeof(context));
 
     st->context = xbt_new0(s_mc_unw_context_t, 1);
     if (mc_unw_init_context(st->context, &mc_model_checker->process,
-      original_context) < 0) {
+      &context) < 0) {
       xbt_die("Could not initialise the libunwind context.");
     }
 
@@ -557,7 +564,6 @@ static xbt_dynar_t MC_take_snapshot_stacks(mc_snapshot_t * snapshot)
 
 }
 
-// FIXME, cross-process support (mc_heap_comparison_ignore)
 static xbt_dynar_t MC_take_snapshot_ignore()
 {
 
@@ -598,7 +604,6 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot)
   // Copy the memory:
   unsigned int cursor = 0;
   mc_checkpoint_ignore_region_t region;
-  // FIXME, cross-process support (mc_checkpoint_ignore)
   xbt_dynar_foreach (mc_model_checker->process.checkpoint_ignore, cursor, region) {
     s_mc_snapshot_ignored_data_t ignored_data;
     ignored_data.start = region->addr;
@@ -701,6 +706,10 @@ static void MC_get_current_fd(mc_snapshot_t snapshot)
     if (strncmp(link, "pipe:", 5) == 0 || strncmp(link, "socket:", 7) == 0)
       continue;
 
+    // If dot_output enabled, do not handle the corresponding file
+    if (dot_output !=  NULL && strcmp(basename(link), _sg_mc_dot_output_file) == 0)
+      continue;
+
     // This is probably a shared memory used by lttng-ust:
     if(strncmp("/dev/shm/ust-shm-tmp-", link, 21)==0)
       continue;
@@ -726,21 +735,24 @@ static s_mc_address_space_class_t mc_snapshot_class = {
 
 mc_snapshot_t MC_take_snapshot(int num_state)
 {
+  XBT_DEBUG("Taking snapshot %i", num_state);
+
   mc_process_t mc_process = &mc_model_checker->process;
   mc_snapshot_t snapshot = xbt_new0(s_mc_snapshot_t, 1);
   snapshot->process = mc_process;
+  snapshot->num_state = num_state;
   snapshot->address_space.address_space_class = &mc_snapshot_class;
 
   snapshot->enabled_processes = xbt_dynar_new(sizeof(int), NULL);
+
   smx_process_t process;
-  // FIXME, cross-process support (simix_global->process_list)
-  xbt_swag_foreach(process, simix_global->process_list) {
-    xbt_dynar_push_as(snapshot->enabled_processes, int, (int)process->pid);
-  }
+  MC_EACH_SIMIX_PROCESS(process,
+    xbt_dynar_push_as(snapshot->enabled_processes, int, (int)process->pid));
 
   MC_snapshot_handle_ignore(snapshot);
 
-  MC_get_current_fd(snapshot);
+  if (_sg_mc_snapshot_fds)
+    MC_get_current_fd(snapshot);
 
   const bool use_soft_dirty = _sg_mc_sparse_checkpoint
     && _sg_mc_soft_dirty
@@ -785,6 +797,7 @@ void MC_restore_snapshot_regions(mc_snapshot_t snapshot)
   }
 
 #ifdef HAVE_SMPI
+  // TODO, send a message to implement this in the MCed process
   if(snapshot->privatization_index >= 0) {
     // We just rewrote the global variables.
     // The privatisation segment SMPI thinks
@@ -797,12 +810,12 @@ void MC_restore_snapshot_regions(mc_snapshot_t snapshot)
 #endif
 }
 
-// FIXME, cross-process support ~ we need to implement this on the app side
-// or use some form of [remote syscall execution](http://criu.org/Remote_syscall_execution)
-// based on [parasite code execution](http://criu.org/Parasite_code).
 static inline
 void MC_restore_snapshot_fds(mc_snapshot_t snapshot)
 {
+  if (mc_mode == MC_MODE_SERVER)
+    xbt_die("FD snapshot not implemented in client/server mode.");
+
   int new_fd;
   size_t i;
   for(i=0; i < snapshot->total_fd; i++){
@@ -823,12 +836,15 @@ void MC_restore_snapshot_fds(mc_snapshot_t snapshot)
 
 void MC_restore_snapshot(mc_snapshot_t snapshot)
 {
+  XBT_DEBUG("Restore snapshot %i", snapshot->num_state);
+
   const bool use_soft_dirty = _sg_mc_sparse_checkpoint
     && _sg_mc_soft_dirty
     && MC_process_is_self(&mc_model_checker->process);
 
   MC_restore_snapshot_regions(snapshot);
-  MC_restore_snapshot_fds(snapshot);
+  if (_sg_mc_snapshot_fds)
+    MC_restore_snapshot_fds(snapshot);
   if (use_soft_dirty) {
     mc_softdirty_reset();
   }
@@ -844,8 +860,3 @@ mc_snapshot_t simcall_HANDLER_mc_snapshot(smx_simcall_t simcall)
 {
   return MC_take_snapshot(1);
 }
-
-void *MC_snapshot(void)
-{
-  return simcall_mc_snapshot();
-}