Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Read from remote process in MC_wait_for_requests()
[simgrid.git] / src / mc / mc_checkpoint.c
index a4a83fe..d368810 100644 (file)
@@ -5,7 +5,6 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #define _GNU_SOURCE
-#define UNW_LOCAL_ONLY
 
 #include <unistd.h>
 
@@ -25,7 +24,6 @@
 
 #include "../simix/smx_private.h"
 
-#define UNW_LOCAL_ONLY
 #include <libunwind.h>
 #include <libelf.h>
 
@@ -35,6 +33,9 @@
 #include "mc_snapshot.h"
 #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");
@@ -47,13 +48,16 @@ static void MC_snapshot_stack_free(mc_snapshot_stack_t s)
   if (s) {
     xbt_dynar_free(&(s->local_variables));
     xbt_dynar_free(&(s->stack_frames));
+    mc_unw_destroy_context(s->context);
+    xbt_free(s->context);
     xbt_free(s);
   }
 }
 
 static void MC_snapshot_stack_free_voidp(void *s)
 {
-  MC_snapshot_stack_free((mc_snapshot_stack_t) * (void **) s);
+  mc_snapshot_stack_t stack = (mc_snapshot_stack_t) * (void **) s;
+  MC_snapshot_stack_free(stack);
 }
 
 static void local_variable_free(local_variable_t v)
@@ -452,7 +456,7 @@ static void MC_stack_frame_free_voipd(void *s)
   }
 }
 
-static xbt_dynar_t MC_unwind_stack_frames(void *stack_context)
+static xbt_dynar_t MC_unwind_stack_frames(mc_unw_context_t stack_context)
 {
   mc_process_t process = &mc_model_checker->process;
   xbt_dynar_t result =
@@ -461,8 +465,7 @@ static xbt_dynar_t MC_unwind_stack_frames(void *stack_context)
   unw_cursor_t c;
 
   // TODO, check condition check (unw_init_local==0 means end of frame)
-  // FIXME, cross-process support
-  if (unw_init_local(&c, (unw_context_t *) stack_context) != 0) {
+  if (mc_unw_init_cursor(&c, stack_context) != 0) {
 
     xbt_die("Could not initialize stack unwinding");
 
@@ -501,11 +504,11 @@ static xbt_dynar_t MC_unwind_stack_frames(void *stack_context)
           && !strcmp(frame->name, "smx_ctx_sysv_wrapper"))
         break;
 
-      int ret = ret = unw_step(&c);
+      int ret = unw_step(&c);
       if (ret == 0) {
         xbt_die("Unexpected end of stack.");
       } else if (ret < 0) {
-        xbt_die("Error while unwinding stack.");
+        xbt_die("Error while unwinding stack");
       }
     }
 
@@ -530,7 +533,16 @@ static xbt_dynar_t MC_take_snapshot_stacks(mc_snapshot_t * snapshot)
   // FIXME, cross-process support (stack_areas)
   xbt_dynar_foreach(stacks_areas, cursor, current_stack) {
     mc_snapshot_stack_t st = xbt_new(s_mc_snapshot_stack_t, 1);
-    st->stack_frames = MC_unwind_stack_frames(current_stack->context);
+
+    unw_context_t* original_context = (unw_context_t*) current_stack->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) {
+      xbt_die("Could not initialise the libunwind context.");
+    }
+
+    st->stack_frames = MC_unwind_stack_frames(st->context);
     st->local_variables = MC_get_local_variables_values(st->stack_frames, current_stack->process_index);
     st->process_index = current_stack->process_index;
 
@@ -589,7 +601,7 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot)
   unsigned int cursor = 0;
   mc_checkpoint_ignore_region_t region;
   // FIXME, cross-process support (mc_checkpoint_ignore)
-  xbt_dynar_foreach (mc_checkpoint_ignore, cursor, region) {
+  xbt_dynar_foreach (mc_model_checker->process.checkpoint_ignore, cursor, region) {
     s_mc_snapshot_ignored_data_t ignored_data;
     ignored_data.start = region->addr;
     ignored_data.size = region->size;
@@ -602,7 +614,7 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot)
   }
 
   // Zero the memory:
-  xbt_dynar_foreach (mc_checkpoint_ignore, cursor, region) {
+  xbt_dynar_foreach (mc_model_checker->process.checkpoint_ignore, cursor, region) {
     MC_process_clear_memory(snapshot->process, region->addr, region->size);
   }
 
@@ -691,6 +703,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;
@@ -722,15 +738,15 @@ mc_snapshot_t MC_take_snapshot(int 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
@@ -787,12 +803,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++){
@@ -818,7 +834,8 @@ void MC_restore_snapshot(mc_snapshot_t snapshot)
     && 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();
   }
@@ -834,8 +851,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();
-}