Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge master into mc-process
authorGabriel Corona <gabriel.corona@loria.fr>
Thu, 12 Feb 2015 15:03:51 +0000 (16:03 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Thu, 12 Feb 2015 15:31:24 +0000 (16:31 +0100)
111 files changed:
buildtools/Cmake/CompleteInFiles.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/Distrib.cmake
buildtools/Cmake/Flags.cmake
buildtools/Cmake/MakeLib.cmake
buildtools/Cmake/PrintArgs.cmake
buildtools/Cmake/src/internal_config.h.in
examples/msg/mc/bugged1.tesh
examples/msg/mc/bugged1_liveness.c
examples/msg/mc/bugged1_liveness.tesh
examples/msg/mc/bugged1_liveness_sparse.tesh
examples/msg/mc/bugged1_liveness_visited.tesh
examples/msg/mc/bugged1_liveness_visited_sparse.tesh
examples/msg/mc/bugged2.tesh
examples/msg/mc/bugged2_liveness.c
examples/smpi/mc/bugged1_liveness.c
examples/smpi/mc/non_deterministic.tesh
examples/smpi/mc/send_deterministic.tesh
include/simgrid/modelchecker.h
include/xbt/automaton.h
include/xbt/mmalloc.h
src/include/mc/datatypes.h
src/include/mc/mc.h
src/mc/mc_address_space.c [new file with mode: 0644]
src/mc/mc_address_space.h [new file with mode: 0644]
src/mc/mc_base.c
src/mc/mc_base.h
src/mc/mc_checkpoint.c
src/mc/mc_client.c [new file with mode: 0644]
src/mc/mc_client.h [new file with mode: 0644]
src/mc/mc_client_api.c [new file with mode: 0644]
src/mc/mc_comm_determinism.c
src/mc/mc_compare.cpp
src/mc/mc_config.c
src/mc/mc_diff.c
src/mc/mc_dwarf.c
src/mc/mc_dwarf_expression.c
src/mc/mc_forward.h
src/mc/mc_global.c
src/mc/mc_hash.c
src/mc/mc_ignore.c
src/mc/mc_ignore.h [new file with mode: 0644]
src/mc/mc_liveness.c
src/mc/mc_location.h
src/mc/mc_member.c
src/mc/mc_memory.c
src/mc/mc_memory_map.h
src/mc/mc_mmu.h
src/mc/mc_model_checker.c [new file with mode: 0644]
src/mc/mc_model_checker.h
src/mc/mc_object_info.c [new file with mode: 0644]
src/mc/mc_object_info.h
src/mc/mc_page_snapshot.cpp
src/mc/mc_page_store.cpp
src/mc/mc_private.h
src/mc/mc_process.c [new file with mode: 0644]
src/mc/mc_process.h [new file with mode: 0644]
src/mc/mc_protocol.c [new file with mode: 0644]
src/mc/mc_protocol.h [new file with mode: 0644]
src/mc/mc_safety.c
src/mc/mc_server.cpp [new file with mode: 0644]
src/mc/mc_server.h [new file with mode: 0644]
src/mc/mc_snapshot.c
src/mc/mc_snapshot.h
src/mc/mc_unw.c [new file with mode: 0644]
src/mc/mc_unw.h [new file with mode: 0644]
src/mc/mc_unw_vmread.c [new file with mode: 0644]
src/mc/mc_visited.c
src/mc/memory_map.c
src/mc/simgrid_mc.cpp [new file with mode: 0644]
src/simgrid/sg_config.c
src/simix/popping_generated.c
src/simix/simcalls.py
src/simix/smx_global.c
src/smpi/smpi_bench.c
src/surf/network_ib.cpp
src/surf/surf_interface.cpp
src/xbt/automaton/automaton.c
src/xbt/mmalloc/mm_legacy.c
src/xbt/mmalloc/mm_module.c
src/xbt/mmalloc/mmprivate.h
src/xbt/xbt_main.c
src/xbt_modinter.h
teshsuite/mc/dwarf/dwarf.c
teshsuite/mc/dwarf/dwarf.tesh
teshsuite/mc/replay/random_bug.tesh
teshsuite/mc/replay/random_bug_replay.tesh
teshsuite/smpi/isp/umpire/any_src-can-deadlock10.tesh
teshsuite/smpi/isp/umpire/any_src-can-deadlock4.tesh
teshsuite/smpi/isp/umpire/any_src-can-deadlock5.tesh
teshsuite/smpi/isp/umpire/any_src-can-deadlock6.tesh
teshsuite/smpi/isp/umpire/any_src-wait-deadlock.tesh
teshsuite/smpi/isp/umpire/any_src-waitall-deadlock2.tesh
teshsuite/smpi/isp/umpire/any_src-waitall-deadlock3.tesh
teshsuite/smpi/isp/umpire/any_src-waitany-deadlock.tesh
teshsuite/smpi/isp/umpire/any_src-waitany-deadlock2.tesh
teshsuite/smpi/isp/umpire/basic-deadlock-comm_create.tesh
teshsuite/smpi/isp/umpire/basic-deadlock-comm_dup.tesh
teshsuite/smpi/isp/umpire/basic-deadlock-comm_split.tesh
teshsuite/smpi/isp/umpire/basic-deadlock.tesh
teshsuite/smpi/isp/umpire/bcast-deadlock.tesh
teshsuite/smpi/isp/umpire/collective-misorder-allreduce.tesh
teshsuite/smpi/isp/umpire/collective-misorder.tesh
teshsuite/smpi/isp/umpire/complex-deadlock.tesh
teshsuite/smpi/isp/umpire/deadlock-config.tesh
teshsuite/smpi/isp/umpire/finalize-deadlock.tesh
teshsuite/smpi/isp/umpire/irecv-deadlock.tesh
teshsuite/smpi/isp/umpire/no-error.tesh
teshsuite/smpi/isp/umpire/no-error2.tesh
teshsuite/smpi/isp/umpire/no-error3-any_src.tesh
teshsuite/smpi/isp/umpire/no-error3.tesh

index 9600214..b1ba41f 100644 (file)
@@ -172,6 +172,7 @@ CHECK_FUNCTION_EXISTS(asprintf HAVE_ASPRINTF)
 CHECK_FUNCTION_EXISTS(vasprintf HAVE_VASPRINTF)
 CHECK_FUNCTION_EXISTS(makecontext HAVE_MAKECONTEXT)
 CHECK_FUNCTION_EXISTS(mmap HAVE_MMAP)
+CHECK_FUNCTION_EXISTS(process_vm_readv HAVE_PROCESS_VM_READV)
 
 #Check if __thread is defined
 execute_process(
index 790a06d..76cc745 100644 (file)
@@ -594,10 +594,19 @@ set(MC_SRC_BASE
   )
 
 set(MC_SRC
+  src/mc/mc_address_space.h
+  src/mc/mc_address_space.c
   src/mc/mc_forward.h
+  src/mc/mc_process.h
+  src/mc/mc_process.c
+  src/mc/mc_unw.h
+  src/mc/mc_unw.c
+  src/mc/mc_unw_vmread.c
   src/mc/mc_mmalloc.h
   src/mc/mc_model_checker.h
+  src/mc/mc_model_checker.c
   src/mc/mc_object_info.h
+  src/mc/mc_object_info.c
   src/mc/mc_checkpoint.c
   src/mc/mc_snapshot.h
   src/mc/mc_snapshot.c
@@ -633,8 +642,18 @@ set(MC_SRC
   src/mc/mc_visited.c
   src/mc/mc_memory_map.h
   src/mc/memory_map.c
+  src/mc/mc_client.c
+  src/mc/mc_client_api.c
+  src/mc/mc_client.h
+  src/mc/mc_protocol.h
+  src/mc/mc_protocol.c
+  src/mc/mc_server.cpp
+  src/mc/mc_server.h
   )
 
+set(MC_SIMGRID_MC_SRC
+  src/mc/simgrid_mc.cpp)
+
 set(headers_to_install
   include/instr/instr.h
   include/msg/datatypes.h
index 428db7c..53f9e09 100644 (file)
@@ -205,6 +205,7 @@ set(source_to_pack
   ${LUA_SRC}
   ${MC_SRC_BASE}
   ${MC_SRC}
+  ${MC_SIMGRID_MC_SRC}
   ${MSG_SRC}
   ${NS3_SRC}
   ${RNGSTREAM_SRC}
index d45e7f9..27aa988 100644 (file)
@@ -1,9 +1,23 @@
 set(warnCFLAGS "")
 set(optCFLAGS "")
 
+include(CheckCXXCompilerFlag)
+
+if(NOT __VISUALC__ AND NOT __BORLANDC__)
+  CHECK_CXX_COMPILER_FLAG("-std=c++11" HAVE_CXX11)
+  CHECK_CXX_COMPILER_FLAG("-std=c++0x" HAVE_CXX0X)
+  if(HAVE_CXX11)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+  elseif(HAVE_CXX0X)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+  else()
+    message(STATUS "Missing support for C++11.")
+  endif()
+endif()
+
 if(NOT __VISUALC__ AND NOT __BORLANDC__)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}-std=gnu99 -g3")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}-g3")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -g3")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
   set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g")
 else()
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}/Zi")
@@ -63,16 +77,19 @@ if(enable_model-checking AND enable_compile_optimizations)
   set(optCFLAGS "-O0 ")
   # But you can still optimize this:
   foreach(s
-      # src/xbt/mmalloc/mm.c
-      # src/xbt/snprintf.c src/xbt/log.c
-      # src/xbt/dynar.c
-      # src/xbt/set.c src/xbt/setset.c
-      # src/xbt/backtrace_linux.c
-      src/mc/mc_dwarf_expression.c src/mc/mc_dwarf.c src/mc/mc_member.c
-      src/mc/mc_snapshot.c src/mc/mc_page_store.cpp src/mc/mc_page_snapshot.cpp
-      src/mc/mc_compare.cpp src/mc/mc_diff.c
-      src/mc/mc_dwarf.c src/mc/mc_dwarf_attrnames.h src/mc/mc_dwarf_expression.c src/mc/mc_dwarf_tagnames.h
-      src/mc/mc_set.cpp)
+      src/xbt/mmalloc/mm.c
+      src/xbt/log.c src/xbt/xbt_log_appender_file.c
+      src/xbt/xbt_log_layout_format.c src/xbt/xbt_log_layout_simple.c
+      src/xbt/dict.c src/xbt/dict_elm.c src/xbt/dict_multi.c src/xbt/dict_cursor.c
+      src/xbt/set.c src/xbt/setset.c
+      src/xbt/dynar.c src/xbt/fifo.c src/xbt/heap.c src/xbt/swag.c
+      src/xbt/str.c src/xbt/strbuff.c src/xbt/snprintf.c
+      src/xbt/queue.c
+      src/xbt/xbt_os_time.c src/xbt/xbt_os_thread.c
+      src/xbt/sha.c
+      src/xbt/matrix.c
+      src/xbt/backtrace_linux.c
+      ${MC_SRC_BASE} ${MC_SRC})
       set (mcCFLAGS "-O3  -funroll-loops -fno-strict-aliasing")
        if(CMAKE_COMPILER_IS_GNUCC)
          set (mcCFLAGS "${mcCFLAGS} -finline-functions")
index 9f15a91..91611c9 100644 (file)
@@ -22,6 +22,14 @@ endif()
 
 add_dependencies(simgrid maintainer_files)
 
+if(enable_model-checking)
+  add_executable(simgrid-mc ${MC_SIMGRID_MC_SRC})
+  target_link_libraries(simgrid-mc simgrid)
+  set_target_properties(simgrid-mc
+    PROPERTIES
+      RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
+endif()
+
 # Compute the dependencies of SimGrid
 #####################################
 set(SIMGRID_DEP "-lm")
@@ -93,7 +101,7 @@ if(HAVE_MC)
   # The availability of libunwind was checked in CompleteInFiles.cmake
   #   (that includes FindLibunwind.cmake), so simply load it now.
   
-  SET(SIMGRID_DEP "${SIMGRID_DEP} -lunwind")
+  SET(SIMGRID_DEP "${SIMGRID_DEP} -lunwind -lunwind-ptrace")
 
   # Same for libdw
   SET(SIMGRID_DEP "${SIMGRID_DEP} -ldw")
index 5180926..9805a49 100644 (file)
@@ -62,6 +62,7 @@ if(enable_print_message)
   message("HAVE_ASPRINTF ...............: ${HAVE_ASPRINTF}")
   message("HAVE_VASPRINTF ..............: ${HAVE_VASPRINTF}")
   message("HAVE_MMAP ...................: ${HAVE_MMAP}")
+  message("HAVE_PROCESS_VM_READV .......: ${HAVE_PROCESS_VM_READV}")
   message("HAVE_THREAD_LOCAL_STORAGE ...: ${HAVE_THREAD_LOCAL_STORAGE}")
   message("HAVE_MMALLOC ................: ${HAVE_MMALLOC}")
   message("")
index 76f05f8..577178a 100644 (file)
 /* Define to 1 if mmap is available */
 #cmakedefine HAVE_MMAP @HAVE_MMAP@
 
+/* Define to 1 if process_vm_readv is available */
+#cmakedefine HAVE_PROCESS_VM_READV @HAVE_PROCESS_VM_READV@
+
 /* Define to 1 if you have the `getdtablesize' function. */
 #cmakedefine HAVE_GETDTABLESIZE @HAVE_GETDTABLESIZE@
 
index 85cd2ce..03f5d54 100644 (file)
@@ -2,11 +2,8 @@
 
 ! expect signal SIGABRT
 ! timeout 20
-$ ${bindir:=.}/bugged1 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/stack_size:256
-> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
+$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/bugged1 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --log=xbt_cfg.thresh:warning --cfg=contexts/stack_size:256
 > [  0.000000] (0:@) Check a safety property
-> [  0.000000] (0:@) Get debug information ...
-> [  0.000000] (0:@) Get debug information done !
 > [  0.000000] (2:client@HostB) Sent!
 > [  0.000000] (3:client@HostC) Sent!
 > [  0.000000] (1:server@HostA) OK
@@ -37,4 +34,3 @@ $ ${bindir:=.}/bugged1 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%
 > [  0.000000] (1:server@HostA) Expanded states = 22
 > [  0.000000] (1:server@HostA) Visited states = 56
 > [  0.000000] (1:server@HostA) Executed transitions = 52
-
index 5143623..c5e9820 100644 (file)
@@ -26,14 +26,6 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(bugged1_liveness, "my log messages");
 int r=0; 
 int cs=0;
 
-int predR(){
-  return r;
-}
-
-int predCS(){
-  return cs;
-}
-
 #ifdef GARBAGE_STACK
 /** Do not use a clean stack */
 static void garbage_stack(void) {
@@ -165,8 +157,8 @@ int main(int argc, char *argv[])
   char **options = &argv[1];
 
   MSG_config("model-check/property","promela_bugged1_liveness");
-  MC_automaton_new_propositional_symbol("r", &predR);
-  MC_automaton_new_propositional_symbol("cs", &predCS);
+  MC_automaton_new_propositional_symbol_pointer("r", &r);
+  MC_automaton_new_propositional_symbol_pointer("cs", &cs);
 
   const char* platform_file = options[0];
   const char* application_file = options[1];
index 5f72c22..dc3c3a7 100644 (file)
@@ -2,11 +2,8 @@
 
 ! expect signal SIGABRT
 ! timeout 20
-$ ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../../platforms/platform.xml ${srcdir:=.}/deploy_bugged1_liveness.xml --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/stack_size:256
-> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
+$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../../platforms/platform.xml ${srcdir:=.}/deploy_bugged1_liveness.xml --log=xbt_cfg.thresh:warning --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/stack_size:256
 > [  0.000000] (0:@) Check the liveness property promela_bugged1_liveness
-> [  0.000000] (0:@) Get debug information ...
-> [  0.000000] (0:@) Get debug information done !
 > [  0.000000] (2:client@Boivin) Ask the request
 > [  0.000000] (3:client@Fafard) Ask the request
 > [  0.000000] (2:client@Boivin) Propositions changed : r=1, cs=0
index bc934d9..1ad6da3 100644 (file)
@@ -2,12 +2,8 @@
 
 ! expect signal SIGABRT
 ! timeout 60
-$ ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../../platforms/platform.xml ${srcdir:=.}/deploy_bugged1_liveness.xml --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/stack_size:256 --cfg=model-check/sparse-checkpoint:yes
-> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
-> [  0.000000] (0:@) Configuration change: Set 'model-check/sparse-checkpoint' to 'yes'
+$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../../platforms/platform.xml ${srcdir:=.}/deploy_bugged1_liveness.xml --log=xbt_cfg.thresh:warning --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/stack_size:256 --cfg=model-check/sparse-checkpoint:yes
 > [  0.000000] (0:@) Check the liveness property promela_bugged1_liveness
-> [  0.000000] (0:@) Get debug information ...
-> [  0.000000] (0:@) Get debug information done !
 > [  0.000000] (2:client@Boivin) Ask the request
 > [  0.000000] (3:client@Fafard) Ask the request
 > [  0.000000] (2:client@Boivin) Propositions changed : r=1, cs=0
index d05858a..859e793 100644 (file)
@@ -2,12 +2,8 @@
 
 ! expect signal SIGABRT
 ! timeout 90
-$ ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../../platforms/platform.xml ${srcdir:=.}/deploy_bugged1_liveness_visited.xml --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/visited:100 --cfg=contexts/stack_size:256
-> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
-> [  0.000000] (0:@) Configuration change: Set 'model-check/visited' to '100'
+$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../../platforms/platform.xml ${srcdir:=.}/deploy_bugged1_liveness_visited.xml --log=xbt_cfg.thresh:warning --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/visited:100 --cfg=contexts/stack_size:256
 > [  0.000000] (0:@) Check the liveness property promela_bugged1_liveness
-> [  0.000000] (0:@) Get debug information ...
-> [  0.000000] (0:@) Get debug information done !
 > [  0.000000] (2:client@Boivin) Ask the request
 > [  0.000000] (3:client@Fafard) Ask the request
 > [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly
index 9e987ea..1750e8b 100644 (file)
@@ -2,13 +2,8 @@
 
 ! expect signal SIGABRT
 ! timeout 90
-$ ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../../platforms/platform.xml ${srcdir:=.}/deploy_bugged1_liveness_visited.xml --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/visited:100 --cfg=contexts/stack_size:256 --cfg=model-check/sparse-checkpoint:yes
-> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
-> [  0.000000] (0:@) Configuration change: Set 'model-check/visited' to '100'
-> [  0.000000] (0:@) Configuration change: Set 'model-check/sparse-checkpoint' to 'yes'
+$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../../platforms/platform.xml ${srcdir:=.}/deploy_bugged1_liveness_visited.xml --log=xbt_cfg.thresh:warning --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/visited:100 --cfg=contexts/stack_size:256 --cfg=model-check/sparse-checkpoint:yes
 > [  0.000000] (0:@) Check the liveness property promela_bugged1_liveness
-> [  0.000000] (0:@) Get debug information ...
-> [  0.000000] (0:@) Get debug information done !
 > [  0.000000] (2:client@Boivin) Ask the request
 > [  0.000000] (3:client@Fafard) Ask the request
 > [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly
index d3d7eec..49619ce 100644 (file)
@@ -2,11 +2,8 @@
 
 ! expect signal SIGABRT
 ! timeout 20
-$ ${bindir:=.}/bugged2 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/stack_size:256
-> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
+$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/bugged2 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --log=xbt_cfg.thresh:warning --cfg=contexts/stack_size:256
 > [  0.000000] (0:@) Check a safety property
-> [  0.000000] (0:@) Get debug information ...
-> [  0.000000] (0:@) Get debug information done !
 > [  0.000000] (2:client@HostB) Send 1!
 > [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
@@ -899,4 +896,3 @@ $ ${bindir:=.}/bugged2 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%
 > [  0.000000] (1:server@HostA) Expanded states = 461
 > [  0.000000] (1:server@HostA) Visited states = 2271
 > [  0.000000] (1:server@HostA) Executed transitions = 2117
-
index d6beac0..25e2ded 100644 (file)
@@ -19,11 +19,6 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(bugged3, "my log messages");
  
 int cs = 0;
 
-int predCS(){
-  return cs;
-}
-
-
 int coordinator(int argc, char **argv);
 int client(int argc, char **argv);
 
@@ -103,7 +98,7 @@ int main(int argc, char *argv[])
   MSG_init(&argc, argv);
 
   MSG_config("model-check/property","promela_bugged2_liveness");
-  MC_automaton_new_propositional_symbol("cs", &predCS);
+  MC_automaton_new_propositional_symbol_pointer("cs", &cs);
   
   MSG_create_environment("../msg_platform.xml");
   MSG_function_register("coordinator", coordinator);
index 68a5ef4..b92f4e3 100644 (file)
 
 int r, cs;
 
-static int predR(){
-  return r;
-}
-
-static int predCS(){
-  return cs;
-}
-
-
 int main(int argc, char **argv){
 
   int err, size, rank;
@@ -47,8 +38,8 @@ int main(int argc, char **argv){
     exit(1);
   }
 
-  MC_automaton_new_propositional_symbol("r", &predR);
-  MC_automaton_new_propositional_symbol("cs", &predCS);
+  MC_automaton_new_propositional_symbol_pointer("r", &r);
+  MC_automaton_new_propositional_symbol_pointer("cs", &cs);
 
   MC_ignore(&(status.count), sizeof(status.count));
 
index d32f46a..494c917 100644 (file)
@@ -1,18 +1,9 @@
 #! ./tesh
 
 ! timeout 60
-$ ../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/hostfile_non_deterministic  -platform ${srcdir:=.}/../../platforms/cluster.xml --cfg=model-check:1 --cfg=model-check/communications_determinism:1 --cfg=smpi/send_is_detached_thres:0 --cfg=smpi/running_power:1e9 ./smpi_non_deterministic
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/communications_determinism' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/send_is_detached_thres' to '0'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
+$ ../../../smpi_script/bin/smpirun -wrapper ${bindir:=.}/../../../bin/simgrid-mc -hostfile ${srcdir:=.}/hostfile_non_deterministic  -platform ${srcdir:=.}/../../platforms/cluster.xml --log=xbt_cfg.thresh:warning --cfg=model-check:1 --cfg=model-check/communications_determinism:1 --cfg=smpi/send_is_detached_thres:0 --cfg=smpi/running_power:1e9 ./smpi_non_deterministic
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check communication determinism
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > [0.000000] [mc_comm_determinism/INFO] The communications pattern of the process 1 is different! (Different communication : 1)
 > [0.000000] [mc_comm_determinism/INFO] ****************************************************
 > [0.000000] [mc_comm_determinism/INFO] ***** Non-deterministic communications pattern *****
index 6bafa97..39dccba 100644 (file)
@@ -1,18 +1,9 @@
 #! ./tesh
 
 ! timeout 60
-$ ../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/hostfile_send_deterministic  -platform ${srcdir:=.}/../../platforms/cluster.xml --cfg=model-check:1 --cfg=model-check/send_determinism:1 --cfg=smpi/send_is_detached_thres:0 --cfg=smpi/running_power:1e9 ./smpi_send_deterministic
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/send_determinism' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/send_is_detached_thres' to '0'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
+$ ../../../smpi_script/bin/smpirun -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -hostfile ${srcdir:=.}/hostfile_send_deterministic  -platform ${srcdir:=.}/../../platforms/cluster.xml --log=xbt_cfg.thresh:warning --cfg=model-check:1 --cfg=model-check/send_determinism:1 --cfg=smpi/send_is_detached_thres:0 --cfg=smpi/running_power:1e9 ./smpi_send_deterministic
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check communication determinism
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > [0.000000] [mc_global/INFO] Expanded states = 520
 > [0.000000] [mc_global/INFO] Visited states = 1476
 > [0.000000] [mc_global/INFO] Executed transitions = 1312
index 0d41344..3cc7e2d 100644 (file)
 
 SG_BEGIN_DECL()
 
+/** Replay path (if any) in string representation
+ *
+ *  This is a path as generated by `MC_record_stack_to_string()`.
+ */
+XBT_PUBLIC_DATA(char*) MC_record_path;
+
+/** Whether the replay mode is enabled */
+static inline bool MC_record_replay_is_active(void) {
+  return MC_record_path;
+}
+
 XBT_PUBLIC(int) MC_random(int min, int max);
 
 #ifdef HAVE_MC
@@ -28,7 +39,11 @@ extern int _sg_mc_visited;
 #define MC_visited_reduction()          _sg_mc_visited
 
 XBT_PUBLIC(void) MC_assert(int);
-XBT_PUBLIC(void) MC_automaton_new_propositional_symbol(const char* id, void* fct);
+XBT_PUBLIC(void) MC_automaton_new_propositional_symbol(const char* id, int(*fct)(void));
+XBT_PUBLIC(void) MC_automaton_new_propositional_symbol_pointer(const char *id, int* value);
+XBT_PUBLIC(void) MC_automaton_new_propositional_symbol_callback(const char* id,
+  xbt_automaton_propositional_symbol_callback_type callback,
+  void* data, xbt_automaton_propositional_symbol_free_function_type free_function);
 XBT_PUBLIC(void *) MC_snapshot(void);
 XBT_PUBLIC(int) MC_compare_snapshots(void *s1, void *s2);
 XBT_PUBLIC(void) MC_cut(void);
@@ -41,6 +56,9 @@ XBT_PUBLIC(void) MC_ignore(void *addr, size_t size);
 
 #define MC_assert(a)                    xbt_assert(a)
 #define MC_automaton_new_propositional_symbol(a, b) ((void)0)
+#define MC_automaton_new_propositional_symbol_pointer(a, b) ((void)0)
+#define MC_automaton_new_propositional_symbol_callback(id,callback,data,free_function) \
+  if(free_function) free_function(data);
 #define MC_snapshot()                   ((void*)0)
 #define MC_compare_snapshots(a, b)      0
 #define MC_cut()                        ((void)0)
@@ -48,17 +66,6 @@ XBT_PUBLIC(void) MC_ignore(void *addr, size_t size);
 
 #endif
 
-/** Replay path (if any) in string representation
- *
- *  This is a path as generated by `MC_record_stack_to_string()`.
- */
-XBT_PUBLIC_DATA(char*) MC_record_path;
-
-/** Whether the replay mode is enabled */
-static inline bool MC_record_replay_is_active(void) {
-  return MC_record_path;
-}
-
 SG_END_DECL()
 
 #endif /* SIMGRID_MODELCHECKER_H */
index c24453f..e6267e2 100644 (file)
@@ -57,13 +57,11 @@ typedef struct xbt_automaton_transition {
 typedef struct xbt_automaton_transition* xbt_automaton_transition_t;
 
 
-typedef struct xbt_automaton_propositional_symbol{
-  char* pred;
-  void* function;
-} s_xbt_automaton_propositional_symbol;
-
+typedef struct xbt_automaton_propositional_symbol s_xbt_automaton_propositional_symbol;
 typedef struct xbt_automaton_propositional_symbol* xbt_automaton_propositional_symbol_t;
 
+typedef int (*xbt_automaton_propositional_symbol_callback_type)(void*);
+typedef void (*xbt_automaton_propositional_symbol_free_function_type)(void*);
 
 XBT_PUBLIC(xbt_automaton_t) xbt_automaton_new(void);
 
@@ -99,7 +97,21 @@ XBT_PUBLIC(void) xbt_automaton_display(xbt_automaton_t a);
 
 XBT_PUBLIC(void) xbt_automaton_exp_label_display(xbt_automaton_exp_label_t l);
 
-XBT_PUBLIC(xbt_automaton_propositional_symbol_t) xbt_automaton_propositional_symbol_new(xbt_automaton_t a, const char* id, void* fct);
+// xbt_automaton_propositional_symbol constructors:
+XBT_PUBLIC(xbt_automaton_propositional_symbol_t) xbt_automaton_propositional_symbol_new(xbt_automaton_t a, const char* id, int(*fct)(void));
+XBT_PUBLIC(xbt_automaton_propositional_symbol_t) xbt_automaton_propositional_symbol_new_pointer(xbt_automaton_t a, const char* id, int* value);
+XBT_PUBLIC(xbt_automaton_propositional_symbol_t) xbt_automaton_propositional_symbol_new_callback(
+  xbt_automaton_t a, const char* id,
+  xbt_automaton_propositional_symbol_callback_type callback,
+  void* data, xbt_automaton_propositional_symbol_free_function_type free_function);
+
+// xbt_automaton_propositional_symbol accessors:
+XBT_PUBLIC(xbt_automaton_propositional_symbol_callback_type) xbt_automaton_propositional_symbol_get_callback(xbt_automaton_propositional_symbol_t symbol);
+XBT_PUBLIC(void*) xbt_automaton_propositional_symbol_get_data(xbt_automaton_propositional_symbol_t symbol);
+XBT_PUBLIC(const char*) xbt_automaton_propositional_symbol_get_name(xbt_automaton_propositional_symbol_t symbol);
+
+// xbt_automaton_propositional_symbol methods!
+XBT_PUBLIC(int) xbt_automaton_propositional_symbol_evaluate(xbt_automaton_propositional_symbol_t symbol);
 
 XBT_PUBLIC(xbt_automaton_state_t) xbt_automaton_get_current_state(xbt_automaton_t a);
 
index 191d3cc..5e32858 100644 (file)
@@ -62,7 +62,7 @@ XBT_PUBLIC( void ) *xbt_mheap_destroy(xbt_mheap_t md);
 XBT_PUBLIC( xbt_mheap_t ) mmalloc_get_default_md(void);
 
 /* To change the heap used when using the legacy version malloc/free/realloc and such */
-void mmalloc_set_current_heap(xbt_mheap_t new_heap);
+xbt_mheap_t mmalloc_set_current_heap(xbt_mheap_t new_heap);
 xbt_mheap_t mmalloc_get_current_heap(void);
 
 struct s_mc_snapshot;
@@ -71,12 +71,14 @@ struct s_dw_type;
 int mmalloc_compare_heap(struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2);
 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(int process_index, void *area1, void* area2, struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2, xbt_dynar_t previous, struct s_dw_type *type, int pointer_level);
+int compare_heap_area(int process_index, const void *area1, const void* area2, struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2, xbt_dynar_t previous, struct s_dw_type *type, int pointer_level);
 void reset_heap_information(void);
 
 size_t mmalloc_get_bytes_used(xbt_mheap_t);
 ssize_t mmalloc_get_busy_size(xbt_mheap_t, void *ptr);
 
+void* malloc_no_memset(size_t n);
+
 SG_END_DECL()
 
 #endif
index 20805a8..22c7e4f 100644 (file)
@@ -7,8 +7,6 @@
 #ifndef MC_DATATYPE_H
 #define MC_DATATYPE_H
 
-#define UNW_LOCAL_ONLY
-
 #include "xbt/misc.h"
 #include "xbt/swag.h"
 #include "xbt/fifo.h"
@@ -33,7 +31,6 @@ typedef struct s_mc_heap_ignore_region{
 
 typedef struct s_stack_region{
   void *address;
-  char *process_name;
   void *context;
   size_t size;
   int block;
index 2bfe7ad..23b1781 100644 (file)
@@ -51,11 +51,10 @@ extern int _sg_mc_comms_determinism;
 extern int _sg_mc_send_determinism;
 extern int _sg_mc_safety;
 extern int _sg_mc_liveness;
+extern int _sg_mc_snapshot_fds;
 
 extern xbt_dynar_t mc_heap_comparison_ignore;
 extern xbt_dynar_t stacks_areas;
-extern void *maestro_stack_start;
-extern void *maestro_stack_end;
 
 /********************************* Global *************************************/
 void _mc_cfg_cb_reduce(const char *name, int pos);
@@ -65,6 +64,7 @@ void _mc_cfg_cb_soft_dirty(const char *name, int pos);
 void _mc_cfg_cb_property(const char *name, int pos);
 void _mc_cfg_cb_timeout(const char *name, int pos);
 void _mc_cfg_cb_hash(const char *name, int pos);
+void _mc_cfg_cb_snapshot_fds(const char *name, int pos);
 void _mc_cfg_cb_max_depth(const char *name, int pos);
 void _mc_cfg_cb_visited(const char *name, int pos);
 void _mc_cfg_cb_dot_output(const char *name, int pos);
@@ -88,6 +88,7 @@ XBT_PUBLIC(void) MC_new_stack_area(void *stack, smx_process_t process, void *con
 /********************************* Memory *************************************/
 XBT_PUBLIC(void) MC_memory_init(void);  /* Initialize the memory subsystem */
 XBT_PUBLIC(void) MC_memory_exit(void);
+XBT_PUBLIC(void) MC_memory_init_server(void);
 
 SG_END_DECL()
 
diff --git a/src/mc/mc_address_space.c b/src/mc/mc_address_space.c
new file mode 100644 (file)
index 0000000..df738ec
--- /dev/null
@@ -0,0 +1,7 @@
+/* Copyright (c) 2008-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 "mc_address_space.h"
diff --git a/src/mc/mc_address_space.h b/src/mc/mc_address_space.h
new file mode 100644 (file)
index 0000000..a8724bc
--- /dev/null
@@ -0,0 +1,89 @@
+/* Copyright (c) 2008-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. */
+
+#ifndef MC_ADDRESS_SPACE_H
+#define MC_ADDRESS_SPACE_H
+
+#include <stdint.h>
+
+#include "mc_forward.h"
+
+// ***** Data types
+
+typedef enum e_adress_space_read_flags {
+  MC_ADDRESS_SPACE_READ_FLAGS_NONE = 0,
+
+  /** Avoid a copy for when the data is available in the current process.
+   *
+   *  In this case, the return value of a MC_address_space_read might
+   *  be different from the provided buffer.
+   */
+  MC_ADDRESS_SPACE_READ_FLAGS_LAZY = 1
+} e_adress_space_read_flags_t;
+
+/** Process index used when no process is available
+ *
+ *  The expected behaviour is that if a process index is needed it will fail.
+ * */
+#define MC_PROCESS_INDEX_MISSING -1
+
+#define MC_PROCESS_INDEX_DISABLED -2
+
+/** Process index when any process is suitable
+ *
+ * We could use a special negative value in the future.
+ */
+#define MC_PROCESS_INDEX_ANY 0
+
+// ***** Class definition
+
+typedef struct s_mc_address_space s_mc_address_space_t, *mc_address_space_t;
+typedef struct s_mc_address_space_class s_mc_address_space_class_t, *mc_address_space_class_t;
+
+/** Abstract base class for an address space
+ *
+ *  This is the base class for all virtual address spaces (process, snapshot).
+ *  It uses dynamic dispatch based on a vtable (`address_space_class`).
+ */
+struct s_mc_address_space {
+  const s_mc_address_space_class_t* address_space_class;
+};
+
+/** Class object (vtable) for the virtual address spaces
+ */
+struct s_mc_address_space_class {
+  const void* (*read)(
+    mc_address_space_t address_space, e_adress_space_read_flags_t flags,
+    void* target, const void* addr, size_t size,
+    int process_index);
+  mc_process_t (*get_process)(mc_address_space_t address_space);
+};
+
+// ***** Virtual/non-final methods
+
+/** Read data from the given address space
+ *
+ *  Dynamic dispatch.
+ */
+static inline __attribute__((always_inline))
+const void* MC_address_space_read(
+  mc_address_space_t address_space, e_adress_space_read_flags_t flags,
+  void* target, const void* addr, size_t size,
+  int process_index)
+{
+  return address_space->address_space_class->read(
+    address_space, flags, target, addr, size,
+    process_index);
+}
+
+static inline __attribute__((always_inline))
+const void* MC_address_space_get_process(mc_address_space_t address_space)
+{
+  return address_space->address_space_class->get_process(address_space);
+}
+
+
+#endif
index 82ca8c6..96c14b2 100644 (file)
 #include "../simix/smx_private.h"
 #include "mc_record.h"
 
+#ifdef HAVE_MC
+#include "mc_process.h"
+#include "mc_model_checker.h"
+#endif
+
 XBT_LOG_NEW_CATEGORY(mc, "All MC categories");
 
-/**
- * \brief Schedules all the process that are ready to run
- */
 void MC_wait_for_requests(void)
 {
   smx_process_t process;
index c462414..c21a00b 100644 (file)
 
 SG_BEGIN_DECL()
 
+/** Check if the given simcall can be resolved
+ *
+ *  \return `TRUE` or `FALSE`
+ */
 int MC_request_is_enabled(smx_simcall_t req);
+
+/** Check if the given simcall is visible
+ *
+ *  \return `TRUE` or `FALSE`
+ */
 int MC_request_is_visible(smx_simcall_t req);
+
+/** Execute everything which is invisible
+ *
+ *  Execute all the processes that are ready to run and all invisible simcalls
+ *  iteratively until there doesn't remain any. At this point, the function
+ *  returns to the caller which can handle the visible (and ready) simcalls.
+ */
 void MC_wait_for_requests(void);
 
 extern double *mc_time;
index 38f6489..1fdf717 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>
 
 #include "mc_snapshot.h"
 #include "mc_object_info.h"
 #include "mc_mmu.h"
+#include "mc_unw.h"
+#include "mc_protocol.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc,
                                 "Logging specific to mc_checkpoint");
 
-char *libsimgrid_path;
-
 /************************************  Free functions **************************************/
 /*****************************************************************************************/
 
@@ -49,13 +47,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)
@@ -69,59 +70,66 @@ static void local_variable_free_voidp(void *v)
   local_variable_free((local_variable_t) * (void **) v);
 }
 
-void MC_region_destroy(mc_mem_region_t reg)
+void MC_region_destroy(mc_mem_region_t region)
 {
-  if (!reg)
+  if (!region)
     return;
-
-  //munmap(reg->data, reg->size);
-  xbt_free(reg->data);
-  if (reg->page_numbers) {
-    mc_free_page_snapshot_region(reg->page_numbers, mc_page_count(reg->size));
+  switch(region->storage_type) {
+    case MC_REGION_STORAGE_TYPE_NONE:
+      break;
+    case MC_REGION_STORAGE_TYPE_FLAT:
+      xbt_free(region->flat.data);
+      break;
+    case MC_REGION_STORAGE_TYPE_CHUNKED:
+      mc_free_page_snapshot_region(region->chunked.page_numbers, mc_page_count(region->size));
+      xbt_free(region->chunked.page_numbers);
+      break;
+    case MC_REGION_STORAGE_TYPE_PRIVATIZED:
+      {
+        size_t regions_count = region->privatized.regions_count;
+        for (size_t i=0; i!=regions_count; ++i) {
+          MC_region_destroy(region->privatized.regions[i]);
+        }
+        free(region->privatized.regions);
+        break;
+      }
   }
-  xbt_free(reg);
+  xbt_free(region);
 }
 
 void MC_free_snapshot(mc_snapshot_t snapshot)
 {
-  unsigned int i;
-  for (i = 0; i < NB_REGIONS; i++) {
-    MC_region_destroy(snapshot->regions[i]);
+  for (size_t i = 0; i < snapshot->snapshot_regions_count; i++) {
+    MC_region_destroy(snapshot->snapshot_regions[i]);
   }
-
+  xbt_free(snapshot->snapshot_regions);
   xbt_free(snapshot->stack_sizes);
   xbt_dynar_free(&(snapshot->stacks));
   xbt_dynar_free(&(snapshot->to_ignore));
   xbt_dynar_free(&snapshot->ignored_data);
-
-  if (snapshot->privatization_regions) {
-    size_t n = xbt_dynar_length(snapshot->enabled_processes);
-    for (i = 0; i != n; ++i) {
-      MC_region_destroy(snapshot->privatization_regions[i]);
-    }
-    xbt_free(snapshot->privatization_regions);
-  }
-
   xbt_free(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(
+  mc_region_type_t region_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;
-  new_reg->permanent_addr = permanent_addr;
-  new_reg->data = NULL;
-  new_reg->size = size;
-  new_reg->page_numbers = NULL;
-  new_reg->data = xbt_malloc(size);
-  memcpy(new_reg->data, permanent_addr, size);
+  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_FLAT;
+  region->start_addr = start_addr;
+  region->permanent_addr = permanent_addr;
+  region->size = size;
+  region->flat.data = xbt_malloc(size);
+  MC_process_read(&mc_model_checker->process, MC_ADDRESS_SPACE_READ_FLAGS_NONE,
+    region->flat.data, permanent_addr, size,
+    MC_PROCESS_INDEX_DISABLED);
   XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu",
-            type, new_reg->data, permanent_addr, size);
-  return new_reg;
-
+            region_type, region->flat.data, permanent_addr, size);
+  return region;
 }
 
 /** @brief Take a snapshot of a given region
@@ -132,7 +140,7 @@ static mc_mem_region_t mc_region_new_dense(int type, void *start_addr, void* per
  * @param size         Size of the data*
  * @param ref_reg      Reference corresponding region
  */
-static mc_mem_region_t MC_region_new(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(mc_region_type_t type, void *start_addr, void* permanent_addr, size_t size, mc_mem_region_t ref_reg)
 {
   if (_sg_mc_sparse_checkpoint) {
     return mc_region_new_sparse(type, start_addr, permanent_addr, size, ref_reg);
@@ -151,113 +159,139 @@ static mc_mem_region_t MC_region_new(int type, void *start_addr, void* permanent
  *  @param reg     Target region
  *  @param reg_reg Current region (if not NULL), used for lazy per page restoration
  */
-static void MC_region_restore(mc_mem_region_t reg, mc_mem_region_t ref_reg)
+static void MC_region_restore(mc_mem_region_t region, mc_mem_region_t ref_region)
 {
-  /*FIXME: check if start_addr is still mapped, if it is not, then map it
-    before copying the data */
-  if (!reg->page_numbers) {
-    memcpy(reg->permanent_addr, reg->data, reg->size);
-  } else {
-    mc_region_restore_sparse(reg, ref_reg);
+  switch(region->storage_type) {
+  case MC_REGION_STORAGE_TYPE_NONE:
+  default:
+    xbt_die("Storage type not supported");
+    break;
+
+  case MC_REGION_STORAGE_TYPE_FLAT:
+    MC_process_write(&mc_model_checker->process, region->flat.data,
+      region->permanent_addr, region->size);
+    break;
+
+  case MC_REGION_STORAGE_TYPE_CHUNKED:
+    mc_region_restore_sparse(&mc_model_checker->process, region, ref_region);
+    break;
+
+  case MC_REGION_STORAGE_TYPE_PRIVATIZED:
+    {
+      bool has_ref_regions = ref_region &&
+        ref_region->storage_type == MC_REGION_STORAGE_TYPE_PRIVATIZED;
+      size_t process_count = region->privatized.regions_count;
+      for (size_t i = 0; i < process_count; i++) {
+        MC_region_restore(region->privatized.regions[i],
+          has_ref_regions ? ref_region->privatized.regions[i] : NULL);
+      }
+      break;
+    }
   }
-  return;
 }
 
-static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type,
-                                   void *start_addr, void* permanent_addr, size_t size)
+// 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();
+  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;
+  region->start_addr = start_addr;
+  region->permanent_addr = permanent_addr;
+  region->size = size;
+  region->privatized.regions_count = process_count;
+  region->privatized.regions = xbt_new(mc_mem_region_t, process_count);
+
+  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,
+        ref_subreg);
+  }
+
+  return region;
+}
 
+static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, mc_region_type_t type,
+                                  mc_object_info_t object_info,
+                                  void *start_addr, void* permanent_addr, size_t size)
 {
-  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, permanent_addr, size, ref_reg);
-  snapshot->regions[type] = new_reg;
+  if (type == MC_REGION_TYPE_DATA)
+    xbt_assert(object_info, "Missing object info for object.");
+  else if (type == MC_REGION_TYPE_HEAP)
+    xbt_assert(!object_info, "Unexpected object info for heap region.");
+
+  mc_mem_region_t ref_reg = NULL;
+  if (mc_model_checker->parent_snapshot)
+    ref_reg = mc_model_checker->parent_snapshot->snapshot_regions[index];
+
+  mc_mem_region_t region;
+  const bool privatization_aware = MC_object_info_is_privatized(object_info);
+  if (privatization_aware && 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);
+
+  region->object_info = object_info;
+  snapshot->snapshot_regions[index] = region;
   return;
 }
 
-static void MC_get_memory_regions(mc_snapshot_t snapshot)
+static void MC_get_memory_regions(mc_process_t process, mc_snapshot_t snapshot)
 {
+  const size_t n = process->object_infos_size;
+  snapshot->snapshot_regions_count = n + 1;
+  snapshot->snapshot_regions = xbt_new0(mc_mem_region_t, n + 1);
+
+  for (size_t i = 0; i!=n; ++i) {
+    mc_object_info_t object_info = process->object_infos[i];
+    MC_snapshot_add_region(i, snapshot, MC_REGION_TYPE_DATA, object_info,
+      object_info->start_rw, object_info->start_rw,
+      object_info->end_rw - object_info->start_rw);
+  }
 
-  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);
-  snapshot->privatization_regions = NULL;
+  xbt_mheap_t heap = MC_process_get_heap(process);
+  void *start_heap = heap->base;
+  void *end_heap = heap->breakval;
 
-  MC_snapshot_add_region(snapshot, 1,
-      mc_libsimgrid_info->start_rw, mc_libsimgrid_info->start_rw,
-      mc_libsimgrid_info->end_rw - mc_libsimgrid_info->start_rw);
+  MC_snapshot_add_region(n, snapshot, MC_REGION_TYPE_HEAP, NULL,
+                        start_heap, start_heap,
+                        (char *) end_heap - (char *) start_heap);
+  snapshot->heap_bytes_used = mmalloc_get_bytes_used_remote(
+    heap->heaplimit,
+    MC_process_get_malloc_info(process));
 
 #ifdef HAVE_SMPI
-  size_t i;
   if (smpi_privatize_global_variables && smpi_process_count()) {
-    // Snapshot the global variable of the application separately for each
-    // simulated process:
-    snapshot->privatization_regions =
-      xbt_new(mc_mem_region_t, smpi_process_count());
-    for (i = 0; i < smpi_process_count(); i++) {
-      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, smpi_privatisation_regions[i].address, size_data_exe, ref_reg);
-    }
+    // FIXME, cross-process
     snapshot->privatization_index = smpi_loaded_page;
-    snapshot->regions[2] = NULL;
   } else
 #endif
   {
-    MC_snapshot_add_region(snapshot, 2,
-                           mc_binary_info->start_rw, mc_binary_info->start_rw,
-                           mc_binary_info->end_rw - mc_binary_info->start_rw);
-    snapshot->privatization_regions = NULL;
-    snapshot->privatization_index = -1;
-  }
-}
-
-/** @brief Finds the range of the different memory segments and binary paths */
-void MC_init_memory_map_info()
-{
-
-  unsigned int i = 0;
-  s_map_region_t reg;
-  memory_map_t maps = MC_get_memory_map();
-
-  maestro_stack_start = NULL;
-  maestro_stack_end = NULL;
-  libsimgrid_path = NULL;
-
-  while (i < maps->mapsize) {
-    reg = maps->regions[i];
-    if (maps->regions[i].pathname == NULL) {
-      // Nothing to do
-    } else if ((reg.prot & PROT_WRITE)
-               && !memcmp(maps->regions[i].pathname, "[stack]", 7)) {
-      maestro_stack_start = reg.start_addr;
-      maestro_stack_end = reg.end_addr;
-    } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)
-               && !memcmp(basename(maps->regions[i].pathname), "libsimgrid",
-                          10)) {
-      if (libsimgrid_path == NULL)
-        libsimgrid_path = strdup(maps->regions[i].pathname);
-    }
-    i++;
+    snapshot->privatization_index = MC_PROCESS_INDEX_MISSING;
   }
-
-  xbt_assert(maestro_stack_start, "maestro_stack_start");
-  xbt_assert(maestro_stack_end, "maestro_stack_end");
-  xbt_assert(libsimgrid_path, "libsimgrid_path&");
-
-  MC_free_memory_map(maps);
-
 }
 
 /** \brief Fills the position of the segments (executable, read-only, read/write).
  *
- * TODO, use dl_iterate_phdr to be more robust
+ *  `dl_iterate_phdr` would be more robust but would not work in cross-process.
  * */
 void MC_find_object_address(memory_map_t maps, mc_object_info_t result)
 {
-
   unsigned int i = 0;
   s_map_region_t reg;
   const char *name = basename(result->file_name);
@@ -294,6 +328,18 @@ void MC_find_object_address(memory_map_t maps, mc_object_info_t result)
     i++;
   }
 
+  result->start = result->start_rw;
+  if ((const void*) result->start_ro > result->start)
+    result->start = result->start_ro;
+  if ((const void*) result->start_exec > result->start)
+    result->start = result->start_exec;
+
+  result->end = result->end_rw;
+  if (result->end_ro && (const void*) result->end_ro < result->end)
+    result->end = result->end_ro;
+  if (result->end_exec && (const void*) result->end_exec > result->end)
+    result->end = result->end_exec;
+
   xbt_assert(result->file_name);
   xbt_assert(result->start_rw);
   xbt_assert(result->start_exec);
@@ -324,6 +370,8 @@ static bool mc_valid_variable(dw_variable_t var, dw_frame_t scope,
 static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame,
                                            dw_frame_t scope, int process_index, xbt_dynar_t result)
 {
+  mc_process_t process = &mc_model_checker->process;
+
   void *ip = (void *) stack_frame->ip;
   if (ip < scope->low_pc || ip >= scope->high_pc)
     return;
@@ -336,7 +384,8 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame,
       continue;
 
     int region_type;
-    if ((long) stack_frame->ip > (long) mc_libsimgrid_info->start_exec)
+    // FIXME, get rid of `region_type`
+    if ((long) stack_frame->ip > (long) process->libsimgrid_info->start_exec)
       region_type = 1;
     else
       region_type = 2;
@@ -352,6 +401,7 @@ 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),
@@ -405,15 +455,16 @@ 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 =
       xbt_dynar_new(sizeof(mc_stack_frame_t), MC_stack_frame_free_voipd);
 
   unw_cursor_t c;
 
   // TODO, check condition check (unw_init_local==0 means end of frame)
-  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");
 
@@ -435,7 +486,7 @@ static xbt_dynar_t MC_unwind_stack_frames(void *stack_context)
 
       // TODO, use real addresses in frame_t instead of fixing it here
 
-      dw_frame_t frame = MC_find_function_by_ip((void *) ip);
+      dw_frame_t frame = MC_process_find_function(process, (void *) ip);
       stack_frame->frame = frame;
 
       if (frame) {
@@ -452,11 +503,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");
       }
     }
 
@@ -478,9 +529,19 @@ static xbt_dynar_t MC_take_snapshot_stacks(mc_snapshot_t * snapshot)
   unsigned int cursor = 0;
   stack_region_t current_stack;
 
+  // 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;
 
@@ -497,6 +558,7 @@ 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()
 {
 
@@ -531,23 +593,28 @@ static void mc_free_snapshot_ignored_data_pvoid(void* data) {
 
 static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot)
 {
+  xbt_assert(snapshot->process);
   snapshot->ignored_data = xbt_dynar_new(sizeof(s_mc_snapshot_ignored_data_t), mc_free_snapshot_ignored_data_pvoid);
 
   // Copy the memory:
   unsigned int cursor = 0;
   mc_checkpoint_ignore_region_t region;
-  xbt_dynar_foreach (mc_checkpoint_ignore, cursor, 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;
     ignored_data.size = region->size;
     ignored_data.data = malloc(region->size);
-    memcpy(ignored_data.data, region->addr, region->size);
+    // TODO, we should do this once per privatization segment:
+    MC_process_read(snapshot->process,
+      MC_ADDRESS_SPACE_READ_FLAGS_NONE,
+      ignored_data.data, region->addr, region->size, MC_PROCESS_INDEX_DISABLED);
     xbt_dynar_push(snapshot->ignored_data, &ignored_data);
   }
 
   // Zero the memory:
-  xbt_dynar_foreach (mc_checkpoint_ignore, cursor, region) {
-    memset(region->addr, 0, region->size);
+  xbt_dynar_foreach (mc_model_checker->process.checkpoint_ignore, cursor, region) {
+    MC_process_clear_memory(snapshot->process, region->addr, region->size);
   }
 
 }
@@ -557,7 +624,8 @@ static void MC_snapshot_ignore_restore(mc_snapshot_t snapshot)
   unsigned int cursor = 0;
   s_mc_snapshot_ignored_data_t ignored_data;
   xbt_dynar_foreach (snapshot->ignored_data, cursor, ignored_data) {
-    memcpy(ignored_data.start, ignored_data.data, ignored_data.size);
+    MC_process_write(snapshot->process,
+      ignored_data.data, ignored_data.start, ignored_data.size);
   }
 }
 
@@ -580,17 +648,18 @@ int mc_important_snapshot(mc_snapshot_t snapshot)
   return false;
 }
 
-static void MC_get_current_fd(mc_snapshot_t snapshot){
+static void MC_get_current_fd(mc_snapshot_t snapshot)
+{
 
   snapshot->total_fd = 0;
 
   const size_t fd_dir_path_size = 20;
   char fd_dir_path[fd_dir_path_size];
   if (snprintf(fd_dir_path, fd_dir_path_size,
-    "/proc/%lli/fd", (long long int) getpid()) > fd_dir_path_size)
+    "/proc/%lli/fd", (long long int) snapshot->process->pid) > fd_dir_path_size)
     xbt_die("Unexpected buffer is too small for fd_dir_path");
 
-  DIR* fd_dir = opendir (fd_dir_path);
+  DIR* fd_dir = opendir(fd_dir_path);
   if (fd_dir == NULL)
     xbt_die("Cannot open directory '/proc/self/fd'\n");
 
@@ -605,7 +674,8 @@ static void MC_get_current_fd(mc_snapshot_t snapshot){
 
     const size_t source_size = 25;
     char source[25];
-    if (snprintf(source, source_size, "/proc/self/fd/%s", fd_number->d_name) > source_size)
+    if (snprintf(source, source_size, "/proc/%lli/fd/%s",
+        (long long int) snapshot->process->pid, fd_number->d_name) > source_size)
       xbt_die("Unexpected buffer is too small for fd %s", fd_number->d_name);
 
     const size_t link_size = 200;
@@ -655,25 +725,37 @@ static void MC_get_current_fd(mc_snapshot_t snapshot){
   closedir (fd_dir);
 }
 
+static s_mc_address_space_class_t mc_snapshot_class = {
+  .read = (void*) &MC_snapshot_read
+};
+
 mc_snapshot_t MC_take_snapshot(int 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->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_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
+    && MC_process_is_self(mc_process);
 
   /* 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) {
+  MC_get_memory_regions(mc_process, snapshot);
+  if (use_soft_dirty)
     mc_softdirty_reset();
-  }
 
   snapshot->to_ignore = MC_take_snapshot_ignore();
 
@@ -690,36 +772,25 @@ mc_snapshot_t MC_take_snapshot(int num_state)
   }
 
   MC_snapshot_ignore_restore(snapshot);
-  if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
+  if (use_soft_dirty)
     mc_model_checker->parent_snapshot = snapshot;
-  }
   return snapshot;
 }
 
-void MC_restore_snapshot(mc_snapshot_t snapshot)
+static inline
+void MC_restore_snapshot_regions(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++) {
+  const size_t n = snapshot->snapshot_regions_count;
+  for (size_t i = 0; i < n; i++) {
     // For privatized, variables we decided it was not necessary to take the snapshot:
-    if (snapshot->regions[i])
-      MC_region_restore(snapshot->regions[i],
-        parent_snapshot ? parent_snapshot->regions[i] : NULL);
+    if (snapshot->snapshot_regions[i])
+      MC_region_restore(snapshot->snapshot_regions[i],
+        parent_snapshot ? parent_snapshot->snapshot_regions[i] : NULL);
   }
 
 #ifdef HAVE_SMPI
-  if (snapshot->privatization_regions) {
-    // Restore the global variables of the application separately for each
-    // simulated process:
-    for (i = 0; i < smpi_process_count(); i++) {
-      if (snapshot->privatization_regions[i]) {
-        MC_region_restore(snapshot->privatization_regions[i],
-          parent_snapshot ? parent_snapshot->privatization_regions[i] : NULL);
-      }
-    }
-  }
   if(snapshot->privatization_index >= 0) {
     // We just rewrote the global variables.
     // The privatisation segment SMPI thinks
@@ -730,7 +801,16 @@ void MC_restore_snapshot(mc_snapshot_t snapshot)
     smpi_really_switch_data_segment(snapshot->privatization_index);
   }
 #endif
+}
+
+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++){
     
     new_fd = open(snapshot->current_fd[i]->filename, snapshot->current_fd[i]->flags);
@@ -745,24 +825,29 @@ void MC_restore_snapshot(mc_snapshot_t snapshot)
     };
     lseek(snapshot->current_fd[i]->number, snapshot->current_fd[i]->current_position, SEEK_SET);
   }
+}
 
-  if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
+void MC_restore_snapshot(mc_snapshot_t snapshot)
+{
+  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);
+  if (_sg_mc_snapshot_fds)
+    MC_restore_snapshot_fds(snapshot);
+  if (use_soft_dirty) {
     mc_softdirty_reset();
   }
-
   MC_snapshot_ignore_restore(snapshot);
-  if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
+  if (use_soft_dirty) {
     mc_model_checker->parent_snapshot = snapshot;
   }
 
+  mc_model_checker->process.cache_flags = 0;
 }
 
 mc_snapshot_t simcall_HANDLER_mc_snapshot(smx_simcall_t simcall)
 {
   return MC_take_snapshot(1);
 }
-
-void *MC_snapshot(void)
-{
-  return simcall_mc_snapshot();
-}
diff --git a/src/mc/mc_client.c b/src/mc/mc_client.c
new file mode 100644 (file)
index 0000000..6a8d4ee
--- /dev/null
@@ -0,0 +1,94 @@
+/* Copyright (c) 2015. 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 <stdlib.h>
+#include <errno.h>
+#include <error.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <xbt/log.h>
+#include <xbt/sysdep.h>
+#include <xbt/mmalloc.h>
+
+#include "mc_protocol.h"
+#include "mc_client.h"
+
+// We won't need those once the separation MCer/MCed is complete:
+#include "mc_mmalloc.h"
+#include "mc_ignore.h"
+#include "mc_model_checker.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_client, mc, "MC client logic");
+
+mc_client_t mc_client;
+
+void MC_client_init(void)
+{
+  if (mc_client) {
+    XBT_WARN("MC_client_init called more than once.");
+    return;
+  }
+
+  char* fd_env = getenv(MC_ENV_SOCKET_FD);
+  if (!fd_env)
+    xbt_die("MC socket not found");
+
+  int fd = atoi(fd_env);
+  XBT_DEBUG("Model-checked application found socket FD %i", fd);
+
+  int type;
+  socklen_t socklen = sizeof(type);
+  if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &socklen) != 0)
+    xbt_die("Could not check socket type: %s", strerror(errno));
+  if (type != SOCK_DGRAM)
+    xbt_die("Unexpected socket type %i", type);
+  XBT_DEBUG("Model-checked application found expected socket type");
+
+  mc_client = xbt_new0(s_mc_client_t, 1);
+  mc_client->fd = fd;
+  mc_client->active = 1;
+}
+
+void MC_client_hello(void)
+{
+  XBT_DEBUG("Greeting the MC server");
+  if (MC_protocol_hello(mc_client->fd) != 0)
+    xbt_die("Could not say hello the MC server");
+  XBT_DEBUG("Greeted the MC server");
+}
+
+void MC_client_send_message(void* message, size_t size)
+{
+  if (MC_protocol_send(mc_client->fd, message, size))
+    xbt_die("Could not send message %i", (int) ((mc_message_t)message)->type);
+}
+
+void MC_client_handle_messages(void)
+{
+  while (1) {
+    XBT_DEBUG("Waiting messages from model-checker");
+
+    char message_buffer[MC_MESSAGE_LENGTH];
+    size_t s;
+    if ((s = recv(mc_client->fd, &message_buffer, sizeof(message_buffer), 0)) == -1)
+      xbt_die("Could not receive commands from the model-checker: %s",
+        strerror(errno));
+
+    XBT_DEBUG("Receive message from model-checker");
+    s_mc_message_t message;
+    if (s < sizeof(message))
+      xbt_die("Message is too short");
+    memcpy(&message, message_buffer, sizeof(message));
+    switch (message.type) {
+    case MC_MESSAGE_CONTINUE:
+      return;
+    default:
+      xbt_die("Unexpected message from model-checker %i", message.type);
+    }
+  }
+}
diff --git a/src/mc/mc_client.h b/src/mc/mc_client.h
new file mode 100644 (file)
index 0000000..638a8ea
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (c) 2015. 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. */
+
+#ifndef MC_CLIENT_H
+#define MC_CLIENT_H
+
+#include <xbt/misc.h>
+
+SG_BEGIN_DECL()
+
+typedef struct s_mc_client {
+  int active;
+  int fd;
+} s_mc_client_t, *mc_client_t;
+
+extern mc_client_t mc_client;
+
+void MC_client_init(void);
+void MC_client_hello(void);
+void MC_client_handle_messages(void);
+void MC_client_send_message(void* message, size_t size);
+
+void MC_ignore(void* addr, size_t size);
+
+
+SG_END_DECL()
+
+#endif
diff --git a/src/mc/mc_client_api.c b/src/mc/mc_client_api.c
new file mode 100644 (file)
index 0000000..fad7c0f
--- /dev/null
@@ -0,0 +1,74 @@
+/* Copyright (c) 2008-2015. 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 <xbt/log.h>
+#include <xbt/fifo.h>
+#include <xbt/sysdep.h>
+#include <simgrid/modelchecker.h>
+
+#include "mc_record.h"
+#include "mc_private.h"
+#include "mc_mmalloc.h"
+#include "mc_model_checker.h"
+#include "mc_ignore.h"
+#include "mc_protocol.h"
+#include "mc_client.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_client_api, mc,
+  "Public API for the model-checked application");
+
+void MC_assert(int prop)
+{
+  if (MC_is_active() && !prop) {
+    XBT_INFO("**************************");
+    XBT_INFO("*** PROPERTY NOT VALID ***");
+    XBT_INFO("**************************");
+    XBT_INFO("Counter-example execution trace:");
+    MC_record_dump_path(mc_stack);
+    MC_dump_stack_safety(mc_stack);
+    MC_print_statistics(mc_stats);
+    xbt_abort();
+  }
+}
+
+// TODO, MC_automaton_new_propositional_symbol
+
+void *MC_snapshot(void)
+{
+  return simcall_mc_snapshot();
+}
+
+int simcall_HANDLER_mc_compare_snapshots(smx_simcall_t simcall,
+                                   mc_snapshot_t s1, mc_snapshot_t s2)
+{
+  return snapshot_compare(s1, s2);
+}
+
+int MC_compare_snapshots(void *s1, void *s2)
+{
+  return simcall_mc_compare_snapshots(s1, s2);
+}
+
+void MC_cut(void)
+{
+  user_max_depth_reached = 1;
+}
+
+void MC_ignore(void* addr, size_t size)
+{
+  if (mc_mode == MC_MODE_CLIENT) {
+    s_mc_ignore_memory_message_t message;
+    message.type = MC_MESSAGE_IGNORE_MEMORY;
+    message.addr = addr;
+    message.size = size;
+    MC_client_send_message(&message, sizeof(message));
+  }
+
+  // TODO, remove this once the migration has been completed
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
+  MC_process_ignore_memory(&mc_model_checker->process, addr, size);
+  mmalloc_set_current_heap(heap);
+}
index b68e563..6576d60 100644 (file)
@@ -167,6 +167,7 @@ static void print_incomplete_communications_pattern(){
 
 static void update_comm_pattern(mc_comm_pattern_t comm_pattern, smx_synchro_t comm)
 {
+  mc_process_t process = &mc_model_checker->process;
   void *addr_pointed;
   comm_pattern->src_proc = comm->comm.src_proc->pid;
   comm_pattern->dst_proc = comm->comm.dst_proc->pid;
@@ -176,7 +177,8 @@ static void update_comm_pattern(mc_comm_pattern_t comm_pattern, smx_synchro_t co
     comm_pattern->data_size = *(comm->comm.dst_buff_size);
     comm_pattern->data = xbt_malloc0(comm_pattern->data_size);
     addr_pointed = *(void **) comm->comm.src_buff;
-    if (addr_pointed > (void*) std_heap && addr_pointed < std_heap->breakval)
+    if (addr_pointed > (void*) process->heap_address
+        && addr_pointed < MC_process_get_heap(process)->breakval)
       memcpy(comm_pattern->data, addr_pointed, comm_pattern->data_size);
     else
       memcpy(comm_pattern->data, comm->comm.src_buff, comm_pattern->data_size);
@@ -216,7 +218,7 @@ void list_comm_pattern_free_voidp(void *p) {
 
 void get_comm_pattern(xbt_dynar_t list, smx_simcall_t request, e_mc_call_type_t call_type)
 {
-
+  mc_process_t process = &mc_model_checker->process;
   mc_comm_pattern_t pattern = NULL;
   pattern = xbt_new0(s_mc_comm_pattern_t, 1);
   pattern->data_size = -1;
@@ -237,7 +239,8 @@ void get_comm_pattern(xbt_dynar_t list, smx_simcall_t request, e_mc_call_type_t
       pattern->data_size = pattern->comm->comm.src_buff_size;
       pattern->data = xbt_malloc0(pattern->data_size);
       addr_pointed = *(void **) pattern->comm->comm.src_buff;
-      if (addr_pointed > (void*) std_heap && addr_pointed < std_heap->breakval)
+      if (addr_pointed > (void*) process->heap_address
+          && addr_pointed < MC_process_get_heap(process)->breakval)
         memcpy(pattern->data, addr_pointed, pattern->data_size);
       else
         memcpy(pattern->data, pattern->comm->comm.src_buff, pattern->data_size);
@@ -322,16 +325,12 @@ void complete_comm_pattern(xbt_dynar_t list, smx_synchro_t comm, int backtrackin
 
 void MC_pre_modelcheck_comm_determinism(void)
 {
-
-  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
+  MC_SET_MC_HEAP;
 
   mc_state_t initial_state = NULL;
   smx_process_t process;
   int i;
 
-  if (!mc_mem_set)
-    MC_SET_MC_HEAP;
-
   if (_sg_mc_visited > 0)
     visited_states = xbt_dynar_new(sizeof(mc_visited_state_t), visited_state_free_voidp);
  
index 4745d3a..5b6352a 100644 (file)
@@ -60,7 +60,6 @@ extern "C" {
 static void stack_region_free(stack_region_t s)
 {
   if (s) {
-    xbt_free(s->process_name);
     xbt_free(s);
   }
 }
@@ -102,6 +101,8 @@ static int compare_areas_with_type(struct mc_compare_state& state,
                                    void* real_area2, mc_snapshot_t snapshot2, mc_mem_region_t region2,
                                    dw_type_t type, int pointer_level)
 {
+  mc_process_t process = &mc_model_checker->process;
+
   unsigned int cursor = 0;
   dw_type_t member, subtype, subsubtype;
   int elm_size, i, res;
@@ -115,7 +116,7 @@ static int compare_areas_with_type(struct mc_compare_state& state,
   case DW_TAG_enumeration_type:
   case DW_TAG_union_type:
   {
-    return mc_snapshot_region_memcmp(
+    return MC_snapshot_region_memcmp(
       real_area1, region1, real_area2, region2,
       type->byte_size) != 0;
   }
@@ -169,8 +170,8 @@ static int compare_areas_with_type(struct mc_compare_state& state,
   case DW_TAG_reference_type:
   case DW_TAG_rvalue_reference_type:
   {
-    void* addr_pointed1 = mc_snapshot_read_pointer_region(real_area1, region1);
-    void* addr_pointed2 = mc_snapshot_read_pointer_region(real_area2, region2);
+    void* addr_pointed1 = MC_region_read_pointer(region1, real_area1);
+    void* addr_pointed2 = MC_region_read_pointer(region2, real_area2);
 
     if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) {
       return (addr_pointed1 != addr_pointed2);
@@ -190,10 +191,10 @@ static int compare_areas_with_type(struct mc_compare_state& state,
       // * a pointer leads to the read-only segment of the current object;
       // * a pointer lead to a different ELF object.
 
-      if (addr_pointed1 > std_heap
+      if (addr_pointed1 > process->heap_address
           && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)) {
         if (!
-            (addr_pointed2 > std_heap
+            (addr_pointed2 > process->heap_address
              && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2)))
           return 1;
         // The pointers are both in the heap:
@@ -228,9 +229,9 @@ static int compare_areas_with_type(struct mc_compare_state& state,
   case DW_TAG_class_type:
     xbt_dynar_foreach(type->members, cursor, member) {
       void *member1 =
-        mc_member_resolve(real_area1, type, member, snapshot1, process_index);
+        mc_member_resolve(real_area1, type, member, (mc_address_space_t) snapshot1, process_index);
       void *member2 =
-        mc_member_resolve(real_area2, type, member, snapshot2, process_index);
+        mc_member_resolve(real_area2, type, member, (mc_address_space_t) snapshot2, process_index);
       mc_mem_region_t subregion1 = mc_get_region_hinted(member1, snapshot1, process_index, region1);
       mc_mem_region_t subregion2 = mc_get_region_hinted(member2, snapshot2, process_index, region2);
       res =
@@ -260,6 +261,32 @@ static int compare_global_variables(mc_object_info_t object_info,
                                     mc_snapshot_t snapshot2)
 {
   xbt_assert(r1 && r2, "Missing region.");
+
+#ifdef HAVE_SMPI
+  if (r1->storage_type == MC_REGION_STORAGE_TYPE_PRIVATIZED) {
+    xbt_assert(process_index >= 0);
+    if (r2->storage_type != MC_REGION_STORAGE_TYPE_PRIVATIZED) {
+      return 1;
+    }
+
+    size_t process_count = smpi_process_count();
+    xbt_assert(process_count == r1->privatized.regions_count
+      && process_count == r2->privatized.regions_count);
+
+    // Compare the global variables separately for each simulates process:
+    for (size_t process_index = 0; process_index < process_count; process_index++) {
+      int is_diff = compare_global_variables(object_info, process_index,
+        r1->privatized.regions[process_index], r2->privatized.regions[process_index],
+        snapshot1, snapshot2);
+      if (is_diff) return 1;
+    }
+    return 0;
+  }
+#else
+  xbt_assert(r1->storage_type != MC_REGION_STORAGE_TYPE_PRIVATIZED);
+#endif
+  xbt_assert(r2->storage_type != MC_REGION_STORAGE_TYPE_PRIVATIZED);
+
   struct mc_compare_state state;
 
   xbt_dynar_t variables;
@@ -357,6 +384,7 @@ static int compare_local_variables(int process_index,
 
 int snapshot_compare(void *state1, void *state2)
 {
+  mc_process_t process = &mc_model_checker->process;
 
   mc_snapshot_t s1, s2;
   int num1, num2;
@@ -456,10 +484,14 @@ int snapshot_compare(void *state1, void *state2)
 #endif
 
   /* Init heap information used in heap comparison algorithm */
-  xbt_mheap_t heap1 = (xbt_mheap_t) mc_snapshot_read(std_heap, s1, MC_NO_PROCESS_INDEX,
-    alloca(sizeof(struct mdesc)), sizeof(struct mdesc));
-  xbt_mheap_t heap2 = (xbt_mheap_t) mc_snapshot_read(std_heap, s2, MC_NO_PROCESS_INDEX,
-    alloca(sizeof(struct mdesc)), sizeof(struct mdesc));
+  xbt_mheap_t heap1 = (xbt_mheap_t) MC_snapshot_read(
+    s1, MC_ADDRESS_SPACE_READ_FLAGS_LAZY,
+    alloca(sizeof(struct mdesc)), process->heap_address, sizeof(struct mdesc),
+    MC_PROCESS_INDEX_MISSING);
+  xbt_mheap_t heap2 = (xbt_mheap_t) MC_snapshot_read(
+    s2, MC_ADDRESS_SPACE_READ_FLAGS_LAZY,
+    alloca(sizeof(struct mdesc)), process->heap_address, sizeof(struct mdesc),
+    MC_PROCESS_INDEX_MISSING);
   res_init = init_heap_information(heap1, heap2, s1->to_ignore, s2->to_ignore);
   if (res_init == -1) {
 #ifdef MC_DEBUG
@@ -535,21 +567,27 @@ int snapshot_compare(void *state1, void *state2)
     cursor++;
   }
 
+  size_t regions_count = s1->snapshot_regions_count;
+  // TODO, raise a difference instead?
+  xbt_assert(regions_count == s2->snapshot_regions_count);
 
+  mc_comp_times->global_variables_comparison_time = 0;
 
-  const char *names[3] = { "?", "libsimgrid", "binary" };
-#ifdef MC_DEBUG
-  double *times[3] = {
-    NULL,
-    &mc_comp_times->libsimgrid_global_variables_comparison_time,
-    &mc_comp_times->binary_global_variables_comparison_time
-  };
-#endif
+  for (size_t k = 0; k != regions_count; ++k) {
+    mc_mem_region_t region1 = s1->snapshot_regions[k];
+    mc_mem_region_t region2 = s2->snapshot_regions[k];
 
-  mc_object_info_t object_infos[] = { NULL, mc_libsimgrid_info, mc_binary_info };
+    // Preconditions:
+    if (region1->region_type != MC_REGION_TYPE_DATA)
+      continue;
+
+    xbt_assert(region1->region_type == region2->region_type);
+    xbt_assert(region1->object_info == region2->object_info);
+
+    xbt_assert(region1->object_info);
+
+    const char* name = region1->object_info->file_name;
 
-  int k = 0;
-  for (k = 2; k != 0; --k) {
 #ifdef MC_DEBUG
     if (is_diff == 0)
       xbt_os_walltimer_stop(timer);
@@ -557,33 +595,24 @@ int snapshot_compare(void *state1, void *state2)
 #endif
 
     /* Compare global variables */
-#ifdef HAVE_SMPI
-    if (object_infos[k] == mc_binary_info && smpi_privatize_global_variables) {
-      // Compare the global variables separately for each simulates process:
-      for (int process_index = 0; process_index < smpi_process_count(); process_index++) {
-        is_diff =
-          compare_global_variables(object_infos[k], process_index,
-            s1->privatization_regions[process_index], s2->privatization_regions[process_index], s1, s2);
-        if (is_diff) break;
-      }
-    }
-    else
-#endif
-      is_diff =
-        compare_global_variables(object_infos[k], MC_NO_PROCESS_INDEX, s1->regions[k], s2->regions[k], s1, s2);
+    is_diff =
+      compare_global_variables(region1->object_info, MC_ADDRESS_SPACE_READ_FLAGS_NONE,
+        region1, region2,
+        s1, s2);
 
     if (is_diff != 0) {
       XBT_TRACE3(mc, state_diff, num1, num2, "Different global variables");
 #ifdef MC_DEBUG
       xbt_os_walltimer_stop(timer);
-      *times[k] = xbt_os_timer_elapsed(timer);
+      mc_comp_times->global_variables_comparison_time
+        += xbt_os_timer_elapsed(timer);
       XBT_DEBUG("(%d - %d) Different global variables in %s", num1, num2,
-                names[k]);
+                name);
       errors++;
 #else
 #ifdef MC_VERBOSE
       XBT_VERB("(%d - %d) Different global variables in %s", num1, num2,
-               names[k]);
+               name);
 #endif
 
       reset_heap_information();
@@ -679,28 +708,9 @@ void print_comparison_times()
   XBT_DEBUG("- Nb processes : %f", mc_comp_times->nb_processes_comparison_time);
   XBT_DEBUG("- Nb bytes used : %f", mc_comp_times->bytes_used_comparison_time);
   XBT_DEBUG("- Stacks sizes : %f", mc_comp_times->stacks_sizes_comparison_time);
-  XBT_DEBUG("- Binary global variables : %f",
-            mc_comp_times->binary_global_variables_comparison_time);
-  XBT_DEBUG("- Libsimgrid global variables : %f",
-            mc_comp_times->libsimgrid_global_variables_comparison_time);
+  XBT_DEBUG("- GLobal variables : %f", mc_comp_times->global_variables_comparison_time);
   XBT_DEBUG("- Heap : %f", mc_comp_times->heap_comparison_time);
   XBT_DEBUG("- Stacks : %f", mc_comp_times->stacks_comparison_time);
 }
 
-/**************************** MC snapshot compare simcall **************************/
-/***********************************************************************************/
-
-int simcall_HANDLER_mc_compare_snapshots(smx_simcall_t simcall,
-                                   mc_snapshot_t s1, mc_snapshot_t s2)
-{
-  return snapshot_compare(s1, s2);
-}
-
-int MC_compare_snapshots(void *s1, void *s2)
-{
-
-  return simcall_mc_compare_snapshots(s1, s2);
-
-}
-
 }
index 07c9179..6251712 100644 (file)
@@ -58,7 +58,7 @@ int _sg_mc_comms_determinism = 0;
 int _sg_mc_send_determinism = 0;
 int _sg_mc_safety = 0;
 int _sg_mc_liveness = 0;
-
+int _sg_mc_snapshot_fds = 0;
 
 void _mc_cfg_cb_reduce(const char *name, int pos)
 {
@@ -118,6 +118,15 @@ void _mc_cfg_cb_hash(const char *name, int pos)
   _sg_mc_hash = xbt_cfg_get_boolean(_sg_cfg_set, name);
 }
 
+void _mc_cfg_cb_snapshot_fds(const char *name, int pos)
+{
+  if (_sg_cfg_init_status && !_sg_do_model_check) {
+    xbt_die
+        ("You are specifying a value to enable/disable the use of FD snapshoting, but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+  }
+  _sg_mc_snapshot_fds = xbt_cfg_get_boolean(_sg_cfg_set, name);
+}
+
 void _mc_cfg_cb_max_depth(const char *name, int pos)
 {
   if (_sg_cfg_init_status && !_sg_do_model_check) {
index 03dfb36..257481c 100644 (file)
@@ -20,7 +20,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_diff, xbt,
 
 xbt_dynar_t mc_heap_comparison_ignore;
 xbt_dynar_t stacks_areas;
-void *maestro_stack_start, *maestro_stack_end;
+
 
 
 /********************************* Backtrace ***********************************/
@@ -229,7 +229,7 @@ static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1,
 }
 
 static ssize_t heap_comparison_ignore_size(xbt_dynar_t ignore_list,
-                                           void *address)
+                                           const void *address)
 {
 
   unsigned int cursor = 0;
@@ -253,7 +253,7 @@ static ssize_t heap_comparison_ignore_size(xbt_dynar_t ignore_list,
   return -1;
 }
 
-static int is_stack(void *address)
+static int is_stack(const void *address)
 {
   unsigned int cursor = 0;
   stack_region_t stack;
@@ -415,9 +415,22 @@ void reset_heap_information()
 
 }
 
-int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
+// TODO, have a robust way to find it in O(1)
+static inline
+mc_mem_region_t MC_get_heap_region(mc_snapshot_t snapshot)
 {
+  size_t n = snapshot->snapshot_regions_count;
+  for (size_t i=0; i!=n; ++i) {
+    mc_mem_region_t region = snapshot->snapshot_regions[i];
+    if (region->region_type == MC_REGION_TYPE_HEAP)
+      return region;
+  }
+  xbt_die("No heap region");
+}
 
+int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
+{
+  mc_process_t process = &mc_model_checker->process;
   struct s_mc_diff *state = mc_diff_info;
 
   /* Start comparison */
@@ -434,17 +447,20 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
   malloc_info heapinfo_temp1, heapinfo_temp2;
   malloc_info heapinfo_temp2b;
 
-  mc_mem_region_t heap_region1 = snapshot1->regions[0];
-  mc_mem_region_t heap_region2 = snapshot2->regions[0];
+  mc_mem_region_t heap_region1 = MC_get_heap_region(snapshot1);
+  mc_mem_region_t heap_region2 = MC_get_heap_region(snapshot2);
+
+  // This is the address of std_heap->heapinfo in the application process:
+  void* heapinfo_address = &((xbt_mheap_t) process->heap_address)->heapinfo;
 
   // This is in snapshot do not use them directly:
-  malloc_info* heapinfos1 = mc_snapshot_read_pointer(&std_heap->heapinfo, snapshot1, MC_NO_PROCESS_INDEX);
-  malloc_info* heapinfos2 = mc_snapshot_read_pointer(&std_heap->heapinfo, snapshot2, MC_NO_PROCESS_INDEX);
+  const malloc_info* heapinfos1 = MC_snapshot_read_pointer(snapshot1, heapinfo_address, MC_PROCESS_INDEX_MISSING);
+  const malloc_info* heapinfos2 = MC_snapshot_read_pointer(snapshot2, heapinfo_address, MC_PROCESS_INDEX_MISSING);
 
   while (i1 <= state->heaplimit) {
 
-    malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i1], heap_region1, &heapinfo_temp1, sizeof(malloc_info));
-    malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i1], heap_region2, &heapinfo_temp2, sizeof(malloc_info));
+    const malloc_info* heapinfo1 = MC_region_read(heap_region1, &heapinfo_temp1, &heapinfos1[i1], sizeof(malloc_info));
+    const malloc_info* heapinfo2 = MC_region_read(heap_region2, &heapinfo_temp2, &heapinfos2[i1], sizeof(malloc_info));
 
     if (heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type == MMALLOC_TYPE_HEAPINFO) {      /* Free block */
       i1 ++;
@@ -490,7 +506,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
                          (char *) ((xbt_mheap_t) state->s_heap)->heapbase));
 
           res_compare =
-              compare_heap_area(MC_NO_PROCESS_INDEX, addr_block1, addr_block2, snapshot1, snapshot2,
+              compare_heap_area(MC_PROCESS_INDEX_MISSING, addr_block1, addr_block2, snapshot1, snapshot2,
                                 NULL, NULL, 0);
 
           if (res_compare != 1) {
@@ -517,7 +533,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
           continue;
         }
 
-        malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info));
+        const malloc_info* heapinfo2b = MC_region_read(heap_region2, &heapinfo_temp2b, &heapinfos2[i2], sizeof(malloc_info));
 
         if (heapinfo2b->type != MMALLOC_TYPE_UNFRAGMENTED) {
           i2++;
@@ -530,7 +546,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
         }
 
         res_compare =
-            compare_heap_area(MC_NO_PROCESS_INDEX, addr_block1, addr_block2, snapshot1, snapshot2,
+            compare_heap_area(MC_PROCESS_INDEX_MISSING, addr_block1, addr_block2, snapshot1, snapshot2,
                               NULL, NULL, 0);
 
         if (res_compare != 1) {
@@ -583,7 +599,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
                           (j1 << heapinfo2->type));
 
             res_compare =
-                compare_heap_area(MC_NO_PROCESS_INDEX, addr_frag1, addr_frag2, snapshot1, snapshot2,
+                compare_heap_area(MC_PROCESS_INDEX_MISSING, addr_frag1, addr_frag2, snapshot1, snapshot2,
                                   NULL, NULL, 0);
 
             if (res_compare != 1)
@@ -595,7 +611,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
 
         while (i2 <= state->heaplimit && !equal) {
 
-          malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info));
+          const malloc_info* heapinfo2b = MC_region_read(heap_region2, &heapinfo_temp2b, &heapinfos2[i2], sizeof(malloc_info));
 
           if (heapinfo2b->type == MMALLOC_TYPE_FREE || heapinfo2b->type == MMALLOC_TYPE_HEAPINFO) {
             i2 ++;
@@ -630,7 +646,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
                           (j2 << heapinfo2b->type));
 
             res_compare =
-                compare_heap_area(MC_NO_PROCESS_INDEX, addr_frag1, addr_frag2, snapshot2, snapshot2,
+                compare_heap_area(MC_PROCESS_INDEX_MISSING, addr_frag1, addr_frag2, snapshot2, snapshot2,
                                   NULL, NULL, 0);
 
             if (res_compare != 1) {
@@ -667,7 +683,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
   size_t i = 1, j = 0;
 
   for(i = 1; i <= state->heaplimit; i++) {
-    malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i], heap_region1, &heapinfo_temp1, sizeof(malloc_info));
+    const malloc_info* heapinfo1 = MC_region_read(heap_region1, &heapinfo_temp1, &heapinfos1[i], sizeof(malloc_info));
     if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED) {
       if (i1 == state->heaplimit) {
         if (heapinfo1->busy_block.busy_size > 0) {
@@ -708,7 +724,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
     XBT_DEBUG("Number of blocks/fragments not found in heap1 : %d", nb_diff1);
 
   for (i=1; i <= state->heaplimit; i++) {
-    malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i], heap_region2, &heapinfo_temp2, sizeof(malloc_info));
+    const malloc_info* heapinfo2 = MC_region_read(heap_region2, &heapinfo_temp2, &heapinfos2[i], sizeof(malloc_info));
     if (heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED) {
       if (i1 == state->heaplimit) {
         if (heapinfo2->busy_block.busy_size > 0) {
@@ -763,20 +779,21 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
  * @param check_ignore
  */
 static int compare_heap_area_without_type(struct s_mc_diff *state, int process_index,
-                                          void *real_area1, void *real_area2,
+                                          const void *real_area1, const void *real_area2,
                                           mc_snapshot_t snapshot1,
                                           mc_snapshot_t snapshot2,
                                           xbt_dynar_t previous, int size,
                                           int check_ignore)
 {
+  mc_process_t process = &mc_model_checker->process;
 
   int i = 0;
-  void *addr_pointed1, *addr_pointed2;
+  const void *addr_pointed1, *addr_pointed2;
   int pointer_align, res_compare;
   ssize_t ignore1, ignore2;
 
-  mc_mem_region_t heap_region1 = snapshot1->regions[0];
-  mc_mem_region_t heap_region2 = snapshot2->regions[0];
+  mc_mem_region_t heap_region1 = MC_get_heap_region(snapshot1);
+  mc_mem_region_t heap_region2 = MC_get_heap_region(snapshot2);
 
   while (i < size) {
 
@@ -799,16 +816,16 @@ static int compare_heap_area_without_type(struct s_mc_diff *state, int process_i
       }
     }
 
-    if (mc_snapshot_region_memcmp(((char *) real_area1) + i, heap_region1, ((char *) real_area2) + i, heap_region2, 1) != 0) {
+    if (MC_snapshot_region_memcmp(((char *) real_area1) + i, heap_region1, ((char *) real_area2) + i, heap_region2, 1) != 0) {
 
       pointer_align = (i / sizeof(void *)) * sizeof(void *);
-      addr_pointed1 = mc_snapshot_read_pointer((char *) real_area1 + pointer_align, snapshot1, process_index);
-      addr_pointed2 = mc_snapshot_read_pointer((char *) real_area2 + pointer_align, snapshot2, process_index);
+      addr_pointed1 = MC_snapshot_read_pointer(snapshot1, (char *) real_area1 + pointer_align, process_index);
+      addr_pointed2 = MC_snapshot_read_pointer(snapshot2, (char *) real_area2 + pointer_align, process_index);
 
-      if (addr_pointed1 > maestro_stack_start
-          && addr_pointed1 < maestro_stack_end
-          && addr_pointed2 > maestro_stack_start
-          && addr_pointed2 < maestro_stack_end) {
+      if (addr_pointed1 > process->maestro_stack_start
+          && addr_pointed1 < process->maestro_stack_end
+          && addr_pointed2 > process->maestro_stack_start
+          && addr_pointed2 < process->maestro_stack_end) {
         i = pointer_align + sizeof(void *);
         continue;
       } else if (addr_pointed1 > state->s_heap
@@ -853,7 +870,7 @@ static int compare_heap_area_without_type(struct s_mc_diff *state, int process_i
  * @return               0 (same), 1 (different), -1 (unknown)
  */
 static int compare_heap_area_with_type(struct s_mc_diff *state, int process_index,
-                                       void *real_area1, void *real_area2,
+                                       const void *real_area1, const void *real_area2,
                                        mc_snapshot_t snapshot1,
                                        mc_snapshot_t snapshot2,
                                        xbt_dynar_t previous, dw_type_t type,
@@ -878,10 +895,10 @@ top:
   int res, elm_size, i;
   unsigned int cursor = 0;
   dw_type_t member;
-  void *addr_pointed1, *addr_pointed2;;
+  const void *addr_pointed1, *addr_pointed2;;
 
-  mc_mem_region_t heap_region1 = snapshot1->regions[0];
-  mc_mem_region_t heap_region2 = snapshot2->regions[0];
+  mc_mem_region_t heap_region1 = MC_get_heap_region(snapshot1);
+  mc_mem_region_t heap_region2 = MC_get_heap_region(snapshot2);
 
   switch (type->type) {
   case DW_TAG_unspecified_type:
@@ -892,12 +909,12 @@ top:
       if (real_area1 == real_area2)
         return -1;
       else
-        return (mc_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, area_size) != 0);
+        return (MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, area_size) != 0);
     } else {
       if (area_size != -1 && type->byte_size != area_size)
         return -1;
       else {
-        return (mc_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0);
+        return (MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0);
       }
     }
     break;
@@ -905,7 +922,7 @@ top:
     if (area_size != -1 && type->byte_size != area_size)
       return -1;
     else
-      return (mc_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0);
+      return (MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0);
     break;
   case DW_TAG_typedef:
   case DW_TAG_const_type:
@@ -962,15 +979,15 @@ top:
   case DW_TAG_rvalue_reference_type:
   case DW_TAG_pointer_type:
     if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) {
-      addr_pointed1 = mc_snapshot_read_pointer(real_area1, snapshot1, process_index);
-      addr_pointed2 = mc_snapshot_read_pointer(real_area2, snapshot2, process_index);
+      addr_pointed1 = MC_snapshot_read_pointer(snapshot1, real_area1, process_index);
+      addr_pointed2 = MC_snapshot_read_pointer(snapshot2, real_area2, process_index);
       return (addr_pointed1 != addr_pointed2);;
     } else {
       pointer_level++;
       if (pointer_level > 1) {  /* Array of pointers */
         for (i = 0; i < (area_size / sizeof(void *)); i++) {
-          addr_pointed1 = mc_snapshot_read_pointer((char*) real_area1 + i * sizeof(void *), snapshot1, process_index);
-          addr_pointed2 = mc_snapshot_read_pointer((char*) real_area2 + i * sizeof(void *), snapshot2, process_index);
+          addr_pointed1 = MC_snapshot_read_pointer(snapshot1, (char*) real_area1 + i * sizeof(void *), process_index);
+          addr_pointed2 = MC_snapshot_read_pointer(snapshot2, (char*) real_area2 + i * sizeof(void *), process_index);
           if (addr_pointed1 > state->s_heap
               && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)
               && addr_pointed2 > state->s_heap
@@ -985,8 +1002,8 @@ top:
             return res;
         }
       } else {
-        addr_pointed1 = mc_snapshot_read_pointer(real_area1, snapshot1, process_index);
-        addr_pointed2 = mc_snapshot_read_pointer(real_area2, snapshot2, process_index);
+        addr_pointed1 = MC_snapshot_read_pointer(snapshot1, real_area1, process_index);
+        addr_pointed2 = MC_snapshot_read_pointer(snapshot2, real_area2, process_index);
         if (addr_pointed1 > state->s_heap
             && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)
             && addr_pointed2 > state->s_heap
@@ -1023,9 +1040,9 @@ top:
       xbt_dynar_foreach(type->members, cursor, member) {
         // TODO, optimize this? (for the offset case)
         char *real_member1 =
-            mc_member_resolve(real_area1, type, member, snapshot1, process_index);
+            mc_member_resolve(real_area1, type, member, (mc_address_space_t) snapshot1, process_index);
         char *real_member2 =
-            mc_member_resolve(real_area2, type, member, snapshot2, process_index);
+            mc_member_resolve(real_area2, type, member, (mc_address_space_t) snapshot2, process_index);
         res =
             compare_heap_area_with_type(state, process_index, real_member1, real_member2,
                                         snapshot1, snapshot2,
@@ -1091,7 +1108,7 @@ static dw_type_t get_offset_type(void *real_base_address, dw_type_t type,
             return member->subtype;
         } else {
           char *real_member =
-              mc_member_resolve(real_base_address, type, member, snapshot, process_index);
+              mc_member_resolve(real_base_address, type, member, (mc_address_space_t) snapshot, process_index);
           if (real_member - (char *) real_base_address == offset)
             return member->subtype;
         }
@@ -1118,10 +1135,11 @@ static dw_type_t get_offset_type(void *real_base_address, dw_type_t type,
  * @param pointer_level
  * @return 0 (same), 1 (different), -1
  */
-int compare_heap_area(int process_index, void *area1, void *area2, mc_snapshot_t snapshot1,
+int compare_heap_area(int process_index, const void *area1, const void *area2, mc_snapshot_t snapshot1,
                       mc_snapshot_t snapshot2, xbt_dynar_t previous,
                       dw_type_t type, int pointer_level)
 {
+  mc_process_t process = &mc_model_checker->process;
 
   struct s_mc_diff *state = mc_diff_info;
 
@@ -1138,8 +1156,11 @@ int compare_heap_area(int process_index, void *area1, void *area2, mc_snapshot_t
 
   int match_pairs = 0;
 
-  malloc_info* heapinfos1 = mc_snapshot_read_pointer(&std_heap->heapinfo, snapshot1, process_index);
-  malloc_info* heapinfos2 = mc_snapshot_read_pointer(&std_heap->heapinfo, snapshot2, process_index);
+  // This is the address of std_heap->heapinfo in the application process:
+  void* heapinfo_address = &((xbt_mheap_t) process->heap_address)->heapinfo;
+
+  const malloc_info* heapinfos1 = MC_snapshot_read_pointer(snapshot1, heapinfo_address, process_index);
+  const malloc_info* heapinfos2 = MC_snapshot_read_pointer(snapshot2, heapinfo_address, process_index);
 
   malloc_info heapinfo_temp1, heapinfo_temp2;
 
@@ -1203,11 +1224,11 @@ int compare_heap_area(int process_index, void *area1, void *area2, mc_snapshot_t
 
   }
 
-  mc_mem_region_t heap_region1 = snapshot1->regions[0];
-  mc_mem_region_t heap_region2 = snapshot2->regions[0];
+  mc_mem_region_t heap_region1 = MC_get_heap_region(snapshot1);
+  mc_mem_region_t heap_region2 = MC_get_heap_region(snapshot2);
 
-  malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[block1], heap_region1, &heapinfo_temp1, sizeof(malloc_info));
-  malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[block2], heap_region2, &heapinfo_temp2, sizeof(malloc_info));
+  const malloc_info* heapinfo1 = MC_region_read(heap_region1, &heapinfo_temp1, &heapinfos1[block1], sizeof(malloc_info));
+  const malloc_info* heapinfo2 = MC_region_read(heap_region2, &heapinfo_temp2, &heapinfos2[block2], sizeof(malloc_info));
 
   if ((heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type==MMALLOC_TYPE_HEAPINFO)
     && (heapinfo2->type == MMALLOC_TYPE_FREE || heapinfo2->type ==MMALLOC_TYPE_HEAPINFO)) {
index 2b2c2a0..a286459 100644 (file)
@@ -1024,7 +1024,7 @@ void MC_dwarf_get_variables(mc_object_info_t info)
   }
   Dwarf *dwarf = dwarf_begin(fd, DWARF_C_READ);
   if (dwarf == NULL) {
-    xbt_die("Your program must be compiled with -g");
+    xbt_die("Your program must be compiled with -g (%s)", info->file_name);
   }
   // For each compilation unit:
   Dwarf_Off offset = 0;
@@ -1172,48 +1172,6 @@ static void MC_make_functions_index(mc_object_info_t info)
   info->functions_index = index;
 }
 
-mc_object_info_t MC_ip_find_object_info(void *ip)
-{
-  size_t i;
-  for (i = 0; i != mc_object_infos_size; ++i) {
-    if (ip >= (void *) mc_object_infos[i]->start_exec
-        && ip <= (void *) mc_object_infos[i]->end_exec) {
-      return mc_object_infos[i];
-    }
-  }
-  return NULL;
-}
-
-static dw_frame_t MC_find_function_by_ip_and_object(void *ip,
-                                                    mc_object_info_t info)
-{
-  xbt_dynar_t dynar = info->functions_index;
-  mc_function_index_item_t base =
-      (mc_function_index_item_t) xbt_dynar_get_ptr(dynar, 0);
-  int i = 0;
-  int j = xbt_dynar_length(dynar) - 1;
-  while (j >= i) {
-    int k = i + ((j - i) / 2);
-    if (ip < base[k].low_pc) {
-      j = k - 1;
-    } else if (ip >= base[k].high_pc) {
-      i = k + 1;
-    } else {
-      return base[k].function;
-    }
-  }
-  return NULL;
-}
-
-dw_frame_t MC_find_function_by_ip(void *ip)
-{
-  mc_object_info_t info = MC_ip_find_object_info(ip);
-  if (info == NULL)
-    return NULL;
-  else
-    return MC_find_function_by_ip_and_object(ip, info);
-}
-
 static void MC_post_process_variables(mc_object_info_t info)
 {
   unsigned cursor = 0;
@@ -1310,7 +1268,7 @@ static void MC_post_process_types(mc_object_info_t info)
 }
 
 /** \brief Finds informations about a given shared object/executable */
-mc_object_info_t MC_find_object_info(memory_map_t maps, char *name,
+mc_object_info_t MC_find_object_info(memory_map_t maps, const char *name,
                                      int executable)
 {
   mc_object_info_t result = MC_new_object_info();
@@ -1408,7 +1366,7 @@ void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame,
     MC_dwarf_register_non_global_variable(info, frame, variable);
 }
 
-void MC_post_process_object_info(mc_object_info_t info)
+void MC_post_process_object_info(mc_process_t process, mc_object_info_t info)
 {
   xbt_dict_cursor_t cursor = NULL;
   char *key = NULL;
@@ -1417,9 +1375,9 @@ void MC_post_process_object_info(mc_object_info_t info)
 
     // Resolve full_type:
     if (type->name && type->byte_size == 0) {
-      for (size_t i = 0; i != mc_object_infos_size; ++i) {
+      for (size_t i = 0; i != process->object_infos_size; ++i) {
         dw_type_t same_type =
-            xbt_dict_get_or_null(mc_object_infos[i]->full_types_by_name,
+            xbt_dict_get_or_null(process->object_infos[i]->full_types_by_name,
                                  type->name);
         if (same_type && same_type->name && same_type->byte_size) {
           type->full_type = same_type;
index 7653210..92e4e47 100644 (file)
@@ -11,7 +11,6 @@
 #include <elfutils/libdw.h>
 
 #include "mc_object_info.h"
-#include "mc_snapshot.h"
 #include "mc_private.h"
 
 static int mc_dwarf_push_value(mc_expression_state_t state, Dwarf_Off value)
@@ -23,6 +22,12 @@ static int mc_dwarf_push_value(mc_expression_state_t state, Dwarf_Off value)
   return 0;
 }
 
+/** Convert a DWARF register into a libunwind register
+ *
+ *  DWARF and libunwind does not use the same convention for numbering the
+ *  registers on some architectures. The function makes the necessary
+ *  convertion.
+ */
 static int mc_dwarf_register_to_libunwind(int dwarf_register)
 {
 #if defined(UNW_TARGET_X86_64)
@@ -84,7 +89,7 @@ static int mc_dwarf_register_to_libunwind(int dwarf_register)
     xbt_die("Bad/unknown register number.");
   }
 #else
-#error This architecture is not supported yet.
+#error This architecture is not supported yet for DWARF expression evaluation.
 #endif
 }
 
@@ -168,15 +173,16 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops,
       {
         if (!state->frame_base)
           return MC_EXPRESSION_E_MISSING_FRAME_BASE;
-        error =
-            mc_dwarf_push_value(state,
-                                ((uintptr_t) state->frame_base) + op->number);
+        uintptr_t fb = ((uintptr_t) state->frame_base) + op->number;
+        error = mc_dwarf_push_value(state, fb);
         break;
       }
 
 
-      // Constants:
+      // ***** Constants:
 
+      // Short constant literals:
+      // DW_OP_lit15 pushed the 15 on the stack.
     case DW_OP_lit0:
     case DW_OP_lit1:
     case DW_OP_lit2:
@@ -212,17 +218,20 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops,
       error = mc_dwarf_push_value(state, atom - DW_OP_lit0);
       break;
 
+      // Address from the base address of this ELF object.
+      // Push the address on the stack (base_address + argument).
     case DW_OP_addr:
       if (!state->object_info)
         return MC_EXPRESSION_E_NO_BASE_ADDRESS;
       if (state->stack_size == MC_EXPRESSION_STACK_SIZE)
         return MC_EXPRESSION_E_STACK_OVERFLOW;
-      error = mc_dwarf_push_value(state,
-                                  (Dwarf_Off) (uintptr_t)
-                                  MC_object_base_address(state->object_info) +
-                                  op->number);
+      Dwarf_Off addr = (Dwarf_Off) (uintptr_t)
+        MC_object_base_address(state->object_info) + op->number;
+      error = mc_dwarf_push_value(state, addr);
       break;
 
+      // General constants:
+      // Push the constant argument on the stack.
     case DW_OP_const1u:
     case DW_OP_const2u:
     case DW_OP_const4u:
@@ -238,9 +247,9 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops,
       error = mc_dwarf_push_value(state, op->number);
       break;
 
-      // Stack manipulation:
+      // ***** Stack manipulation:
 
-      // Push the value at the top of the stack:
+      // Push another copy/duplicate the value at the top of the stack:
     case DW_OP_dup:
       if (state->stack_size == 0)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
@@ -248,6 +257,7 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops,
         error = mc_dwarf_push_value(state, state->stack[state->stack_size - 1]);
       break;
 
+      // Pop/drop the top of the stack:
     case DW_OP_drop:
       if (state->stack_size == 0)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
@@ -255,6 +265,7 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops,
         state->stack_size--;
       break;
 
+      // Swap the two top-most value of the stack:
     case DW_OP_swap:
       if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
@@ -266,13 +277,17 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops,
       }
       break;
 
+      // Duplicate the value under the top of the stack:
     case DW_OP_over:
       if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       error = mc_dwarf_push_value(state, state->stack[state->stack_size - 2]);
       break;
 
-      // Operations:
+      // ***** Operations:
+      // Those usually take the top of the stack and the next value as argument
+      // and replace the top of the stack with the computed value
+      // (stack.top() += stack.before_top()).
 
     case DW_OP_plus:
       if (state->stack_size < 2)
@@ -373,7 +388,8 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops,
     case DW_OP_nop:
       break;
 
-      // Dereference:
+      // ***** Deference (memory fetch)
+
     case DW_OP_deref_size:
       return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
 
@@ -383,9 +399,19 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops,
       {
         // Computed address:
         uintptr_t address = (uintptr_t) state->stack[state->stack_size - 1];
-        uintptr_t temp;
-        uintptr_t* res = (uintptr_t*) mc_snapshot_read((void*) address, state->snapshot, state->process_index, &temp, sizeof(uintptr_t));
-        state->stack[state->stack_size - 1] = *res;
+        uintptr_t value;
+        if (state->address_space) {
+          uintptr_t temp;
+          const uintptr_t* res = (uintptr_t*) MC_address_space_read(
+            state->address_space, MC_ADDRESS_SPACE_READ_FLAGS_LAZY,
+            &temp, (const void*) address, sizeof(uintptr_t), state->process_index);
+          value = *res;
+        }
+        else {
+          // TODO, use a mc_process representing the current process instead of this
+          value = *(const uintptr_t*) address;
+        }
+        state->stack[state->stack_size - 1] = value;
       }
       break;
 
@@ -410,13 +436,13 @@ void mc_dwarf_resolve_location(mc_location_t location,
                                mc_object_info_t object_info,
                                unw_cursor_t * c,
                                void *frame_pointer_address,
-                               mc_snapshot_t snapshot, int process_index)
+                               mc_address_space_t address_space, int process_index)
 {
   s_mc_expression_state_t state;
   memset(&state, 0, sizeof(s_mc_expression_state_t));
   state.frame_base = frame_pointer_address;
   state.cursor = c;
-  state.snapshot = snapshot;
+  state.address_space = address_space;
   state.object_info = object_info;
   state.process_index = process_index;
 
@@ -459,7 +485,7 @@ void mc_dwarf_resolve_locations(mc_location_t location,
                                      mc_object_info_t object_info,
                                      unw_cursor_t * c,
                                      void *frame_pointer_address,
-                                     mc_snapshot_t snapshot, int process_index)
+                                     mc_address_space_t address_space, int process_index)
 {
 
   unw_word_t ip = 0;
@@ -472,7 +498,7 @@ void mc_dwarf_resolve_locations(mc_location_t location,
   if (expression) {
     mc_dwarf_resolve_location(location,
                               expression, object_info, c,
-                              frame_pointer_address, snapshot, process_index);
+                              frame_pointer_address, address_space, process_index);
   } else {
     xbt_die("Could not resolve location");
   }
index 267f82c..bd78e99 100644 (file)
@@ -15,7 +15,11 @@ typedef struct s_dw_type s_dw_type_t, *dw_type_t;
 typedef struct s_memory_map s_memory_map_t, *memory_map_t;
 typedef struct s_dw_variable s_dw_variable_t, *dw_variable_t;
 typedef struct s_dw_frame s_dw_frame_t, *dw_frame_t;
+
 typedef struct s_mc_pages_store s_mc_pages_store_t, *mc_pages_store_t;
+typedef struct s_mc_snapshot s_mc_snapshot_t, *mc_snapshot_t;
+
+typedef struct s_mc_process s_mc_process_t, * mc_process_t;
 typedef struct s_mc_model_checker s_mc_model_checker_t, *mc_model_checker_t;
 extern mc_model_checker_t mc_model_checker;
 
index 63ecd05..85dacbc 100644 (file)
@@ -4,15 +4,14 @@
 /* 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 <string.h>
+
 #include "mc_base.h"
 
 #ifndef _XBT_WIN32
 #include <unistd.h>
-#include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/time.h>
-#include <sys/mman.h>
-#include <libgen.h>
 #endif
 
 #include "simgrid/sg_config.h"
@@ -23,8 +22,8 @@
 #include "xbt/dict.h"
 
 #ifdef HAVE_MC
-#define UNW_LOCAL_ONLY
 #include <libunwind.h>
+#include <xbt/mmalloc.h>
 
 #include "../xbt/mmalloc/mmprivate.h"
 #include "mc_object_info.h"
 #include "mc_snapshot.h"
 #include "mc_liveness.h"
 #include "mc_private.h"
+#include "mc_unw.h"
 #endif
 #include "mc_record.h"
+#include "mc_protocol.h"
+#include "mc_client.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_global, mc,
                                 "Logging specific to MC (global)");
 
+e_mc_mode_t mc_mode;
+
 double *mc_time = NULL;
 
 #ifdef HAVE_MC
@@ -59,14 +63,6 @@ xbt_fifo_t mc_stack = NULL;
 /* Liveness */
 xbt_automaton_t _mc_property_automaton = NULL;
 
-/* Variables */
-mc_object_info_t mc_libsimgrid_info = NULL;
-mc_object_info_t mc_binary_info = NULL;
-
-mc_object_info_t mc_object_infos[2] = { NULL, NULL };
-
-size_t mc_object_infos_size = 2;
-
 /* Dot output */
 FILE *dot_output = NULL;
 const char *colors[13];
@@ -104,57 +100,29 @@ static void MC_init_dot_output()
 
 }
 
-static void MC_init_debug_info(void)
-{
-  XBT_INFO("Get debug information ...");
-
-  memory_map_t maps = MC_get_memory_map();
-
-  /* Get local variables for state equality detection */
-  mc_binary_info = MC_find_object_info(maps, xbt_binary_name, 1);
-  mc_object_infos[0] = mc_binary_info;
-
-  mc_libsimgrid_info = MC_find_object_info(maps, libsimgrid_path, 0);
-  mc_object_infos[1] = mc_libsimgrid_info;
-
-  // Use information of the other objects:
-  MC_post_process_object_info(mc_binary_info);
-  MC_post_process_object_info(mc_libsimgrid_info);
-
-  MC_free_memory_map(maps);
-  XBT_INFO("Get debug information done !");
-}
-
-
-mc_model_checker_t mc_model_checker = NULL;
-
-mc_model_checker_t MC_model_checker_new()
+void MC_init()
 {
-  mc_model_checker_t mc = xbt_new0(s_mc_model_checker_t, 1);
-  mc->pages = mc_pages_store_new();
-  mc->fd_clear_refs = -1;
-  mc->fd_pagemap = -1;
-  return mc;
+  MC_init_pid(getpid(), -1);
 }
 
-void MC_model_checker_delete(mc_model_checker_t mc) {
-  mc_pages_store_delete(mc->pages);
-  if(mc->record)
-    xbt_dynar_free(&mc->record);
-}
-
-void MC_init()
+void MC_init_pid(pid_t pid, int socket)
 {
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+  if (mc_mode == MC_MODE_NONE) {
+    if (getenv(MC_ENV_SOCKET_FD)) {
+      mc_mode = MC_MODE_CLIENT;
+    } else {
+      mc_mode = MC_MODE_STANDALONE;
+    }
+  }
 
   mc_time = xbt_new0(double, simix_process_maxpid);
 
   /* Initialize the data structures that must be persistent across every
      iteration of the model-checker (in RAW memory) */
 
-  MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
-  mc_model_checker = MC_model_checker_new();
+  mc_model_checker = MC_model_checker_new(pid, socket);
 
   mc_comp_times = xbt_new0(s_mc_comparison_times_t, 1);
 
@@ -162,9 +130,6 @@ void MC_init()
   mc_stats = xbt_new0(s_mc_stats_t, 1);
   mc_stats->state_size = 1;
 
-  MC_init_memory_map_info();
-  MC_init_debug_info();         /* FIXME : get debug information only if liveness verification or visited state reduction */
-
   if ((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0] != '\0'))
     MC_init_dot_output();
 
@@ -212,16 +177,22 @@ void MC_init()
     /* SIMIX */
     MC_ignore_global_variable("smx_total_comms");
 
-    MC_ignore_heap(mc_time, simix_process_maxpid * sizeof(double));
+    if (mc_mode == MC_MODE_STANDALONE || mc_mode == MC_MODE_CLIENT) {
+      MC_ignore_heap(mc_time, simix_process_maxpid * sizeof(double));
 
-    smx_process_t process;
-    xbt_swag_foreach(process, simix_global->process_list) {
-      MC_ignore_heap(&(process->process_hookup), sizeof(process->process_hookup));
+      smx_process_t process;
+      xbt_swag_foreach(process, simix_global->process_list) {
+        MC_ignore_heap(&(process->process_hookup), sizeof(process->process_hookup));
+      }
     }
   }
 
-  if (raw_mem_set)
-    MC_SET_MC_HEAP;
+  mmalloc_set_current_heap(heap);
+
+  if (mc_mode == MC_MODE_CLIENT) {
+    // This will move somehwere else:
+    MC_client_handle_messages();
+  }
 
 }
 
@@ -230,13 +201,9 @@ void MC_init()
 
 static void MC_modelcheck_comm_determinism_init(void)
 {
-
-  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
   MC_init();
 
-  if (!mc_mem_set)
-    MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   /* Create exploration stack */
   mc_stack = xbt_fifo_new();
@@ -255,21 +222,16 @@ static void MC_modelcheck_comm_determinism_init(void)
 
   MC_modelcheck_comm_determinism();
 
-  if(mc_mem_set)
-    MC_SET_MC_HEAP;
-
+  mmalloc_set_current_heap(heap);
 }
 
 static void MC_modelcheck_safety_init(void)
 {
-  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
   _sg_mc_safety = 1;
 
   MC_init();
 
-  if (!mc_mem_set)
-    MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   /* Create exploration stack */
   mc_stack = xbt_fifo_new();
@@ -286,8 +248,7 @@ static void MC_modelcheck_safety_init(void)
 
   MC_modelcheck_safety();
 
-  if (mc_mem_set)
-    MC_SET_MC_HEAP;
+  mmalloc_set_current_heap(heap);
 
   xbt_abort();
   //MC_exit();
@@ -295,15 +256,11 @@ static void MC_modelcheck_safety_init(void)
 
 static void MC_modelcheck_liveness_init()
 {
-
-  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
   _sg_mc_liveness = 1;
 
   MC_init();
 
-  if (!mc_mem_set)
-    MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   /* Create exploration stack */
   mc_stack = xbt_fifo_new();
@@ -319,8 +276,7 @@ static void MC_modelcheck_liveness_init()
   MC_print_statistics(mc_stats);
   xbt_free(mc_time);
 
-  if (mc_mem_set)
-    MC_SET_MC_HEAP;
+  mmalloc_set_current_heap(heap);
 
 }
 
@@ -443,7 +399,7 @@ static void MC_restore_communications_pattern(mc_state_t state) {
  */
 void MC_replay(xbt_fifo_t stack)
 {
-  int raw_mem = (mmalloc_get_current_heap() == mc_heap);
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   int value, count = 1, j;
   char *req_str;
@@ -530,13 +486,7 @@ void MC_replay(xbt_fifo_t stack)
   }
 
   XBT_DEBUG("**** End Replay ****");
-
-  if (raw_mem)
-    MC_SET_MC_HEAP;
-  else
-    MC_SET_STD_HEAP;
-
-
+  mmalloc_set_current_heap(heap);
 }
 
 void MC_replay_liveness(xbt_fifo_t stack)
@@ -627,8 +577,7 @@ void MC_replay_liveness(xbt_fifo_t stack)
  */
 void MC_dump_stack_safety(xbt_fifo_t stack)
 {
-
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   MC_show_stack_safety(stack);
   
@@ -637,22 +586,13 @@ void MC_dump_stack_safety(xbt_fifo_t stack)
   MC_SET_MC_HEAP;
   while ((state = (mc_state_t) xbt_fifo_pop(stack)) != NULL)
     MC_state_delete(state, !state->in_visited_states ? 1 : 0);
-  MC_SET_STD_HEAP;
-
-  if (raw_mem_set)
-    MC_SET_MC_HEAP;
-  else
-    MC_SET_STD_HEAP;
-
+  mmalloc_set_current_heap(heap);
 }
 
 
 void MC_show_stack_safety(xbt_fifo_t stack)
 {
-
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   int value;
   mc_state_t state;
@@ -671,8 +611,7 @@ void MC_show_stack_safety(xbt_fifo_t stack)
     }
   }
 
-  if (!raw_mem_set)
-    MC_SET_STD_HEAP;
+  mmalloc_set_current_heap(heap);
 }
 
 void MC_show_deadlock(smx_simcall_t req)
@@ -714,26 +653,16 @@ void MC_show_stack_liveness(xbt_fifo_t stack)
 
 void MC_dump_stack_liveness(xbt_fifo_t stack)
 {
-
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
   mc_pair_t pair;
-
-  MC_SET_MC_HEAP;
   while ((pair = (mc_pair_t) xbt_fifo_pop(stack)) != NULL)
     MC_pair_delete(pair);
-  MC_SET_STD_HEAP;
-
-  if (raw_mem_set)
-    MC_SET_MC_HEAP;
-
+  mmalloc_set_current_heap(heap);
 }
 
 
 void MC_print_statistics(mc_stats_t stats)
 {
-  xbt_mheap_t previous_heap = mmalloc_get_current_heap();
-
   if (stats->expanded_pairs == 0) {
     XBT_INFO("Expanded states = %lu", stats->expanded_states);
     XBT_INFO("Visited states = %lu", stats->visited_states);
@@ -742,7 +671,7 @@ void MC_print_statistics(mc_stats_t stats)
     XBT_INFO("Visited pairs = %lu", stats->visited_pairs);
   }
   XBT_INFO("Executed transitions = %lu", stats->executed_transitions);
-  MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
   if ((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0] != '\0')) {
     fprintf(dot_output, "}\n");
     fclose(dot_output);
@@ -753,70 +682,73 @@ void MC_print_statistics(mc_stats_t stats)
     if (_sg_mc_send_determinism)
       XBT_INFO("Send-deterministic : %s", !initial_global_state->send_deterministic ? "No" : "Yes");
   }
-  mmalloc_set_current_heap(previous_heap);
-}
-
-void MC_assert(int prop)
-{
-  if (MC_is_active() && !prop) {
-    XBT_INFO("**************************");
-    XBT_INFO("*** PROPERTY NOT VALID ***");
-    XBT_INFO("**************************");
-    XBT_INFO("Counter-example execution trace:");
-    MC_record_dump_path(mc_stack);
-    MC_dump_stack_safety(mc_stack);
-    MC_print_statistics(mc_stats);
-    xbt_abort();
-  }
-}
-
-void MC_cut(void)
-{
-  user_max_depth_reached = 1;
+  mmalloc_set_current_heap(heap);
 }
 
 void MC_automaton_load(const char *file)
 {
-
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   if (_mc_property_automaton == NULL)
     _mc_property_automaton = xbt_automaton_new();
 
   xbt_automaton_load(_mc_property_automaton, file);
-
-  MC_SET_STD_HEAP;
-
-  if (raw_mem_set)
-    MC_SET_MC_HEAP;
-
+  mmalloc_set_current_heap(heap);
 }
 
-void MC_automaton_new_propositional_symbol(const char *id, void *fct)
+static void register_symbol(xbt_automaton_propositional_symbol_t symbol)
 {
+  if (mc_mode != MC_MODE_CLIENT)
+    return;
+  s_mc_register_symbol_message_t message;
+  message.type = MC_MESSAGE_REGISTER_SYMBOL;
+  const char* name = xbt_automaton_propositional_symbol_get_name(symbol);
+  if (strlen(name) + 1 > sizeof(message.name))
+    xbt_die("Symbol is too long");
+  strncpy(message.name, name, sizeof(message.name));
+  message.callback = xbt_automaton_propositional_symbol_get_callback(symbol);
+  message.data = xbt_automaton_propositional_symbol_get_data(symbol);
+  MC_client_send_message(&message, sizeof(message));
+}
 
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
+void MC_automaton_new_propositional_symbol(const char *id, int(*fct)(void))
+{
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   if (_mc_property_automaton == NULL)
     _mc_property_automaton = xbt_automaton_new();
 
-  xbt_automaton_propositional_symbol_new(_mc_property_automaton, id, fct);
-
-  MC_SET_STD_HEAP;
+  xbt_automaton_propositional_symbol_t symbol = xbt_automaton_propositional_symbol_new(_mc_property_automaton, id, fct);
+  register_symbol(symbol);
+  mmalloc_set_current_heap(heap);
+}
 
-  if (raw_mem_set)
-    MC_SET_MC_HEAP;
+void MC_automaton_new_propositional_symbol_pointer(const char *id, int* value)
+{
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
+  if (_mc_property_automaton == NULL)
+    _mc_property_automaton = xbt_automaton_new();
+  xbt_automaton_propositional_symbol_t symbol = xbt_automaton_propositional_symbol_new_pointer(_mc_property_automaton, id, value);
+  register_symbol(symbol);
+  mmalloc_set_current_heap(heap);
+}
 
+void MC_automaton_new_propositional_symbol_callback(const char* id,
+  xbt_automaton_propositional_symbol_callback_type callback,
+  void* data, xbt_automaton_propositional_symbol_free_function_type free_function)
+{
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
+  if (_mc_property_automaton == NULL)
+    _mc_property_automaton = xbt_automaton_new();
+  xbt_automaton_propositional_symbol_t symbol = xbt_automaton_propositional_symbol_new_callback(
+    _mc_property_automaton, id, callback, data, free_function);
+  register_symbol(symbol);
+  mmalloc_set_current_heap(heap);
 }
 
 void MC_dump_stacks(FILE* file)
 {
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-  MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   int nstack = 0;
   stack_region_t current_stack;
@@ -838,9 +770,7 @@ void MC_dump_stacks(FILE* file)
 
     ++nstack;
   }
-
-  if (raw_mem_set)
-    MC_SET_MC_HEAP;
+  mmalloc_set_current_heap(heap);
 }
 #endif
 
index cc78c3d..b83bc83 100644 (file)
@@ -81,6 +81,7 @@ 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)
 {
+  mc_process_t process = &mc_model_checker->process;
 top:
 
   switch (type->type) {
@@ -171,12 +172,12 @@ top:
       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));
+      bool valid_pointer = (pointed >= (void *) binary_info->start_rw
+                            && pointed <= (void *) binary_info->end_rw)
+          || (pointed >= (void *) libsimgrid_info->start_rw
+              && pointed <= (void *) libsimgrid_info->end_rw)
+          || (pointed >= process->heap_address
+              && pointed < (void *) ((const char *) process->heap_address + STD_HEAP_SIZE));
       if (!valid_pointer) {
         XBT_DEBUG("Hashed pointed data %p is in an ignored range", pointed);
         return;
@@ -220,12 +221,12 @@ static void mc_hash_object_globals(mc_hash_t * hash, mc_hashing_state * state,
     }
 
     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);
+    bool valid_pointer = (address >= binary_info->start_rw
+                          && address <= binary_info->end_rw)
+        || (address >= libsimgrid_info->start_rw
+            && address <= libsimgrid_info->end_rw)
+        || (address >= (const char *) process->heap_address
+            && address < (const char *) process->heap_address + STD_HEAP_SIZE);
     if (!valid_pointer)
       continue;
 
@@ -285,12 +286,12 @@ static void mc_hash_stack(mc_hash_t * hash, mc_snapshot_stack_t stack,
     MC_HASH(*hash, stack_frame->ip);
 
     mc_object_info_t info;
-    if (stack_frame->ip >= (unw_word_t) mc_libsimgrid_info->start_exec
-        && stack_frame->ip < (unw_word_t) mc_libsimgrid_info->end_exec)
-      info = mc_libsimgrid_info;
-    else if (stack_frame->ip >= (unw_word_t) mc_binary_info->start_exec
-             && stack_frame->ip < (unw_word_t) mc_binary_info->end_exec)
-      info = mc_binary_info;
+    if (stack_frame->ip >= (unw_word_t) libsimgrid_info->start_exec
+        && stack_frame->ip < (unw_word_t) libsimgrid_info->end_exec)
+      info = libsimgrid_info;
+    else if (stack_frame->ip >= (unw_word_t) binary_info->start_exec
+             && stack_frame->ip < (unw_word_t) binary_info->end_exec)
+      info = binary_info;
     else
       continue;
 
@@ -328,8 +329,8 @@ uint64_t mc_hash_processes_state(int num_state, xbt_dynar_t stacks)
   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_object_globals(&hash, &state, binary_info);
+  // mc_hash_object_globals(&hash, &state, libsimgrid_info);
   // mc_hash_stacks(&hash, &state, stacks);
 
   mc_hash_state_destroy(&state);
index 13cab5e..f213822 100644 (file)
@@ -9,13 +9,19 @@
 #include "mc_private.h"
 #include "smpi/private.h"
 #include "mc/mc_snapshot.h"
+#include "mc_ignore.h"
+#include "mc_protocol.h"
+#include "mc_client.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_ignore, mc,
                                 "Logging specific to MC ignore mechanism");
 
 
 /**************************** Global variables ******************************/
-xbt_dynar_t mc_checkpoint_ignore;
+// Those structures live with the MCer and should be moved in the model_checker
+// structure but they are currently used before the MC initialisation
+// (in standalone mode).
+
 extern xbt_dynar_t mc_heap_comparison_ignore;
 extern xbt_dynar_t stacks_areas;
 
@@ -59,41 +65,22 @@ static void checkpoint_ignore_region_free_voidp(void *r)
   checkpoint_ignore_region_free((mc_checkpoint_ignore_region_t) * (void **) r);
 }
 
-/***********************************************************************/
-
-void MC_ignore_heap(void *address, size_t size)
+xbt_dynar_t MC_checkpoint_ignore_new(void)
 {
+  return xbt_dynar_new(sizeof(mc_checkpoint_ignore_region_t),
+                        checkpoint_ignore_region_free_voidp);
+}
 
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
-
-  mc_heap_ignore_region_t region = NULL;
-  region = xbt_new0(s_mc_heap_ignore_region_t, 1);
-  region->address = address;
-  region->size = size;
-
-  region->block =
-      ((char *) address -
-       (char *) std_heap->heapbase) / BLOCKSIZE + 1;
-
-  if (std_heap->heapinfo[region->block].type == 0) {
-    region->fragment = -1;
-    std_heap->heapinfo[region->block].busy_block.ignore++;
-  } else {
-    region->fragment =
-        ((uintptr_t) (ADDR2UINT(address) % (BLOCKSIZE))) >> std_heap->
-        heapinfo[region->block].type;
-    std_heap->heapinfo[region->block].busy_frag.ignore[region->fragment]++;
-  }
+/***********************************************************************/
 
+// Mcer
+void MC_heap_region_ignore_insert(mc_heap_ignore_region_t region)
+{
   if (mc_heap_comparison_ignore == NULL) {
     mc_heap_comparison_ignore =
         xbt_dynar_new(sizeof(mc_heap_ignore_region_t),
                       heap_ignore_region_free_voidp);
     xbt_dynar_push(mc_heap_comparison_ignore, &region);
-    if (!raw_mem_set)
-      MC_SET_STD_HEAP;
     return;
   }
 
@@ -102,39 +89,84 @@ void MC_ignore_heap(void *address, size_t size)
   int start = 0;
   int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
 
+  // Find the position where we want to insert the mc_heap_ignore_region_t:
   while (start <= end) {
     cursor = (start + end) / 2;
     current_region =
         (mc_heap_ignore_region_t) xbt_dynar_get_as(mc_heap_comparison_ignore,
                                                    cursor,
                                                    mc_heap_ignore_region_t);
-    if (current_region->address == address) {
+    if (current_region->address == region->address) {
       heap_ignore_region_free(region);
-      if (!raw_mem_set)
-        MC_SET_STD_HEAP;
       return;
-    } else if (current_region->address < address) {
+    } else if (current_region->address < region->address) {
       start = cursor + 1;
     } else {
       end = cursor - 1;
     }
   }
 
-  if (current_region->address < address)
+  // Insert it mc_heap_ignore_region_t:
+  if (current_region->address < region->address)
     xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor + 1, &region);
   else
     xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, &region);
+}
 
-  if (!raw_mem_set)
-    MC_SET_STD_HEAP;
+// MCed:
+static void MC_heap_region_ignore_send(mc_heap_ignore_region_t region)
+{
+  s_mc_ignore_heap_message_t message;
+  message.type = MC_MESSAGE_IGNORE_HEAP;
+  message.region = *region;
+  if (MC_protocol_send(mc_client->fd, &message, sizeof(message)))
+    xbt_die("Could not send ignored region to MCer");
+  XBT_DEBUG("Sent ignored region to the model-checker");
 }
 
-void MC_remove_ignore_heap(void *address, size_t size)
+// MCed:
+void MC_ignore_heap(void *address, size_t size)
 {
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
+
+  mc_heap_ignore_region_t region = xbt_new0(s_mc_heap_ignore_region_t, 1);
+  region->address = address;
+  region->size = size;
+
+  region->block =
+      ((char *) address -
+       (char *) std_heap->heapbase) / BLOCKSIZE + 1;
+
+  if (std_heap->heapinfo[region->block].type == 0) {
+    region->fragment = -1;
+    std_heap->heapinfo[region->block].busy_block.ignore++;
+  } else {
+    region->fragment =
+        ((uintptr_t) (ADDR2UINT(address) % (BLOCKSIZE))) >> std_heap->
+        heapinfo[region->block].type;
+    std_heap->heapinfo[region->block].busy_frag.ignore[region->fragment]++;
+  }
+
+  MC_heap_region_ignore_insert(region);
 
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+#if 1
+  if (mc_mode == MC_MODE_CLIENT)
+    MC_heap_region_ignore_send(region);
+#endif
+  mmalloc_set_current_heap(heap);
+}
+
+void MC_remove_ignore_heap(void *address, size_t size)
+{
+  if (mc_mode == MC_MODE_CLIENT) {
+    s_mc_ignore_memory_message_t message;
+    message.type = MC_MESSAGE_UNIGNORE_HEAP;
+    message.addr = address;
+    message.size = size;
+    MC_client_send_message(&message, sizeof(message));
+  }
 
-  MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   unsigned int cursor = 0;
   int start = 0;
@@ -167,44 +199,40 @@ void MC_remove_ignore_heap(void *address, size_t size)
     xbt_dynar_remove_at(mc_heap_comparison_ignore, cursor, NULL);
     MC_remove_ignore_heap(address, size);
   }
-
-  if (!raw_mem_set)
-    MC_SET_STD_HEAP;
-
+  mmalloc_set_current_heap(heap);
 }
 
+// MCer
 void MC_ignore_global_variable(const char *name)
 {
+  mc_process_t process = &mc_model_checker->process;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
+  xbt_assert(process->object_infos, "MC subsystem not initialized");
 
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
-
-  xbt_assert(mc_libsimgrid_info, "MC subsystem not initialized");
-
-  unsigned int cursor = 0;
-  dw_variable_t current_var;
-  int start = 0;
-  int end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
+  size_t n = process->object_infos_size;
+  for (size_t i=0; i!=n; ++i) {
+    mc_object_info_t info = process->object_infos[i];
 
-  while (start <= end) {
-    cursor = (start + end) / 2;
-    current_var =
-        (dw_variable_t) xbt_dynar_get_as(mc_libsimgrid_info->global_variables,
-                                         cursor, dw_variable_t);
-    if (strcmp(current_var->name, name) == 0) {
-      xbt_dynar_remove_at(mc_libsimgrid_info->global_variables, cursor, NULL);
-      start = 0;
-      end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
-    } else if (strcmp(current_var->name, name) < 0) {
-      start = cursor + 1;
-    } else {
-      end = cursor - 1;
+    // Binary search:
+    int start = 0;
+    int end = xbt_dynar_length(info->global_variables) - 1;
+    while (start <= end) {
+      unsigned int cursor = (start + end) / 2;
+      dw_variable_t current_var =
+          (dw_variable_t) xbt_dynar_get_as(info->global_variables,
+                                           cursor, dw_variable_t);
+      if (strcmp(current_var->name, name) == 0) {
+        xbt_dynar_remove_at(info->global_variables, cursor, NULL);
+        start = 0;
+        end = xbt_dynar_length(info->global_variables) - 1;
+      } else if (strcmp(current_var->name, name) < 0) {
+        start = cursor + 1;
+      } else {
+        end = cursor - 1;
+      }
     }
   }
-
-  if (!raw_mem_set)
-    MC_SET_STD_HEAP;
+  mmalloc_set_current_heap(heap);
 }
 
 /** \brief Ignore a local variable in a scope
@@ -225,7 +253,7 @@ static void mc_ignore_local_variable_in_scope(const char *var_name,
 {
   // Processing of direct variables:
 
-  // If the current subprogram matche the given name:
+  // If the current subprogram matches the given name:
   if (!subprogram_name ||
       (subprogram->name && strcmp(subprogram_name, subprogram->name) == 0)) {
 
@@ -283,29 +311,34 @@ static void MC_ignore_local_variable_in_object(const char *var_name,
   }
 }
 
+// MCer
 void MC_ignore_local_variable(const char *var_name, const char *frame_name)
 {
-
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
+  mc_process_t process = &mc_model_checker->process;
   if (strcmp(frame_name, "*") == 0)
     frame_name = NULL;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
-  MC_SET_MC_HEAP;
-
-  MC_ignore_local_variable_in_object(var_name, frame_name, mc_libsimgrid_info);
-  if (frame_name != NULL)
-    MC_ignore_local_variable_in_object(var_name, frame_name, mc_binary_info);
+  size_t n = process->object_infos_size;
+  size_t i;
+  for (i=0; i!=n; ++i) {
+    MC_ignore_local_variable_in_object(var_name, frame_name, process->object_infos[i]);
+  }
 
-  if (!raw_mem_set)
-    MC_SET_STD_HEAP;
+  mmalloc_set_current_heap(heap);
+}
 
+void MC_stack_area_add(stack_region_t stack_area)
+{
+  if (stacks_areas == NULL)
+    stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
+  xbt_dynar_push(stacks_areas, &stack_area);
 }
 
 /** @brief Register a stack in the model checker
  *
  *  The stacks are allocated in the heap. The MC handle them especially
- *  when we analyse/compare the content of theap so it must be told where
+ *  when we analyse/compare the content of the heap so it must be told where
  *  they are with this function.
  *
  *  @param stack
@@ -315,18 +348,10 @@ void MC_ignore_local_variable(const char *var_name, const char *frame_name)
  */
 void MC_new_stack_area(void *stack, smx_process_t process, void *context, size_t size)
 {
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
-
-  if (stacks_areas == NULL)
-    stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
-
-  stack_region_t region = NULL;
-  region = xbt_new0(s_stack_region_t, 1);
+  stack_region_t region = xbt_new0(s_stack_region_t, 1);
   region->address = stack;
-  region->process_name = process && process->name ? strdup(process->name) : NULL;
   region->context = context;
   region->size = size;
   region->block =
@@ -339,49 +364,44 @@ void MC_new_stack_area(void *stack, smx_process_t process, void *context, size_t
 #endif
   region->process_index = -1;
 
-  xbt_dynar_push(stacks_areas, &region);
+  if (mc_mode == MC_MODE_CLIENT) {
+    s_mc_stack_region_message_t message;
+    message.type = MC_MESSAGE_STACK_REGION;
+    message.stack_region = *region;
+    MC_client_send_message(&message, sizeof(message));
+  }
+
+  MC_stack_area_add(region);
 
-  if (!raw_mem_set)
-    MC_SET_STD_HEAP;
+  mmalloc_set_current_heap(heap);
 }
 
-void MC_ignore(void *addr, size_t size)
+void MC_process_ignore_memory(mc_process_t process, void *addr, size_t size)
 {
-
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
-
-  if (mc_checkpoint_ignore == NULL)
-    mc_checkpoint_ignore =
-        xbt_dynar_new(sizeof(mc_checkpoint_ignore_region_t),
-                      checkpoint_ignore_region_free_voidp);
-
+  xbt_dynar_t checkpoint_ignore = process->checkpoint_ignore;
   mc_checkpoint_ignore_region_t region =
       xbt_new0(s_mc_checkpoint_ignore_region_t, 1);
   region->addr = addr;
   region->size = size;
 
-  if (xbt_dynar_is_empty(mc_checkpoint_ignore)) {
-    xbt_dynar_push(mc_checkpoint_ignore, &region);
+  if (xbt_dynar_is_empty(checkpoint_ignore)) {
+    xbt_dynar_push(checkpoint_ignore, &region);
   } else {
 
     unsigned int cursor = 0;
     int start = 0;
-    int end = xbt_dynar_length(mc_checkpoint_ignore) - 1;
+    int end = xbt_dynar_length(checkpoint_ignore) - 1;
     mc_checkpoint_ignore_region_t current_region = NULL;
 
     while (start <= end) {
       cursor = (start + end) / 2;
       current_region =
-          (mc_checkpoint_ignore_region_t) xbt_dynar_get_as(mc_checkpoint_ignore,
+          (mc_checkpoint_ignore_region_t) xbt_dynar_get_as(checkpoint_ignore,
                                                            cursor,
                                                            mc_checkpoint_ignore_region_t);
       if (current_region->addr == addr) {
         if (current_region->size == size) {
           checkpoint_ignore_region_free(region);
-          if (!raw_mem_set)
-            MC_SET_STD_HEAP;
           return;
         } else if (current_region->size < size) {
           start = cursor + 1;
@@ -397,17 +417,14 @@ void MC_ignore(void *addr, size_t size)
 
     if (current_region->addr == addr) {
       if (current_region->size < size) {
-        xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, &region);
+        xbt_dynar_insert_at(checkpoint_ignore, cursor + 1, &region);
       } else {
-        xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, &region);
+        xbt_dynar_insert_at(checkpoint_ignore, cursor, &region);
       }
     } else if (current_region->addr < addr) {
-      xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, &region);
+      xbt_dynar_insert_at(checkpoint_ignore, cursor + 1, &region);
     } else {
-      xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, &region);
+      xbt_dynar_insert_at(checkpoint_ignore, cursor, &region);
     }
   }
-
-  if (!raw_mem_set)
-    MC_SET_STD_HEAP;
 }
diff --git a/src/mc/mc_ignore.h b/src/mc/mc_ignore.h
new file mode 100644 (file)
index 0000000..fef9bcd
--- /dev/null
@@ -0,0 +1,22 @@
+/* Copyright (c) 2015. 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 <xbt/dynar.h>
+
+#include "mc/datatypes.h"
+#include "mc_process.h"
+
+#include "xbt/misc.h"           /* SG_BEGIN_DECL */
+
+SG_BEGIN_DECL();
+
+void MC_heap_region_ignore_insert(mc_heap_ignore_region_t region);
+void MC_process_ignore_memory(mc_process_t process, void *addr, size_t size);
+void MC_stack_area_add(stack_region_t stack_area);
+
+xbt_dynar_t MC_checkpoint_ignore_new(void);
+
+
+SG_END_DECL();
index 6a21a60..ec50dad 100644 (file)
@@ -27,27 +27,19 @@ xbt_parmap_t parmap;
 
 static xbt_dynar_t get_atomic_propositions_values()
 {
-  int res;
-  int_f_void_t f;
   unsigned int cursor = 0;
   xbt_automaton_propositional_symbol_t ps = NULL;
   xbt_dynar_t values = xbt_dynar_new(sizeof(int), NULL);
-
   xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps) {
-    f = (int_f_void_t) ps->function;
-    res = f();
+    int res = xbt_automaton_propositional_symbol_evaluate(ps);
     xbt_dynar_push_as(values, int, res);
   }
 
   return values;
 }
 
-
-static mc_visited_pair_t is_reached_acceptance_pair(mc_pair_t pair){
-
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
+static mc_visited_pair_t is_reached_acceptance_pair(mc_pair_t pair) {
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   mc_visited_pair_t new_pair = NULL;
   new_pair = MC_visited_pair_new(pair->num, pair->automaton_state, pair->atomic_propositions, pair->graph_state);
@@ -87,10 +79,7 @@ static mc_visited_pair_t is_reached_acceptance_pair(mc_pair_t pair){
                 xbt_fifo_shift(mc_stack);
                 if (dot_output != NULL)
                   fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", initial_global_state->prev_pair, pair_test->num, initial_global_state->prev_req);
-
-                if (!raw_mem_set)
-                  MC_SET_STD_HEAP;
-
+                mmalloc_set_current_heap(heap);
                 return NULL;
               }
             }
@@ -112,19 +101,13 @@ static mc_visited_pair_t is_reached_acceptance_pair(mc_pair_t pair){
     }
 
   }
-
-  if (!raw_mem_set)
-    MC_SET_STD_HEAP;
-
+  mmalloc_set_current_heap(heap);
   return new_pair;
-
 }
 
-static void remove_acceptance_pair(int pair_num) {
-
-  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
+static void remove_acceptance_pair(int pair_num)
+{
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   unsigned int cursor = 0;
   mc_visited_pair_t pair_test = NULL;
@@ -147,8 +130,7 @@ static void remove_acceptance_pair(int pair_num) {
 
   }
 
-  if (!raw_mem_set)
-    MC_SET_STD_HEAP;
+  mmalloc_set_current_heap(heap);
 }
 
 
@@ -175,7 +157,7 @@ static int MC_automaton_evaluate_label(xbt_automaton_exp_label_t l,
       unsigned int cursor = 0;
       xbt_automaton_propositional_symbol_t p = NULL;
       xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, p) {
-        if (strcmp(p->pred, l->u.predicat) == 0)
+        if (strcmp(xbt_automaton_propositional_symbol_get_name(p), l->u.predicat) == 0)
           return (int) xbt_dynar_get_as(atomic_propositions_values, cursor, int);
       }
       return -1;
@@ -238,12 +220,10 @@ void MC_pre_modelcheck_liveness(void) {
 
   if (initial_global_state->raw_mem_set)
     MC_SET_MC_HEAP;
-
-
 }
 
-void MC_modelcheck_liveness() {
-
+void MC_modelcheck_liveness()
+{
   smx_process_t process = NULL;
   mc_pair_t current_pair = NULL;
   int value, res, visited_num = -1;
index 45657f4..5c450ca 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <stdint.h>
 
-#define UNW_LOCAL_ONLY
 #include <libunwind.h>
 #include <dwarf.h>
 #include <elfutils/libdw.h>
@@ -18,6 +17,7 @@
 #include "mc_interface.h"
 #include "mc_object_info.h"
 #include "mc_forward.h"
+#include "mc_address_space.h"
 
 SG_BEGIN_DECL()
 
@@ -76,8 +76,8 @@ enum mc_location_type mc_get_location_type(mc_location_t location) {
   }
 }
 
-void mc_dwarf_resolve_location(mc_location_t location, mc_expression_t expression, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot, int process_index);
-void mc_dwarf_resolve_locations(mc_location_t location, mc_location_list_t locations, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot, int process_index);
+void mc_dwarf_resolve_location(mc_location_t location, mc_expression_t expression, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_address_space_t address_space, int process_index);
+void mc_dwarf_resolve_locations(mc_location_t location, mc_location_list_t locations, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_address_space_t address_space, int process_index);
 
 void mc_dwarf_expression_clear(mc_expression_t expression);
 void mc_dwarf_expression_init(mc_expression_t expression, size_t len, Dwarf_Op* ops);
@@ -103,7 +103,7 @@ typedef struct s_mc_expression_state {
 
   unw_cursor_t* cursor;
   void* frame_base;
-  mc_snapshot_t snapshot;
+  mc_address_space_t address_space;
   mc_object_info_t object_info;
   int process_index;
 } s_mc_expression_state_t, *mc_expression_state_t;
index b5ee069..666a246 100644 (file)
@@ -16,7 +16,7 @@
  * @return Process address of the given member of the 'object' struct/class
  */
 void *mc_member_resolve(const void *base, dw_type_t type, dw_type_t member,
-                        mc_snapshot_t snapshot, int process_index)
+                        mc_address_space_t address_space, int process_index)
 {
   if (!member->location.size) {
     return ((char *) base) + member->offset;
@@ -26,7 +26,7 @@ void *mc_member_resolve(const void *base, dw_type_t type, dw_type_t member,
   memset(&state, 0, sizeof(s_mc_expression_state_t));
   state.frame_base = NULL;
   state.cursor = NULL;
-  state.snapshot = snapshot;
+  state.address_space = address_space;
   state.stack_size = 1;
   state.stack[0] = (uintptr_t) base;
   state.process_index = process_index;
index b474b0c..72f51a9 100644 (file)
@@ -8,6 +8,8 @@
 #include <fcntl.h>
 
 #include "xbt/log.h"
+#include "xbt/dynar.h"
+#include "xbt/virtu.h"
 
 #include "mc/mc.h"
 #include "mc_object_info.h"
@@ -24,30 +26,26 @@ xbt_mheap_t mc_heap = NULL;           /* memory persistent over the MC rollbacks
 /* It creates the two heap regions: std_heap and mc_heap */
 void MC_memory_init()
 {
+  if (!malloc_use_mmalloc()) {
+    xbt_die("Model-checking support is not enabled: run with simgrid-mc.");
+  }
+
   /* Create the first region HEAP_OFFSET bytes after the heap break address */
   std_heap = mmalloc_get_default_md();
   xbt_assert(std_heap != NULL);
 
-#if 0 && defined HAVE_GNU_LD && !defined MMALLOC_WANT_OVERRIDE_LEGACY
-  /* use the system malloc for the model-checker data */
-  mc_heap = NULL;
-#else
   /* Create the second region a page after the first one ends + safety gap */
   mc_heap =
       xbt_mheap_new_options(-1,
                             (char *) (std_heap) + STD_HEAP_SIZE + xbt_pagesize,
                             0);
   xbt_assert(mc_heap != NULL);
-#endif
 }
 
 /* Finalize the memory subsystem */
 #include "xbt_modinter.h"
 void MC_memory_exit(void)
 {
-  MC_free_object_info(&mc_binary_info);
-  MC_free_object_info(&mc_libsimgrid_info);
-
-  if (mc_heap)
+  if (mc_heap && mc_heap != std_heap)
     xbt_mheap_destroy(mc_heap);
 }
index afa2b58..12da85f 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef MC_MEMORY_MAP_H
 #define MC_MEMORY_MAP_H
 
+#include <sys/types.h>
+
 #include <simgrid_config.h>
 #include "mc_forward.h"
 
@@ -39,8 +41,7 @@ struct s_memory_map {
 
 };
 
-void MC_init_memory_map_info(void);
-memory_map_t MC_get_memory_map(void);
+memory_map_t MC_get_memory_map(pid_t pid);
 void MC_free_memory_map(memory_map_t map);
 
 SG_END_DECL()
index 6740829..1fa7423 100644 (file)
@@ -38,7 +38,7 @@ size_t mc_page_count(size_t size)
  *  @return Virtual memory page number of the given address
  */
 static inline __attribute__ ((always_inline))
-size_t mc_page_number(void* base, void* address)
+size_t mc_page_number(const void* base, const void* address)
 {
   xbt_assert(address>=base, "The address is not in the range");
   return ((uintptr_t) address - (uintptr_t) base) >> xbt_pagebits;
@@ -50,7 +50,7 @@ size_t mc_page_number(void* base, void* address)
  *  @return Offset within the memory page
  */
 static inline __attribute__ ((always_inline))
-size_t mc_page_offset(void* address)
+size_t mc_page_offset(const void* address)
 {
   return ((uintptr_t) address) & (xbt_pagesize-1);
 }
@@ -61,13 +61,13 @@ size_t mc_page_offset(void* address)
  *  @param page Index of the page
  */
 static inline __attribute__ ((always_inline))
-void* mc_page_from_number(void* base, size_t page)
+void* mc_page_from_number(const void* base, size_t page)
 {
   return (void*) ((char*)base + (page << xbt_pagebits));
 }
 
 static inline __attribute__ ((always_inline))
-bool mc_same_page(void* a, void* b)
+bool mc_same_page(const void* a, const void* b)
 {
   return ((uintptr_t) a >> xbt_pagebits) == ((uintptr_t) b >> xbt_pagebits);
 }
diff --git a/src/mc/mc_model_checker.c b/src/mc/mc_model_checker.c
new file mode 100644 (file)
index 0000000..e3cc961
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright (c) 2008-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 "mc_model_checker.h"
+#include "mc_page_store.h"
+
+mc_model_checker_t mc_model_checker = NULL;
+
+mc_model_checker_t MC_model_checker_new(pid_t pid, int socket)
+{
+  mc_model_checker_t mc = xbt_new0(s_mc_model_checker_t, 1);
+  mc->pages = mc_pages_store_new();
+  mc->fd_clear_refs = -1;
+  mc->fd_pagemap = -1;
+  MC_process_init(&mc->process, pid, socket);
+  return mc;
+}
+
+void MC_model_checker_delete(mc_model_checker_t mc)
+{
+  mc_pages_store_delete(mc->pages);
+  if(mc->record)
+    xbt_dynar_free(&mc->record);
+  MC_process_clear(&mc->process);
+}
index 9ab2813..308cf12 100644 (file)
@@ -7,9 +7,13 @@
 #ifndef MC_MODEL_CHECKER_H
 #define MC_MODEL_CHECKER_H
 
+#include <sys/types.h>
+
 #include <simgrid_config.h>
 
 #include "mc_forward.h"
+#include "mc_process.h"
+#include "mc_page_store.h"
 
 SG_BEGIN_DECL()
 
@@ -27,9 +31,10 @@ struct s_mc_model_checker {
   int fd_clear_refs;
   int fd_pagemap;
   xbt_dynar_t record;
+  s_mc_process_t process;
 };
 
-mc_model_checker_t MC_model_checker_new(void);
+mc_model_checker_t MC_model_checker_new(pid_t pid, int socket);
 void MC_model_checker_delete(mc_model_checker_t mc);
 
 SG_END_DECL()
diff --git a/src/mc/mc_object_info.c b/src/mc/mc_object_info.c
new file mode 100644 (file)
index 0000000..874235c
--- /dev/null
@@ -0,0 +1,38 @@
+#include <stddef.h>
+
+#include <xbt/dynar.h>
+
+#include "mc_object_info.h"
+#include "mc_private.h"
+
+dw_frame_t MC_file_object_info_find_function(mc_object_info_t info, const void *ip)
+{
+  xbt_dynar_t dynar = info->functions_index;
+  mc_function_index_item_t base =
+      (mc_function_index_item_t) xbt_dynar_get_ptr(dynar, 0);
+  int i = 0;
+  int j = xbt_dynar_length(dynar) - 1;
+  while (j >= i) {
+    int k = i + ((j - i) / 2);
+    if (ip < base[k].low_pc) {
+      j = k - 1;
+    } else if (ip >= base[k].high_pc) {
+      i = k + 1;
+    } else {
+      return base[k].function;
+    }
+  }
+  return NULL;
+}
+
+dw_variable_t MC_file_object_info_find_variable_by_name(mc_object_info_t info, const char* name)
+{
+  unsigned int cursor = 0;
+  dw_variable_t variable;
+  xbt_dynar_foreach(info->global_variables, cursor, variable){
+    if(!strcmp(name, variable->name))
+      return variable;
+  }
+
+  return NULL;
+}
index 2e0b68f..9914c56 100644 (file)
@@ -12,6 +12,7 @@
 #define MC_OBJECT_INFO_H
 
 #include <stdint.h>
+#include <stdbool.h>
 
 #include <simgrid_config.h>
 #include <xbt/dict.h>
@@ -19,6 +20,8 @@
 
 #include "mc_forward.h"
 #include "mc_location.h"
+#include "mc_process.h"
+#include "../smpi/private.h"
 
 SG_BEGIN_DECL();
 
@@ -58,6 +61,7 @@ enum mc_object_info_flags {
 struct s_mc_object_info {
   enum mc_object_info_flags flags;
   char* file_name;
+  const void* start, *end;
   char *start_exec, *end_exec; // Executable segment
   char *start_rw, *end_rw; // Read-write segment
   char *start_ro, *end_ro; // read-only segment
@@ -72,6 +76,18 @@ struct s_mc_object_info {
   xbt_dynar_t functions_index;
 };
 
+static inline __attribute__ ((always_inline))
+bool MC_object_info_executable(mc_object_info_t info)
+{
+  return info->flags & MC_OBJECT_INFO_EXECUTABLE;
+}
+
+static inline __attribute__ ((always_inline))
+bool MC_object_info_is_privatized(mc_object_info_t info)
+{
+  return info && MC_object_info_executable(info) && smpi_privatize_global_variables;
+}
+
 /** Find the DWARF offset for this ELF object
  *
  *  An offset is applied to address found in DWARF:
@@ -89,10 +105,13 @@ struct s_mc_object_info {
 void* MC_object_base_address(mc_object_info_t info);
 
 mc_object_info_t MC_new_object_info(void);
-mc_object_info_t MC_find_object_info(memory_map_t maps, char* name, int executable);
+mc_object_info_t MC_find_object_info(memory_map_t maps, const char* name, int executable);
 void MC_free_object_info(mc_object_info_t* p);
 
-void MC_post_process_object_info(mc_object_info_t info);
+dw_frame_t MC_file_object_info_find_function(mc_object_info_t info, const void *ip);
+dw_variable_t MC_file_object_info_find_variable_by_name(mc_object_info_t info, const char* name);
+
+void MC_post_process_object_info(mc_process_t process, mc_object_info_t info);
 
 void MC_dwarf_get_variables(mc_object_info_t info);
 void MC_dwarf_get_variables_libdw(mc_object_info_t info);
@@ -102,12 +121,7 @@ const char* MC_dwarf_tagname(int tag);
 // Not used:
 char* get_type_description(mc_object_info_t info, char *type_name);
 
-extern mc_object_info_t mc_libsimgrid_info;
-extern mc_object_info_t mc_binary_info;
-extern mc_object_info_t mc_object_infos[2];
-extern size_t mc_object_infos_size;
-
-void* mc_member_resolve(const void* base, dw_type_t type, dw_type_t member, mc_snapshot_t snapshot, int process_index);
+void* mc_member_resolve(const void* base, dw_type_t type, dw_type_t member, mc_address_space_t snapshot, int process_index);
 
 struct s_dw_variable{
   Dwarf_Off dwarf_offset; /* Global offset of the field. */
index 499e5f2..c8aa50f 100644 (file)
@@ -1,3 +1,5 @@
+#include <unistd.h> // pread, pwrite
+
 #include "mc_page_store.h"
 #include "mc_mmu.h"
 #include "mc_private.h"
@@ -20,10 +22,17 @@ extern "C" {
  *  @param reference_pages Snapshot page numbers of the previous soft_dirty_reset (or NULL)
  *  @return                Snapshot page numbers of this new snapshot
  */
-size_t* mc_take_page_snapshot_region(void* data, size_t page_count, uint64_t* pagemap, size_t* reference_pages)
+size_t* mc_take_page_snapshot_region(mc_process_t process,
+  void* data, size_t page_count, uint64_t* pagemap, size_t* reference_pages)
 {
   size_t* pagenos = (size_t*) malloc(page_count * sizeof(size_t));
 
+  const bool is_self = MC_process_is_self(process);
+
+  void* temp = NULL;
+  if (!is_self)
+    temp = malloc(xbt_pagesize);
+
   for (size_t i=0; i!=page_count; ++i) {
     bool softclean = pagemap && !(pagemap[i] & SOFT_DIRTY);
     if (softclean && reference_pages) {
@@ -34,10 +43,27 @@ size_t* mc_take_page_snapshot_region(void* data, size_t page_count, uint64_t* pa
       // Otherwise, we need to store the page the hard way
       // (by reading its content):
       void* page = (char*) data + (i << xbt_pagebits);
-      pagenos[i] = mc_model_checker->pages->store_page(page);
+      xbt_assert(mc_page_offset(page)==0, "Not at the beginning of a page");
+      void* page_data;
+      if (is_self) {
+        page_data = page;
+      } else {
+        /* Adding another copy (and a syscall) will probably slow things a lot.
+           TODO, optimize this somehow (at least by grouping the syscalls)
+           if needed. Either:
+            - reduce the number of syscalls;
+            - let the application snapshot itself;
+            - move the segments in shared memory (this will break `fork` however).
+        */
+        page_data = temp;
+        MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE,
+          temp, page, xbt_pagesize, MC_PROCESS_INDEX_DISABLED);
+      }
+      pagenos[i] = mc_model_checker->pages->store_page(page_data);
     }
   }
 
+  free(temp);
   return pagenos;
 }
 
@@ -59,7 +85,8 @@ void mc_free_page_snapshot_region(size_t* pagenos, size_t page_count)
  *  @param pagemap         Linux kernel pagemap values fot this region (or NULL)
  *  @param reference_pages Snapshot page numbers of the previous soft_dirty_reset (or NULL)
  */
-void mc_restore_page_snapshot_region(void* start_addr, size_t page_count, size_t* pagenos, uint64_t* pagemap, size_t* reference_pagenos)
+void mc_restore_page_snapshot_region(mc_process_t process,
+  void* start_addr, size_t page_count, size_t* pagenos, uint64_t* pagemap, size_t* reference_pagenos)
 {
   for (size_t i=0; i!=page_count; ++i) {
 
@@ -73,7 +100,7 @@ void mc_restore_page_snapshot_region(void* start_addr, size_t page_count, size_t
     // Otherwise, copy the page:
     void* target_page = mc_page_from_number(start_addr, i);
     const void* source_page = mc_model_checker->pages->get_page(pagenos[i]);
-    memcpy(target_page, source_page, xbt_pagesize);
+    MC_process_write(process, source_page, target_page, xbt_pagesize);
   }
 }
 
@@ -159,15 +186,18 @@ static void mc_read_pagemap(uint64_t* pagemap, size_t page_start, size_t page_co
 
 // ***** High level API
 
-mc_mem_region_t mc_region_new_sparse(int type, void *start_addr, void* permanent_addr, size_t size, mc_mem_region_t ref_reg)
+mc_mem_region_t mc_region_new_sparse(mc_region_type_t region_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);
+  mc_process_t process = &mc_model_checker->process;
 
-  new_reg->start_addr = start_addr;
-  new_reg->permanent_addr = permanent_addr;
-  new_reg->data = NULL;
-  new_reg->size = size;
-  new_reg->page_numbers = NULL;
+  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_CHUNKED;
+  region->start_addr = start_addr;
+  region->permanent_addr = permanent_addr;
+  region->size = size;
 
   xbt_assert((((uintptr_t)start_addr) & (xbt_pagesize-1)) == 0,
     "Not at the beginning of a page");
@@ -176,22 +206,27 @@ mc_mem_region_t mc_region_new_sparse(int type, void *start_addr, void* permanent
   size_t page_count = mc_page_count(size);
 
   uint64_t* pagemap = NULL;
-  if (_sg_mc_soft_dirty && mc_model_checker->parent_snapshot) {
-      pagemap = (uint64_t*) mmalloc_no_memset(mc_heap, sizeof(uint64_t) * page_count);
+  if (_sg_mc_soft_dirty && mc_model_checker->parent_snapshot &&
+      MC_process_is_self(process)) {
+      pagemap = (uint64_t*) malloc_no_memset(sizeof(uint64_t) * page_count);
       mc_read_pagemap(pagemap, mc_page_number(NULL, permanent_addr), page_count);
   }
 
+  size_t* reg_page_numbers = NULL;
+  if (ref_reg!=NULL && ref_reg->storage_type == MC_REGION_STORAGE_TYPE_CHUNKED)
+    reg_page_numbers = ref_reg->chunked.page_numbers;
+
   // Take incremental snapshot:
-  new_reg->page_numbers = mc_take_page_snapshot_region(permanent_addr, page_count, pagemap,
-    ref_reg==NULL ? NULL : ref_reg->page_numbers);
+  region->chunked.page_numbers = mc_take_page_snapshot_region(process,
+    permanent_addr, page_count, pagemap, reg_page_numbers);
 
   if(pagemap) {
     mfree(mc_heap, pagemap);
   }
-  return new_reg;
+  return region;
 }
 
-void mc_region_restore_sparse(mc_mem_region_t reg, mc_mem_region_t ref_reg)
+void mc_region_restore_sparse(mc_process_t process, mc_mem_region_t reg, mc_mem_region_t ref_reg)
 {
   xbt_assert((((uintptr_t)reg->permanent_addr) & (xbt_pagesize-1)) == 0,
     "Not at the beginning of a page");
@@ -200,14 +235,20 @@ void mc_region_restore_sparse(mc_mem_region_t reg, mc_mem_region_t ref_reg)
   uint64_t* pagemap = NULL;
 
   // Read soft-dirty bits if necessary in order to know which pages have changed:
-  if (_sg_mc_soft_dirty && mc_model_checker->parent_snapshot) {
-    pagemap = (uint64_t*) mmalloc_no_memset(mc_heap, sizeof(uint64_t) * page_count);
+  if (_sg_mc_soft_dirty && mc_model_checker->parent_snapshot
+      && MC_process_is_self(process)) {
+    pagemap = (uint64_t*) malloc_no_memset(sizeof(uint64_t) * page_count);
     mc_read_pagemap(pagemap, mc_page_number(NULL, reg->permanent_addr), page_count);
   }
 
-  // Incremental per-page snapshot restoration:
-  mc_restore_page_snapshot_region(reg->permanent_addr, page_count, reg->page_numbers,
-    pagemap, ref_reg ? ref_reg->page_numbers : NULL);
+  // Incremental per-page snapshot restoration:s
+  size_t* reg_page_numbers = NULL;
+  if (ref_reg && ref_reg->storage_type == MC_REGION_STORAGE_TYPE_CHUNKED)
+    reg_page_numbers = ref_reg->chunked.page_numbers;
+
+  mc_restore_page_snapshot_region(process,
+    reg->permanent_addr, page_count, reg->chunked.page_numbers,
+    pagemap, reg_page_numbers);
 
   if(pagemap) {
     free(pagemap);
index 11022f8..222f3a7 100644 (file)
@@ -140,7 +140,6 @@ void s_mc_pages_store::remove_page(size_t pageno)
 /** Store a page in memory */
 size_t s_mc_pages_store::store_page(void* page)
 {
-  xbt_assert(mc_page_offset(page)==0, "Not at the beginning of a page");
   xbt_assert(top_index_ <= this->capacity_, "top_index is not consistent");
 
   // First, we check if a page with the same content is already in the page
@@ -239,7 +238,7 @@ XBT_TEST_UNIT("base", test_mc_page_store, "Test adding/removing pages in the sto
 {
   xbt_test_add("Init");
   size_t pagesize = (size_t) getpagesize();
-  std::auto_ptr<s_mc_pages_store_t> store = std::auto_ptr<s_mc_pages_store_t>(new s_mc_pages_store(500));
+  std::unique_ptr<s_mc_pages_store_t> store = std::unique_ptr<s_mc_pages_store_t>(new s_mc_pages_store(500));
   void* data = getpage();
   xbt_test_assert(store->size()==0, "Bad size");
 
index 4a86245..bcc454f 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef MC_PRIVATE_H
 #define MC_PRIVATE_H
 
+#include <sys/types.h>
+
 #include "simgrid_config.h"
 #include <stdio.h>
 #include <stdint.h>
@@ -21,6 +23,7 @@
 #include "mc/datatypes.h"
 #include "xbt/fifo.h"
 #include "xbt/config.h"
+
 #include "xbt/function_types.h"
 #include "xbt/mmalloc.h"
 #include "../simix/smx_private.h"
@@ -38,12 +41,15 @@ SG_BEGIN_DECL()
 
 typedef struct s_mc_function_index_item s_mc_function_index_item_t, *mc_function_index_item_t;
 
-/****************************** Snapshots ***********************************/
-
-extern xbt_dynar_t mc_checkpoint_ignore;
-
 /********************************* MC Global **********************************/
 
+/** Initialisation of the model-checker
+ *
+ * @param pid     PID of the target process
+ * @param socket  FD for the communication socket **in server mode** (or -1 otherwise)
+ */
+void MC_init_pid(pid_t pid, int socket);
+
 extern FILE *dot_output;
 extern const char* colors[13];
 extern xbt_parmap_t parmap;
@@ -82,16 +88,13 @@ extern mc_stats_t mc_stats;
 
 void MC_print_statistics(mc_stats_t stats);
 
-extern char *libsimgrid_path;
-
 /********************************** Snapshot comparison **********************************/
 
 typedef struct s_mc_comparison_times{
   double nb_processes_comparison_time;
   double bytes_used_comparison_time;
   double stacks_sizes_comparison_time;
-  double binary_global_variables_comparison_time;
-  double libsimgrid_global_variables_comparison_time;
+  double global_variables_comparison_time;
   double heap_comparison_time;
   double stacks_comparison_time;
 }s_mc_comparison_times_t, *mc_comparison_times_t;
@@ -107,9 +110,6 @@ void print_comparison_times(void);
 
 /********************************** Variables with DWARF **********************************/
 
-dw_frame_t MC_find_function_by_ip(void* ip);
-mc_object_info_t MC_ip_find_object_info(void* ip);
-
 void MC_find_object_address(memory_map_t maps, mc_object_info_t result);
 
 /********************************** Miscellaneous **********************************/
diff --git a/src/mc/mc_process.c b/src/mc/mc_process.c
new file mode 100644 (file)
index 0000000..65c77a8
--- /dev/null
@@ -0,0 +1,514 @@
+#include <assert.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <regex.h>
+#include <sys/mman.h> // PROT_*
+
+#include <pthread.h>
+
+#include <libgen.h>
+
+#include <libunwind.h>
+#include <libunwind-ptrace.h>
+
+#include <xbt/mmalloc.h>
+
+#include "mc_process.h"
+#include "mc_object_info.h"
+#include "mc_address_space.h"
+#include "mc_unw.h"
+#include "mc_snapshot.h"
+#include "mc_ignore.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc,
+                                "MC process information");
+
+static void MC_process_init_memory_map_info(mc_process_t process);
+static void MC_process_open_memory_file(mc_process_t process);
+
+// ***** Destructor callbacks
+
+// ***** mc_address_space methods for mc_process
+
+static mc_process_t MC_process_get_process(mc_process_t p) {
+  return p;
+}
+
+static const s_mc_address_space_class_t mc_process_class = {
+  .read = (void*) &MC_process_read,
+  .get_process = (void*) MC_process_get_process
+};
+
+bool MC_is_process(mc_address_space_t p)
+{
+  return p->address_space_class == &mc_process_class;
+}
+
+// ***** mc_process
+
+void MC_process_init(mc_process_t process, pid_t pid, int sockfd)
+{
+  process->address_space.address_space_class = &mc_process_class;
+  process->process_flags = MC_PROCESS_NO_FLAG;
+  process->socket = sockfd;
+  process->pid = pid;
+  if (pid==getpid())
+    process->process_flags |= MC_PROCESS_SELF_FLAG;
+  process->running = true;
+  process->status = 0;
+  process->memory_map = MC_get_memory_map(pid);
+  process->memory_file = -1;
+  process->cache_flags = 0;
+  process->heap = NULL;
+  process->heap_info = NULL;
+  MC_process_init_memory_map_info(process);
+  MC_process_open_memory_file(process);
+
+  // Read std_heap (is a struct mdesc*):
+  dw_variable_t std_heap_var = MC_process_find_variable_by_name(process, "std_heap");
+  if (!std_heap_var)
+    xbt_die("No heap information in the target process");
+  if(!std_heap_var->address)
+    xbt_die("No constant address for this variable");
+  MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE,
+    &process->heap_address, std_heap_var->address, sizeof(struct mdesc*),
+    MC_PROCESS_INDEX_DISABLED);
+
+  process->checkpoint_ignore = MC_checkpoint_ignore_new();
+
+  process->unw_addr_space = unw_create_addr_space(&mc_unw_accessors  , __BYTE_ORDER);
+  if (process->process_flags & MC_PROCESS_SELF_FLAG) {
+    process->unw_underlying_addr_space = unw_local_addr_space;
+    process->unw_underlying_context = NULL;
+  } else {
+    process->unw_underlying_addr_space = unw_create_addr_space(&mc_unw_vmread_accessors, __BYTE_ORDER);
+    process->unw_underlying_context = _UPT_create(pid);
+  }
+}
+
+void MC_process_clear(mc_process_t process)
+{
+  process->address_space.address_space_class = NULL;
+  process->process_flags = MC_PROCESS_NO_FLAG;
+  process->pid = 0;
+
+  MC_free_memory_map(process->memory_map);
+  process->memory_map = NULL;
+
+  process->maestro_stack_start = NULL;
+  process->maestro_stack_end = NULL;
+
+  xbt_dynar_free(&process->checkpoint_ignore);
+
+  size_t i;
+  for (i=0; i!=process->object_infos_size; ++i) {
+    MC_free_object_info(&process->object_infos[i]);
+  }
+  free(process->object_infos);
+  process->object_infos = NULL;
+  process->object_infos_size = 0;
+  if (process->memory_file >= 0) {
+    close(process->memory_file);
+  }
+
+  if (process->unw_underlying_addr_space != unw_local_addr_space) {
+    unw_destroy_addr_space(process->unw_underlying_addr_space);
+    _UPT_destroy(process->unw_underlying_context);
+  }
+  process->unw_underlying_context = NULL;
+  process->unw_underlying_addr_space = NULL;
+
+  unw_destroy_addr_space(process->unw_addr_space);
+  process->unw_addr_space = NULL;
+
+  process->cache_flags = 0;
+
+  free(process->heap);
+  process->heap = NULL;
+
+  free(process->heap_info);
+  process->heap_info = NULL;
+}
+
+void MC_process_refresh_heap(mc_process_t process)
+{
+  assert(!MC_process_is_self(process));
+  // Read/dereference/refresh the std_heap pointer:
+  if (!process->heap) {
+    xbt_mheap_t oldheap  = mmalloc_set_current_heap(mc_heap);
+    process->heap = malloc(sizeof(struct mdesc));
+    mmalloc_set_current_heap(oldheap);
+  }
+  MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE,
+    process->heap, process->heap_address, sizeof(struct mdesc),
+    MC_PROCESS_INDEX_DISABLED
+    );
+}
+
+void MC_process_refresh_malloc_info(mc_process_t process)
+{
+  assert(!MC_process_is_self(process));
+  if (!process->cache_flags & MC_PROCESS_CACHE_FLAG_HEAP)
+    MC_process_refresh_heap(process);
+  // Refresh process->heapinfo:
+  size_t malloc_info_bytesize = process->heap->heaplimit * sizeof(malloc_info);
+
+  xbt_mheap_t heap  = mmalloc_set_current_heap(mc_heap);
+  process->heap_info = (malloc_info*) realloc(process->heap_info,
+    malloc_info_bytesize);
+  mmalloc_set_current_heap(heap);
+
+  MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE,
+    process->heap_info,
+    process->heap->heapinfo, malloc_info_bytesize,
+    MC_PROCESS_INDEX_DISABLED);
+}
+
+#define SO_RE "\\.so[\\.0-9]*$"
+#define VERSION_RE "-[\\.0-9]*$"
+
+const char* FILTERED_LIBS[] = {
+  "libstdc++",
+  "libc++",
+  "libm",
+  "libgcc_s",
+  "libpthread",
+  "libunwind",
+  "libunwind-x86_64",
+  "libunwind-x86",
+  "libunwind-ptrace",
+  "libdw",
+  "libdl",
+  "librt",
+  "liblzma",
+  "libelf",
+  "libbz2",
+  "libz",
+  "libelf",
+  "libc",
+  "ld"
+};
+
+static bool MC_is_simgrid_lib(const char* libname)
+{
+  return !strcmp(libname, "libsimgrid");
+}
+
+static bool MC_is_filtered_lib(const char* libname)
+{
+  const size_t n = sizeof(FILTERED_LIBS) / sizeof(const char*);
+  size_t i;
+  for (i=0; i!=n; ++i)
+    if (strcmp(libname, FILTERED_LIBS[i])==0)
+      return true;
+  return false;
+}
+
+struct s_mc_memory_map_re {
+  regex_t so_re;
+  regex_t version_re;
+};
+
+static char* MC_get_lib_name(const char* pathname, struct s_mc_memory_map_re* res) {
+  const char* map_basename = basename((char*) pathname);
+
+  regmatch_t match;
+  if(regexec(&res->so_re, map_basename, 1, &match, 0))
+    return NULL;
+
+  char* libname = strndup(map_basename, match.rm_so);
+
+  // Strip the version suffix:
+  if(libname && !regexec(&res->version_re, libname, 1, &match, 0)) {
+    char* temp = libname;
+    libname = strndup(temp, match.rm_so);
+    free(temp);
+  }
+
+  return libname;
+}
+
+/** @brief Finds the range of the different memory segments and binary paths */
+static void MC_process_init_memory_map_info(mc_process_t process)
+{
+  XBT_DEBUG("Get debug information ...");
+  process->maestro_stack_start = NULL;
+  process->maestro_stack_end = NULL;
+  process->object_infos = NULL;
+  process->object_infos_size = 0;
+  process->binary_info = NULL;
+  process->libsimgrid_info = NULL;
+
+  struct s_mc_memory_map_re res;
+
+  if(regcomp(&res.so_re, SO_RE, 0) || regcomp(&res.version_re, VERSION_RE, 0))
+    xbt_die(".so regexp did not compile");
+
+  memory_map_t maps = process->memory_map;
+
+  const char* current_name = NULL;
+
+  size_t i = 0;
+  for (i=0; i < maps->mapsize; i++) {
+    map_region_t reg = &(maps->regions[i]);
+    const char* pathname = maps->regions[i].pathname;
+
+    // Nothing to do
+    if (maps->regions[i].pathname == NULL) {
+      current_name = NULL;
+      continue;
+    }
+
+    // [stack], [vvar], [vsyscall], [vdso] ...
+    if (pathname[0] == '[') {
+      if ((reg->prot & PROT_WRITE) && !memcmp(pathname, "[stack]", 7)) {
+        process->maestro_stack_start = reg->start_addr;
+        process->maestro_stack_end = reg->end_addr;
+      }
+      current_name = NULL;
+      continue;
+    }
+
+    if (current_name && strcmp(current_name, pathname)==0)
+      continue;
+
+    current_name = pathname;
+    if (!(reg->prot & PROT_READ) && (reg->prot & PROT_EXEC))
+      continue;
+
+    const bool is_executable = !i;
+    char* libname = NULL;
+    if (!is_executable) {
+      libname = MC_get_lib_name(pathname, &res);
+      if(!libname)
+        continue;
+      if (MC_is_filtered_lib(libname)) {
+        free(libname);
+        continue;
+      }
+    }
+
+    mc_object_info_t info =
+      MC_find_object_info(process->memory_map, pathname, is_executable);
+    process->object_infos = (mc_object_info_t*) realloc(process->object_infos,
+      (process->object_infos_size+1) * sizeof(mc_object_info_t*));
+    process->object_infos[process->object_infos_size] = info;
+    process->object_infos_size++;
+    if (is_executable)
+      process->binary_info = info;
+    else if (libname && MC_is_simgrid_lib(libname))
+      process->libsimgrid_info = info;
+    free(libname);
+  }
+
+  regfree(&res.so_re);
+  regfree(&res.version_re);
+
+  // Resolve time (including accress differents objects):
+  for (i=0; i!=process->object_infos_size; ++i)
+    MC_post_process_object_info(process, process->object_infos[i]);
+
+  xbt_assert(process->maestro_stack_start, "Did not find maestro_stack_start");
+  xbt_assert(process->maestro_stack_end, "Did not find maestro_stack_end");
+
+  XBT_DEBUG("Get debug information done !");
+}
+
+mc_object_info_t MC_process_find_object_info(mc_process_t process, const void *addr)
+{
+  size_t i;
+  for (i = 0; i != process->object_infos_size; ++i) {
+    if (addr >= (void *) process->object_infos[i]->start
+        && addr <= (void *) process->object_infos[i]->end) {
+      return process->object_infos[i];
+    }
+  }
+  return NULL;
+}
+
+mc_object_info_t MC_process_find_object_info_exec(mc_process_t process, const void *addr)
+{
+  size_t i;
+  for (i = 0; i != process->object_infos_size; ++i) {
+    if (addr >= (void *) process->object_infos[i]->start_exec
+        && addr <= (void *) process->object_infos[i]->end_exec) {
+      return process->object_infos[i];
+    }
+  }
+  return NULL;
+}
+
+mc_object_info_t MC_process_find_object_info_rw(mc_process_t process, const void *addr)
+{
+  size_t i;
+  for (i = 0; i != process->object_infos_size; ++i) {
+    if (addr >= (void *) process->object_infos[i]->start_rw
+        && addr <= (void *) process->object_infos[i]->end_rw) {
+      return process->object_infos[i];
+    }
+  }
+  return NULL;
+}
+
+// Functions, variables…
+
+dw_frame_t MC_process_find_function(mc_process_t process, const void *ip)
+{
+  mc_object_info_t info = MC_process_find_object_info_exec(process, ip);
+  if (info == NULL)
+    return NULL;
+  else
+    return MC_file_object_info_find_function(info, ip);
+}
+
+dw_variable_t MC_process_find_variable_by_name(mc_process_t process, const char* name)
+{
+  const size_t n = process->object_infos_size;
+  size_t i;
+  for (i=0; i!=n; ++i) {
+    mc_object_info_t info =process->object_infos[i];
+    dw_variable_t var = MC_file_object_info_find_variable_by_name(info, name);
+    if (var)
+      return var;
+  }
+  return NULL;
+}
+
+// ***** Memory access
+
+int MC_process_vm_open(pid_t pid, int flags)
+{
+  const size_t buffer_size = 30;
+  char buffer[buffer_size];
+  int res = snprintf(buffer, buffer_size, "/proc/%lli/mem", (long long) pid);
+  if (res < 0 || res >= buffer_size) {
+    errno = ENAMETOOLONG;
+    return -1;
+  }
+  return open(buffer, flags);
+}
+
+static void MC_process_open_memory_file(mc_process_t process)
+{
+  if (MC_process_is_self(process) || process->memory_file >= 0)
+    return;
+
+  int fd = MC_process_vm_open(process->pid, O_RDWR);
+  if (fd<0)
+    xbt_die("Could not open file for process virtual address space");
+  process->memory_file = fd;
+}
+
+static ssize_t pread_whole(int fd, void *buf, size_t count, off_t offset)
+{
+  char* buffer = (char*) buf;
+  ssize_t real_count = count;
+  while (count) {
+    ssize_t res = pread(fd, buffer, count, offset);
+    if (res > 0) {
+      count  -= res;
+      buffer += res;
+      offset += res;
+    } else if (res==0) {
+      return -1;
+    } else if (errno != EINTR) {
+      return -1;
+    }
+  }
+  return real_count;
+}
+
+static ssize_t pwrite_whole(int fd, const void *buf, size_t count, off_t offset)
+{
+  const char* buffer = (const char*) buf;
+  ssize_t real_count = count;
+  while (count) {
+    ssize_t res = pwrite(fd, buffer, count, offset);
+    if (res > 0) {
+      count  -= res;
+      buffer += res;
+      offset += res;
+    } else if (res==0) {
+      return -1;
+    } else if (errno != EINTR) {
+      return -1;
+    }
+  }
+  return real_count;
+}
+
+const void* MC_process_read(mc_process_t process, e_adress_space_read_flags_t flags,
+  void* local, const void* remote, size_t len,
+  int process_index)
+{
+  if (process_index != MC_PROCESS_INDEX_DISABLED) {
+    mc_object_info_t info = MC_process_find_object_info_rw(process, remote);
+    // Segment overlap is not handled.
+    if (MC_object_info_is_privatized(info)) {
+      if (process_index < 0)
+        xbt_die("Missing process index");
+      // Address translation in the privaization segment:
+      size_t offset = (const char*) remote - info->start_rw;
+      remote = (const char*) remote - offset;
+    }
+  }
+
+  if (MC_process_is_self(process)) {
+    if (flags & MC_ADDRESS_SPACE_READ_FLAGS_LAZY)
+      return remote;
+    else {
+      memcpy(local, remote, len);
+      return local;
+    }
+  } else {
+    if (pread_whole(process->memory_file, local, len, (off_t) remote) < 0)
+      xbt_die("Read from process %lli failed", (long long) process->pid);
+    return local;
+  }
+}
+
+void MC_process_write(mc_process_t process, const void* local, void* remote, size_t len)
+{
+  if (MC_process_is_self(process)) {
+    memcpy(remote, local, len);
+  } else {
+    if (pwrite_whole(process->memory_file, local, len, (off_t) remote) < 0)
+      xbt_die("Write to process %lli failed", (long long) process->pid);
+  }
+}
+
+static pthread_once_t zero_buffer_flag = PTHREAD_ONCE_INIT;
+static const void* zero_buffer;
+static const int zero_buffer_size = 10 * 4096;
+
+static void MC_zero_buffer_init(void)
+{
+  int fd = open("/dev/zero", O_RDONLY);
+  if (fd<0)
+    xbt_die("Could not open /dev/zero");
+  zero_buffer = mmap(NULL, zero_buffer_size, PROT_READ, MAP_SHARED, fd, 0);
+  if (zero_buffer == MAP_FAILED)
+    xbt_die("Could not map the zero buffer");
+  close(fd);
+}
+
+void MC_process_clear_memory(mc_process_t process, void* remote, size_t len)
+{
+  if (MC_process_is_self(process)) {
+    memset(remote, 0, len);
+  } else {
+    pthread_once(&zero_buffer_flag, MC_zero_buffer_init);
+    while (len) {
+      size_t s = len > zero_buffer_size ? zero_buffer_size : len;
+      MC_process_write(process, zero_buffer, remote, s);
+      remote = (char*) remote + s;
+      len -= s;
+    }
+  }
+}
diff --git a/src/mc/mc_process.h b/src/mc/mc_process.h
new file mode 100644 (file)
index 0000000..1e4384d
--- /dev/null
@@ -0,0 +1,191 @@
+/* Copyright (c) 2008-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. */
+
+#ifndef MC_PROCESS_H
+#define MC_PROCESS_H
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+#include "simgrid_config.h"
+
+#include <sys/types.h>
+
+#include <xbt/mmalloc.h>
+#include "xbt/mmalloc/mmprivate.h"
+
+#include "simix/popping_private.h"
+
+#include "mc_forward.h"
+#include "mc_mmalloc.h" // std_heap
+#include "mc_memory_map.h"
+#include "mc_address_space.h"
+
+SG_BEGIN_DECL()
+
+int MC_process_vm_open(pid_t pid, int flags);
+
+typedef enum {
+  MC_PROCESS_NO_FLAG = 0,
+  MC_PROCESS_SELF_FLAG = 1,
+} e_mc_process_flags_t;
+
+// Those flags are used to track down which cached information
+// is still up to date and which information needs to be updated.
+typedef enum {
+  MC_PROCESS_CACHE_FLAG_HEAP = 1,
+  MC_PROCESS_CACHE_FLAG_MALLOC_INFO = 2,
+} e_mc_process_cache_flags_t ;
+
+/** Representation of a process
+ */
+struct s_mc_process {
+  s_mc_address_space_t address_space;
+  e_mc_process_flags_t process_flags;
+  pid_t pid;
+  int socket;
+  int status;
+  bool running;
+  memory_map_t memory_map;
+  void *maestro_stack_start, *maestro_stack_end;
+  mc_object_info_t libsimgrid_info;
+  mc_object_info_t binary_info;
+  mc_object_info_t* object_infos;
+  size_t object_infos_size;
+  int memory_file;
+
+  // Cache: don't use those fields directly but with the getters
+  // which ensure that proper synchronisation has been done.
+
+  e_mc_process_cache_flags_t cache_flags;
+
+  /** Address of the heap structure in the target process.
+   */
+  void* heap_address;
+
+  /** Copy of the heap structure of the process
+   *
+   *  This is refreshed with the `MC_process_refresh` call.
+   *  This is not used if the process is the current one:
+   *  use `MC_process_get_heap_info` in order to use it.
+   */
+   xbt_mheap_t heap;
+
+  /** Copy of the allocation info structure
+   *
+   *  This is refreshed with the `MC_process_refresh` call.
+   *  This is not used if the process is the current one:
+   *  use `MC_process_get_malloc_info` in order to use it.
+   */
+  malloc_info* heap_info;
+
+  // ***** Libunwind-data
+
+  /** Full-featured MC-aware libunwind address space for the process
+   *
+   *  This address space is using a mc_unw_context_t
+   *  (with mc_process_t/mc_address_space_t and unw_context_t).
+   */
+  unw_addr_space_t unw_addr_space;
+
+  /** Underlying libunwind addres-space
+   *
+   *  The `find_proc_info`, `put_unwind_info`, `get_dyn_info_list_addr`
+   *  operations of the native MC address space is currently delegated
+   *  to this address space (either the local or a ptrace unwinder).
+   */
+  unw_addr_space_t unw_underlying_addr_space;
+
+  /** The corresponding context
+   */
+  void* unw_underlying_context;
+
+  xbt_dynar_t checkpoint_ignore;
+};
+
+bool MC_is_process(mc_address_space_t p);
+
+void MC_process_init(mc_process_t process, pid_t pid, int sockfd);
+void MC_process_clear(mc_process_t process);
+
+/** Refresh the information about the process
+ *
+ *  Do not use direclty, this is used by the getters when appropriate
+ *  in order to have fresh data.
+ */
+void MC_process_refresh_heap(mc_process_t process);
+
+/** Refresh the information about the process
+ *
+ *  Do not use direclty, this is used by the getters when appropriate
+ *  in order to have fresh data.
+ * */
+void MC_process_refresh_malloc_info(mc_process_t process);
+
+static inline
+bool MC_process_is_self(mc_process_t process)
+{
+  return process->process_flags & MC_PROCESS_SELF_FLAG;
+}
+
+/* Process memory access: */
+
+/** Read data from a process memory
+ *
+ *  @param process the process
+ *  @param local   local memory address (destination)
+ *  @param remote  target process memory address (source)
+ *  @param len     data size
+ */
+const void* MC_process_read(mc_process_t process,
+  e_adress_space_read_flags_t flags,
+  void* local, const void* remote, size_t len,
+  int process_index);
+
+/** Write data to a process memory
+ *
+ *  @param process the process
+ *  @param local   local memory address (source)
+ *  @param remote  target process memory address (target)
+ *  @param len     data size
+ */
+void MC_process_write(mc_process_t process, const void* local, void* remote, size_t len);
+
+void MC_process_clear_memory(mc_process_t process, void* remote, size_t len);
+
+/* Functions, variables of the process: */
+
+mc_object_info_t MC_process_find_object_info(mc_process_t process, const void* addr);
+mc_object_info_t MC_process_find_object_info_exec(mc_process_t process, const void* addr);
+mc_object_info_t MC_process_find_object_info_rw(mc_process_t process, const void* addr);
+
+dw_frame_t MC_process_find_function(mc_process_t process, const void* ip);
+
+static inline xbt_mheap_t MC_process_get_heap(mc_process_t process)
+{
+  if (MC_process_is_self(process))
+    return std_heap;
+  if (!(process->cache_flags & MC_PROCESS_CACHE_FLAG_HEAP))
+    MC_process_refresh_heap(process);
+  return process->heap;
+}
+
+static inline malloc_info* MC_process_get_malloc_info(mc_process_t process)
+{
+  if (MC_process_is_self(process))
+    return std_heap->heapinfo;
+  if (!(process->cache_flags & MC_PROCESS_CACHE_FLAG_MALLOC_INFO))
+    MC_process_refresh_malloc_info(process);
+  return process->heap_info;
+}
+
+/** Find (one occurence of) the named variable definition
+ */
+dw_variable_t MC_process_find_variable_by_name(mc_process_t process, const char* name);
+
+SG_END_DECL()
+
+#endif
diff --git a/src/mc/mc_protocol.c b/src/mc/mc_protocol.c
new file mode 100644 (file)
index 0000000..405a61a
--- /dev/null
@@ -0,0 +1,64 @@
+/* Copyright (c) 2015. 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 <errno.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <xbt/log.h>
+
+#include "mc_protocol.h"
+#include "mc_client.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_protocol, mc, "Generic MC protocol logic");
+
+int MC_protocol_send(int socket, void* message, size_t size)
+{
+  while (send(socket, message, size, 0) == -1) {
+    if (errno == EINTR)
+      continue;
+    else
+      return errno;
+  }
+  return 0;
+}
+
+int MC_protocol_send_simple_message(int socket, int type)
+{
+  s_mc_message_t message;
+  message.type = type;
+  return MC_protocol_send(socket, &message, sizeof(message));
+}
+
+int MC_protocol_hello(int socket)
+{
+  int e;
+  if ((e = MC_protocol_send_simple_message(socket, MC_MESSAGE_HELLO)) != 0) {
+    XBT_ERROR("Could not send HELLO message: %s", strerror(e));
+    return 1;
+  }
+
+  s_mc_message_t message;
+  message.type = MC_MESSAGE_NONE;
+
+  size_t s;
+  while ((s = recv(socket, &message, sizeof(message), 0)) == -1) {
+    if (errno == EINTR)
+      continue;
+    else {
+      XBT_ERROR("Could not receive HELLO message: %s", strerror(errno));
+      return 2;
+    }
+  }
+  if (s < sizeof(message) || message.type != MC_MESSAGE_HELLO) {
+    XBT_ERROR("Did not receive suitable HELLO message. Who are you?");
+    return 3;
+  }
+
+  return 0;
+}
diff --git a/src/mc/mc_protocol.h b/src/mc/mc_protocol.h
new file mode 100644 (file)
index 0000000..251e184
--- /dev/null
@@ -0,0 +1,97 @@
+/* Copyright (c) 2015. 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. */
+
+#ifndef MC_PROTOCOL_H
+#define MC_PROTOCOL_H
+
+#include <xbt/misc.h>
+
+#include "mc/datatypes.h"
+
+SG_BEGIN_DECL()
+
+// ***** Environment variables for passing context to the model-checked process
+
+/** Environment variable name set by `simgrid-mc` to enable MC support in the
+ *  children MC processes
+ */
+#define MC_ENV_VARIABLE "SIMGRIC_MC"
+
+/** Environment variable name used to pass the communication socket */
+#define MC_ENV_SOCKET_FD "SIMGRID_MC_SOCKET_FD"
+
+// ***** MC mode
+
+typedef enum {
+  MC_MODE_NONE = 0,
+  MC_MODE_STANDALONE,
+  MC_MODE_CLIENT,
+  MC_MODE_SERVER
+} e_mc_mode_t;
+
+extern e_mc_mode_t mc_mode;
+
+// ***** Messages
+
+typedef enum {
+  MC_MESSAGE_NONE,
+  MC_MESSAGE_HELLO,
+  MC_MESSAGE_CONTINUE,
+  MC_MESSAGE_IGNORE_HEAP,
+  MC_MESSAGE_UNIGNORE_HEAP,
+  MC_MESSAGE_IGNORE_MEMORY,
+  MC_MESSAGE_STACK_REGION,
+  MC_MESSAGE_REGISTER_SYMBOL,
+} e_mc_message_type;
+
+#define MC_MESSAGE_LENGTH 512
+
+/** Basic structure for a MC message
+ *
+ *  The current version of the client/server protocol sends C structures over `AF_LOCAL`
+ *  `SOCK_DGRAM` sockets. This means that the protocol is ABI/architecture specific:
+ *  we currently can't model-check a x86 process from a x86_64 process.
+ *
+ *  Moreover the protocol is not stable. The same version of the library should be used
+ *  for the client and the server.
+ *
+ *  This is the basic structure shared by all messages: all message start with a message
+ *  type.
+ */
+typedef struct s_mc_message {
+  e_mc_message_type type;
+} s_mc_message_t, *mc_message_t;
+
+typedef struct s_mc_ignore_heap_message {
+  e_mc_message_type type;
+  s_mc_heap_ignore_region_t region;
+} s_mc_ignore_heap_message_t, *mc_ignore_heap_message_t;
+
+typedef struct s_mc_ignore_memory_message {
+  e_mc_message_type type;
+  void *addr;
+  size_t size;
+} s_mc_ignore_memory_message_t, *mc_ignore_memory_message_t;
+
+typedef struct s_mc_stack_region_message {
+  e_mc_message_type type;
+  s_stack_region_t stack_region;
+} s_mc_stack_region_message_t, *mc_stack_region_message_t;
+
+typedef struct s_mc_register_symbol_message {
+  e_mc_message_type type;
+  char name[128];
+  int (*callback)(void*);
+  void* data;
+} s_mc_register_symbol_message_t, * mc_register_symbol_message_t;
+
+int MC_protocol_send(int socket, void* message, size_t size);
+int MC_protocol_send_simple_message(int socket, int type);
+int MC_protocol_hello(int socket);
+
+SG_END_DECL()
+
+#endif
index 83460ff..3d0fc9e 100644 (file)
@@ -20,15 +20,10 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_safety, mc,
  */
 void MC_pre_modelcheck_safety()
 {
-
-  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
   mc_state_t initial_state = NULL;
   smx_process_t process;
 
-  /* Create the initial state and push it into the exploration stack */
-  if (!mc_mem_set)
-    MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   if (_sg_mc_visited > 0)
     visited_states = xbt_dynar_new(sizeof(mc_visited_state_t), visited_state_free_voidp);
@@ -55,9 +50,7 @@ void MC_pre_modelcheck_safety()
   }
 
   xbt_fifo_unshift(mc_stack, initial_state);
-
-  if (!mc_mem_set)
-    MC_SET_STD_HEAP;
+  mmalloc_set_current_heap(heap);
 }
 
 
diff --git a/src/mc/mc_server.cpp b/src/mc/mc_server.cpp
new file mode 100644 (file)
index 0000000..12ca0a8
--- /dev/null
@@ -0,0 +1,329 @@
+/* Copyright (c) 2015. 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 <memory>
+#include <system_error>
+
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/signalfd.h>
+
+#include <xbt/log.h>
+
+#include "mc_model_checker.h"
+#include "mc_protocol.h"
+#include "mc_server.h"
+#include "mc_private.h"
+#include "mc_ignore.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_server, mc, "MC server logic");
+
+// HArdcoded index for now:
+#define SOCKET_FD_INDEX 0
+#define SIGNAL_FD_INDEX 1
+
+mc_server_t mc_server;
+
+struct mc_symbol_pointer_callback
+{
+  mc_process_t process;
+  void* value;
+};
+
+static int mc_symbol_pointer_callback_evaluate(void* p)
+{
+  struct mc_symbol_pointer_callback* callback = (struct mc_symbol_pointer_callback*) p;
+  int value;
+  MC_process_read(callback->process, MC_ADDRESS_SPACE_READ_FLAGS_NONE,
+    &value, callback->value, sizeof(value), MC_PROCESS_INDEX_ANY);
+  return value;
+}
+
+s_mc_server::s_mc_server(pid_t pid, int socket)
+{
+  this->pid = pid;
+  this->socket = socket;
+}
+
+void s_mc_server::start()
+{
+  /* Wait for the target process to initialize and exchange a HELLO messages
+   * before trying to look at its memory map.
+   */
+  XBT_DEBUG("Greeting the MC client");
+  int res = MC_protocol_hello(socket);
+  if (res != 0)
+    throw std::system_error(res, std::system_category());
+  XBT_DEBUG("Greeted the MC client");
+
+  // Block SIGCHLD (this will be handled with accept/signalfd):
+  sigset_t set;
+  sigemptyset(&set);
+  sigaddset(&set, SIGCHLD);
+  if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
+    throw std::system_error(errno, std::system_category());
+
+  sigset_t full_set;
+  sigfillset(&full_set);
+
+  // Prepare data for poll:
+
+  struct pollfd* socket_pollfd = &fds[SOCKET_FD_INDEX];
+  socket_pollfd->fd = socket;
+  socket_pollfd->events = POLLIN;
+  socket_pollfd->revents = 0;
+
+  int signal_fd = signalfd(-1, &set, 0);
+  if (signal_fd == -1)
+    throw std::system_error(errno, std::system_category());
+
+  struct pollfd* signalfd_pollfd = &fds[SIGNAL_FD_INDEX];
+  signalfd_pollfd->fd = signal_fd;
+  signalfd_pollfd->events = POLLIN;
+  signalfd_pollfd->revents = 0;
+}
+
+void s_mc_server::shutdown()
+{
+  XBT_DEBUG("Shuting down model-checker");
+
+  mc_process_t process = &mc_model_checker->process;
+  int status = process->status;
+  if (process->running) {
+    XBT_DEBUG("Killing process");
+    kill(process->pid, SIGTERM);
+    if (waitpid(process->pid, &status, 0) == -1)
+      throw std::system_error(errno, std::system_category());
+    // TODO, handle the case when the process does not want to die with a timeout
+    process->status = status;
+  }
+}
+
+void s_mc_server::exit()
+{
+  // Finished:
+  int status = mc_model_checker->process.status;
+  if (WIFEXITED(status))
+    ::exit(WEXITSTATUS(status));
+  else if (WIFSIGNALED(status)) {
+    // Try to uplicate the signal of the model-checked process.
+    // This is a temporary hack so we don't try too hard.
+    kill(mc_model_checker->process.pid, WTERMSIG(status));
+    abort();
+  } else {
+    xbt_die("Unexpected status from model-checked process");
+  }
+}
+
+void s_mc_server::resume(mc_process_t process)
+{
+  int socket = process->socket;
+  int res = MC_protocol_send_simple_message(socket, MC_MESSAGE_CONTINUE);
+  if (res)
+    throw std::system_error(res, std::system_category());
+}
+
+static
+void throw_socket_error(int fd)
+{
+  int error = 0;
+  socklen_t errlen = sizeof(error);
+  if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen) == -1)
+    error = errno;
+  throw std::system_error(error, std::system_category());
+}
+
+void s_mc_server::handle_events()
+{
+  char buffer[MC_MESSAGE_LENGTH];
+  struct pollfd* socket_pollfd = &fds[SOCKET_FD_INDEX];
+  struct pollfd* signalfd_pollfd = &fds[SIGNAL_FD_INDEX];
+
+  while(poll(fds, 2, -1) == -1) {
+    switch(errno) {
+    case EINTR:
+      continue;
+    default:
+      throw std::system_error(errno, std::system_category());
+    }
+  }
+
+  if (socket_pollfd->revents) {
+    if (socket_pollfd->revents & POLLIN) {
+
+      ssize_t size = recv(socket_pollfd->fd, buffer, sizeof(buffer), MSG_DONTWAIT);
+      if (size == -1 && errno != EAGAIN)
+        throw std::system_error(errno, std::system_category());
+
+      s_mc_message_t base_message;
+      if (size < (ssize_t) sizeof(base_message))
+        xbt_die("Broken message");
+      memcpy(&base_message, buffer, sizeof(base_message));
+
+      switch(base_message.type) {
+
+      case MC_MESSAGE_IGNORE_HEAP:
+        {
+          XBT_DEBUG("Received ignored region");
+          s_mc_ignore_heap_message_t message;
+          if (size != sizeof(message))
+            xbt_die("Broken messsage");
+          memcpy(&message, buffer, sizeof(message));
+          mc_heap_ignore_region_t region = xbt_new(s_mc_heap_ignore_region_t, 1);
+          *region = message.region;
+          MC_heap_region_ignore_insert(region);
+          break;
+        }
+
+
+      case MC_MESSAGE_UNIGNORE_HEAP:
+        {
+          XBT_DEBUG("Received unignored region");
+          s_mc_ignore_memory_message_t message;
+          if (size != sizeof(message))
+            xbt_die("Broken messsage");
+          memcpy(&message, buffer, sizeof(message));
+          MC_remove_ignore_heap(message.addr, message.size);
+          break;
+        }
+
+      case MC_MESSAGE_IGNORE_MEMORY:
+        {
+          XBT_DEBUG("Received ignored memory");
+          s_mc_ignore_memory_message_t message;
+          if (size != sizeof(message))
+            xbt_die("Broken messsage");
+          memcpy(&message, buffer, sizeof(message));
+          MC_process_ignore_memory(&mc_model_checker->process,
+            message.addr, message.size);
+          break;
+        }
+
+      case MC_MESSAGE_STACK_REGION:
+        {
+          XBT_DEBUG("Received stack area");
+          s_mc_stack_region_message_t message;
+          if (size != sizeof(message))
+            xbt_die("Broken messsage");
+          memcpy(&message, buffer, sizeof(message));
+          stack_region_t stack_region = xbt_new(s_stack_region_t, 1);
+          *stack_region = message.stack_region;
+          MC_stack_area_add(stack_region);
+        }
+        break;
+
+      case MC_MESSAGE_REGISTER_SYMBOL:
+        {
+          s_mc_register_symbol_message_t message;
+          if (size != sizeof(message))
+            xbt_die("Broken message");
+          memcpy(&message, buffer, sizeof(message));
+          if (message.callback)
+            xbt_die("Support for callbacks/functions symbols not implemented in client/server mode.");
+          XBT_DEBUG("Received symbol: %s", message.name);
+
+          struct mc_symbol_pointer_callback* callback = xbt_new(struct mc_symbol_pointer_callback, 1);
+          callback->process = &mc_model_checker->process;
+          callback->value   = message.data;
+
+          MC_automaton_new_propositional_symbol_callback(message.name,
+            mc_symbol_pointer_callback_evaluate, callback, free);
+          break;
+        }
+
+      default:
+        xbt_die("Unexpected message from model-checked application");
+
+      }
+      return;
+    }
+    if (socket_pollfd->revents & POLLERR) {
+      throw_socket_error(socket_pollfd->fd);
+    }
+    if (socket_pollfd->revents & POLLHUP)
+      xbt_die("Socket hang up?");
+  }
+
+  if (signalfd_pollfd->revents) {
+    if (signalfd_pollfd->revents & POLLIN) {
+      this->handle_signals();
+      return;
+    }
+    if (signalfd_pollfd->revents & POLLERR) {
+      throw_socket_error(signalfd_pollfd->fd);
+    }
+    if (signalfd_pollfd->revents & POLLHUP)
+      xbt_die("Signalfd hang up?");
+  }
+}
+
+void s_mc_server::loop()
+{
+  while (mc_model_checker->process.running)
+    this->handle_events();
+}
+
+void s_mc_server::handle_signals()
+{
+  struct signalfd_siginfo info;
+  struct pollfd* signalfd_pollfd = &fds[SIGNAL_FD_INDEX];
+  while (1) {
+    ssize_t size = read(signalfd_pollfd->fd, &info, sizeof(info));
+    if (size == -1) {
+      if (errno == EINTR)
+        continue;
+      else
+        throw std::system_error(errno, std::system_category());
+    } else if (size != sizeof(info))
+        return throw std::runtime_error(
+          "Bad communication with model-checked application");
+    else
+      break;
+  }
+  this->on_signal(&info);
+}
+
+void s_mc_server::handle_waitpid()
+{
+  XBT_DEBUG("Check for wait event");
+  int status;
+  pid_t pid;
+  while ((pid = waitpid(-1, &status, WNOHANG)) != 0) {
+    if (pid == -1) {
+      if (errno == ECHILD) {
+        // No more children:
+        if (mc_model_checker->process.running)
+          xbt_die("Inconsistent state");
+        else
+          break;
+      } else {
+        XBT_ERROR("Could not wait for pid: %s", strerror(errno));
+        throw std::system_error(errno, std::system_category());
+      }
+    }
+
+    if (pid == mc_model_checker->process.pid) {
+      if (WIFEXITED(status) || WIFSIGNALED(status)) {
+        XBT_DEBUG("Child process is over");
+        mc_model_checker->process.status = status;
+        mc_model_checker->process.running = false;
+      }
+    }
+  }
+}
+
+void s_mc_server::on_signal(const struct signalfd_siginfo* info)
+{
+  switch(info->ssi_signo) {
+  case SIGCHLD:
+    this->handle_waitpid();
+    break;
+  default:
+    break;
+  }
+}
diff --git a/src/mc/mc_server.h b/src/mc/mc_server.h
new file mode 100644 (file)
index 0000000..a8ea31b
--- /dev/null
@@ -0,0 +1,45 @@
+/* Copyright (c) 2015. 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. */
+
+#ifndef MC_SERVER_H
+#define MC_SERVER_H
+
+#include <xbt/misc.h>
+
+SG_BEGIN_DECL()
+
+#define MC_SERVER_ERROR 127
+
+typedef struct s_mc_server s_mc_server_t, *mc_server_t;
+
+extern mc_server_t mc_server;
+
+SG_END_DECL()
+
+#ifdef __cplusplus
+
+struct s_mc_server {
+private:
+  pid_t pid;
+  int socket;
+  struct pollfd fds[2];
+public:
+  s_mc_server(pid_t pid, int socket);
+  void start();
+  void shutdown();
+  void exit();
+  void resume(mc_process_t process);
+  void loop();
+  void handle_events();
+protected:
+  void handle_signals();
+  void handle_waitpid();
+  void on_signal(const struct signalfd_siginfo* info);
+};
+
+#endif
+
+#endif
index 97c4017..0a4f4f5 100644 (file)
  *  @param Snapshot region in the snapshot this pointer belongs to
  *         (or NULL if it does not belong to any snapshot region)
  * */
-mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot, int process_index)
+mc_mem_region_t mc_get_snapshot_region(const void* addr, mc_snapshot_t snapshot, int process_index)
 {
-#ifdef HAVE_SMPI
-  if (snapshot->privatization_regions) {
-
-    if (process_index < 0) {
+  size_t n = snapshot->snapshot_regions_count;
+  for (size_t i = 0; i != n; ++i) {
+    mc_mem_region_t region = snapshot->snapshot_regions[i];
+    if (!(region && mc_region_contain(region, addr)))
+      continue;
 
-      mc_mem_region_t region = snapshot->privatization_regions[0];
-      if( mc_region_contain(region, addr) ) {
+    if (region->storage_type == MC_REGION_STORAGE_TYPE_PRIVATIZED) {
+#ifdef HAVE_SMPI
+      // Use the current process index of the snapshot:
+      if (process_index == MC_PROCESS_INDEX_DISABLED) {
+        process_index = snapshot->privatization_index;
+      }
+      if (process_index < 0) {
         xbt_die("Missing process index");
       }
-
-    } else {
-      if (process_index >= smpi_process_count()) {
+      if (process_index >= region->privatized.regions_count) {
         xbt_die("Invalid process index");
       }
-
-      mc_mem_region_t region = snapshot->privatization_regions[process_index];
-      if( mc_region_contain(region, addr) ) {
-        return region;
-      }
-
-    }
-  }
+      mc_mem_region_t priv_region = region->privatized.regions[process_index];
+      xbt_assert(mc_region_contain(priv_region, addr));
+      return priv_region;
+#else
+      xbt_die("Privatized region in a non SMPI build (this should not happen)");
 #endif
-
-  for (size_t i = 0; i != NB_REGIONS; ++i) {
-    mc_mem_region_t region = snapshot->regions[i];
-    if ( region && mc_region_contain(region, addr) ) {
-      return region;
     }
+
+    return region;
   }
 
   return NULL;
@@ -65,7 +63,7 @@ mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot, int p
  *  @param size    Size of the data to read in bytes
  *  @return Pointer where the data is located (target buffer of original location)
  */
-void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* target, size_t size)
+const void* MC_region_read_fragmented(mc_mem_region_t region, void* target, const void* addr, size_t size)
 {
   // Last byte of the memory area:
   void* end = (char*) addr + size - 1;
@@ -105,14 +103,15 @@ void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* targ
  *  @param size     Size of the data to read in bytes
  *  @return Pointer where the data is located (target buffer or original location)
  */
-void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, int process_index, void* target, size_t size)
+const void* MC_snapshot_read(
+  mc_snapshot_t snapshot, e_adress_space_read_flags_t flags,
+  void* target, const void* addr, size_t size, int process_index)
 {
-  if (snapshot) {
-    mc_mem_region_t region = mc_get_snapshot_region(addr, snapshot, process_index);
-    return mc_snapshot_read_region(addr, region, target, size);
-  } else {
-    return addr;
-  }
+  mc_mem_region_t region = mc_get_snapshot_region(addr, snapshot, process_index);
+  if (region)
+    return MC_region_read(region, target, addr, size);
+  else
+    return MC_process_read(snapshot->process, flags, target, addr, size, process_index);
 }
 
 /** Compare memory between snapshots (with known regions)
@@ -123,18 +122,20 @@ void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, int process_index, vo
  * @param snapshot2 Region of the address in the second snapshot
  * @return same as memcmp
  * */
-int mc_snapshot_region_memcmp(
-  void* addr1, mc_mem_region_t region1,
-  void* addr2, mc_mem_region_t region2,
+int MC_snapshot_region_memcmp(
+  const void* addr1, mc_mem_region_t region1,
+  const void* addr2, mc_mem_region_t region2,
   size_t size)
 {
   // Using alloca() for large allocations may trigger stack overflow:
   // use malloc if the buffer is too big.
   bool stack_alloc = size < 64;
-  void* buffer1a = (region1==NULL || region1->data) ? NULL : stack_alloc ? alloca(size) : malloc(size);
-  void* buffer2a = (region2==NULL || region2->data) ? NULL : stack_alloc ? alloca(size) : malloc(size);
-  void* buffer1 = mc_snapshot_read_region(addr1, region1, buffer1a, size);
-  void* buffer2 = mc_snapshot_read_region(addr2, region2, buffer2a, size);
+  const bool region1_need_buffer = region1==NULL || region1->storage_type==MC_REGION_STORAGE_TYPE_FLAT;
+  const bool region2_need_buffer = region2==NULL || region2->storage_type==MC_REGION_STORAGE_TYPE_FLAT;
+  void* buffer1a = region1_need_buffer ? NULL : stack_alloc ? alloca(size) : malloc(size);
+  void* buffer2a = region2_need_buffer ? NULL : stack_alloc ? alloca(size) : malloc(size);
+  const void* buffer1 = MC_region_read(region1, buffer1a, addr1, size);
+  const void* buffer2 = MC_region_read(region2, buffer2a, addr2, size);
   int res;
   if (buffer1 == buffer2) {
     res = 0;
@@ -156,13 +157,13 @@ int mc_snapshot_region_memcmp(
  * @param snapshot2 Second snapshot
  * @return same as memcmp
  * */
-int mc_snapshot_memcmp(
-  void* addr1, mc_snapshot_t snapshot1,
-  void* addr2, mc_snapshot_t snapshot2, int process_index, size_t size)
+int MC_snapshot_memcmp(
+  const void* addr1, mc_snapshot_t snapshot1,
+  const void* addr2, mc_snapshot_t snapshot2, int process_index, size_t size)
 {
   mc_mem_region_t region1 = mc_get_snapshot_region(addr1, snapshot1, process_index);
   mc_mem_region_t region2 = mc_get_snapshot_region(addr2, snapshot2, process_index);
-  return mc_snapshot_region_memcmp(addr1, region1, addr2, region2, size);
+  return MC_snapshot_region_memcmp(addr1, region1, addr2, region2, size);
 }
 
 #ifdef SIMGRID_TEST
@@ -219,56 +220,56 @@ static void test_snapshot(bool sparse_checkpoint) {
 
     // Init memory and take snapshots:
     init_memory(source, byte_size);
-    mc_mem_region_t region0 = mc_region_new_sparse(0, source, source, byte_size, NULL);
+    mc_mem_region_t region0 = mc_region_new_sparse(MC_REGION_TYPE_UNKNOWN, source, source, byte_size, NULL);
     for(int i=0; i<n; i+=2) {
       init_memory((char*) source + i*xbt_pagesize, xbt_pagesize);
     }
-    mc_mem_region_t region = mc_region_new_sparse(0, source, source, byte_size, NULL);
+    mc_mem_region_t region = mc_region_new_sparse(MC_REGION_TYPE_UNKNOWN, source, source, byte_size, NULL);
 
     void* destination = mmap(NULL, byte_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
     xbt_assert(source!=MAP_FAILED, "Could not allocate destination memory");
 
     xbt_test_add("Reading whole region data for %i page(s)", n);
-    void* read = mc_snapshot_read_region(source, region, destination, byte_size);
-    xbt_test_assert(!memcmp(source, read, byte_size), "Mismatch in mc_snapshot_read_region()");
+    const void* read = MC_region_read(region, source, destination, byte_size);
+    xbt_test_assert(!memcmp(source, read, byte_size), "Mismatch in MC_region_read()");
 
     xbt_test_add("Reading parts of region data for %i page(s)", n);
     for(int j=0; j!=100; ++j) {
       size_t offset = rand() % byte_size;
       size_t size = rand() % (byte_size - offset);
-      void* read = mc_snapshot_read_region((char*) source+offset, region, destination, size);
+      const void* read = MC_region_read(region, destination, (const char*) source+offset, size);
       xbt_test_assert(!memcmp((char*) source+offset, read, size),
-        "Mismatch in mc_snapshot_read_region()");
+        "Mismatch in MC_region_read()");
     }
 
     xbt_test_add("Compare whole region data for %i page(s)", n);
-    xbt_test_assert(!mc_snapshot_region_memcmp(source, NULL, source, region, byte_size),
-      "Mismatch in mc_snapshot_region_memcmp() for the whole region");
-    xbt_test_assert(mc_snapshot_region_memcmp(source, region0, source, region, byte_size),
-      "Unexpected match in mc_snapshot_region_memcmp() with previous snapshot");
+    xbt_test_assert(!MC_snapshot_region_memcmp(source, NULL, source, region, byte_size),
+      "Mismatch in MC_snapshot_region_memcmp() for the whole region");
+    xbt_test_assert(MC_snapshot_region_memcmp(source, region0, source, region, byte_size),
+      "Unexpected match in MC_snapshot_region_memcmp() with previous snapshot");
 
     xbt_test_add("Compare parts of region data for %i page(s) with current value", n);
     for(int j=0; j!=100; ++j) {
       size_t offset = rand() % byte_size;
       size_t size = rand() % (byte_size - offset);
-      xbt_test_assert(!mc_snapshot_region_memcmp((char*) source+offset, NULL, (char*) source+offset, region, size),
-        "Mismatch in mc_snapshot_region_memcmp()");
+      xbt_test_assert(!MC_snapshot_region_memcmp((char*) source+offset, NULL, (char*) source+offset, region, size),
+        "Mismatch in MC_snapshot_region_memcmp()");
     }
 
     xbt_test_add("Compare parts of region data for %i page(s) with itself", n);
     for(int j=0; j!=100; ++j) {
       size_t offset = rand() % byte_size;
       size_t size = rand() % (byte_size - offset);
-      xbt_test_assert(!mc_snapshot_region_memcmp((char*) source+offset, region, (char*) source+offset, region, size),
-        "Mismatch in mc_snapshot_region_memcmp()");
+      xbt_test_assert(!MC_snapshot_region_memcmp((char*) source+offset, region, (char*) source+offset, region, size),
+        "Mismatch in MC_snapshot_region_memcmp()");
     }
 
     if (n==1) {
       xbt_test_add("Read pointer for %i page(s)", n);
       memcpy(source, &mc_model_checker, sizeof(void*));
-      mc_mem_region_t region2 = mc_region_new_sparse(0, source, source, byte_size, NULL);
-      xbt_test_assert(mc_snapshot_read_pointer_region(source, region2) == mc_model_checker,
-        "Mismtach in mc_snapshot_read_pointer_region()");
+      mc_mem_region_t region2 = mc_region_new_sparse(MC_REGION_TYPE_UNKNOWN, source, source, byte_size, NULL);
+      xbt_test_assert(MC_region_read_pointer(region2, source) == mc_model_checker,
+        "Mismtach in MC_region_read_pointer()");
       MC_region_destroy(region2);
     }
 
index 1d0f9b0..70b37f8 100644 (file)
@@ -19,6 +19,8 @@
 #include "mc_model_checker.h"
 #include "mc_page_store.h"
 #include "mc_mmalloc.h"
+#include "mc_address_space.h"
+#include "mc_unw.h"
 
 SG_BEGIN_DECL()
 
@@ -26,21 +28,49 @@ void mc_softdirty_reset(void);
 
 // ***** Snapshot region
 
-#define NB_REGIONS 3 /* binary data (data + BSS) (type = 2), libsimgrid data (data + BSS) (type = 1), std_heap (type = 0)*/
+typedef enum e_mc_region_type_t {
+  MC_REGION_TYPE_UNKNOWN = 0,
+  MC_REGION_TYPE_HEAP = 1,
+  MC_REGION_TYPE_DATA = 2
+} mc_region_type_t;
+
+// TODO, use OO instead of this
+typedef enum e_mc_region_storeage_type_t {
+  MC_REGION_STORAGE_TYPE_NONE = 0,
+  MC_REGION_STORAGE_TYPE_FLAT = 1,
+  MC_REGION_STORAGE_TYPE_CHUNKED = 2,
+  MC_REGION_STORAGE_TYPE_PRIVATIZED = 3
+} mc_region_storage_type_t;
 
 /** @brief Copy/snapshot of a given memory region
  *
- *  Two types of region snapshots exist:
+ *  Different types of region snapshot storage types exist:
  *  <ul>
  *    <li>flat/dense snapshots are a simple copy of the region;</li>
  *    <li>sparse/per-page snapshots are snaapshots which shared
  *    identical pages.</li>
+ *    <li>privatized (SMPI global variable privatisation).
  *  </ul>
+ *
+ *  This is handled with a variant based approch:
+ *
+ *    * `storage_type` identified the type of storage;
+ *    * an anonymous enum is used to distinguish the relevant types for
+ *      each type.
  */
-typedef struct s_mc_mem_region{
+typedef struct s_mc_mem_region s_mc_mem_region_t, *mc_mem_region_t;
+
+struct s_mc_mem_region {
+  mc_region_type_t region_type;
+  mc_region_storage_type_t storage_type;
+  mc_object_info_t object_info;
+
   /** @brief  Virtual address of the region in the simulated process */
   void *start_addr;
 
+  /** @brief Size of the data region in bytes */
+  size_t size;
+
   /** @brief Permanent virtual address of the region
    *
    * This is usually the same address as the simuilated process address.
@@ -52,23 +82,29 @@ typedef struct s_mc_mem_region{
    * */
   void *permanent_addr;
 
-  /** @brief Copy of the snapshot for flat snapshots regions (NULL otherwise) */
-  void *data;
+  union {
+    struct {
+      /** @brief Copy of the snapshot for flat snapshots regions (NULL otherwise) */
+      void *data;
+    } flat;
+    struct {
+      /** @brief Pages indices in the page store for per-page snapshots (NULL otherwise) */
+      size_t* page_numbers;
+    } chunked;
+    struct {
+      size_t regions_count;
+      mc_mem_region_t* regions;
+    } privatized;
+  };
 
-  /** @brief Size of the data region in bytes */
-  size_t size;
-
-  /** @brief Pages indices in the page store for per-page snapshots (NULL otherwise) */
-  size_t* page_numbers;
-
-} s_mc_mem_region_t, *mc_mem_region_t;
+};
 
-mc_mem_region_t mc_region_new_sparse(int type, void *start_addr, void* data_addr, size_t size, mc_mem_region_t ref_reg);
+mc_mem_region_t mc_region_new_sparse(mc_region_type_t type, void *start_addr, void* data_addr, size_t size, mc_mem_region_t ref_reg);
 void MC_region_destroy(mc_mem_region_t reg);
-void mc_region_restore_sparse(mc_mem_region_t reg, mc_mem_region_t ref_reg);
+void mc_region_restore_sparse(mc_process_t process, mc_mem_region_t reg, mc_mem_region_t ref_reg);
 
 static inline  __attribute__ ((always_inline))
-bool mc_region_contain(mc_mem_region_t region, void* p)
+bool mc_region_contain(mc_mem_region_t region, const void* p)
 {
   return p >= region->start_addr &&
     p < (void*)((char*) region->start_addr + region->size);
@@ -78,12 +114,12 @@ static inline __attribute__((always_inline))
 void* mc_translate_address_region(uintptr_t addr, mc_mem_region_t region)
 {
     size_t pageno = mc_page_number(region->start_addr, (void*) addr);
-    size_t snapshot_pageno = region->page_numbers[pageno];
+    size_t snapshot_pageno = region->chunked.page_numbers[pageno];
     const void* snapshot_page = mc_page_store_get_page(mc_model_checker->pages, snapshot_pageno);
     return (char*) snapshot_page + mc_page_offset((void*) addr);
 }
 
-mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot, int process_index);
+mc_mem_region_t mc_get_snapshot_region(const void* addr, mc_snapshot_t snapshot, int process_index);
 
 /** \brief Translate a pointer from process address space to snapshot address space
  *
@@ -115,19 +151,30 @@ void* mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot, int process_i
     return (void *) addr;
   }
 
-  // Flat snapshot:
-  else if (region->data) {
-    uintptr_t offset = addr - (uintptr_t) region->start_addr;
-    return (void *) ((uintptr_t) region->data + offset);
-  }
+  switch (region->storage_type) {
+  case MC_REGION_STORAGE_TYPE_NONE:
+  default:
+    xbt_die("Storage type not supported");
+
+  case MC_REGION_STORAGE_TYPE_FLAT:
+    {
+      uintptr_t offset = addr - (uintptr_t) region->start_addr;
+      return (void *) ((uintptr_t) region->flat.data + offset);
+    }
 
-  // Per-page snapshot:
-  else if (region->page_numbers) {
+  case MC_REGION_STORAGE_TYPE_CHUNKED:
     return mc_translate_address_region(addr, region);
-  }
 
-  else {
-    xbt_die("No data for this memory region");
+  case MC_REGION_STORAGE_TYPE_PRIVATIZED:
+    {
+      xbt_assert(process_index >=0,
+        "Missing process index for privatized region");
+      xbt_assert((size_t) process_index < region->privatized.regions_count,
+        "Out of range process index");
+      mc_mem_region_t subregion = region->privatized.regions[process_index];
+      xbt_assert(subregion, "Missing memory region for process %i", process_index);
+      return mc_translate_address(addr, snapshot, process_index);
+    }
   }
 }
 
@@ -151,11 +198,13 @@ typedef struct s_fd_infos{
   int flags;
 }s_fd_infos_t, *fd_infos_t;
 
-struct s_mc_snapshot{
+struct s_mc_snapshot {
+  mc_process_t process;
+  s_mc_address_space_t address_space;
   size_t heap_bytes_used;
-  mc_mem_region_t regions[NB_REGIONS];
+  mc_mem_region_t* snapshot_regions;
+  size_t snapshot_regions_count;
   xbt_dynar_t enabled_processes;
-  mc_mem_region_t* privatization_regions;
   int privatization_index;
   size_t *stack_sizes;
   xbt_dynar_t stacks;
@@ -166,18 +215,6 @@ struct s_mc_snapshot{
   fd_infos_t *current_fd;
 };
 
-/** @brief Process index used when no process is available
- *
- *  The expected behaviour is that if a process index is needed it will fail.
- * */
-#define MC_NO_PROCESS_INDEX -1
-
-/** @brief Process index when any process is suitable
- *
- * We could use a special negative value in the future.
- */
-#define MC_ANY_PROCESS_INDEX 0
-
 static inline __attribute__ ((always_inline))
 mc_mem_region_t mc_get_region_hinted(void* addr, mc_snapshot_t snapshot, int process_index, mc_mem_region_t region)
 {
@@ -203,11 +240,12 @@ typedef struct s_mc_stack_frame {
 
 typedef struct s_mc_snapshot_stack{
   xbt_dynar_t local_variables;
+  mc_unw_context_t context;
   xbt_dynar_t stack_frames; // mc_stack_frame_t
   int process_index;
 }s_mc_snapshot_stack_t, *mc_snapshot_stack_t;
 
-typedef struct s_mc_global_t{
+typedef struct s_mc_global_t {
   mc_snapshot_t snapshot;
   int raw_mem_set;
   int prev_pair;
@@ -222,7 +260,7 @@ typedef struct s_mc_checkpoint_ignore_region{
   size_t size;
 }s_mc_checkpoint_ignore_region_t, *mc_checkpoint_ignore_region_t;
 
-static void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot);
+static const void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot);
 
 mc_snapshot_t MC_take_snapshot(int num_state);
 void MC_restore_snapshot(mc_snapshot_t);
@@ -230,40 +268,42 @@ void MC_free_snapshot(mc_snapshot_t);
 
 int mc_important_snapshot(mc_snapshot_t snapshot);
 
-size_t* mc_take_page_snapshot_region(void* data, size_t page_count, uint64_t* pagemap, size_t* reference_pages);
+size_t* mc_take_page_snapshot_region(mc_process_t process,
+  void* data, size_t page_count, uint64_t* pagemap, size_t* reference_pages);
 void mc_free_page_snapshot_region(size_t* pagenos, size_t page_count);
-void mc_restore_page_snapshot_region(void* start_addr, size_t page_count, size_t* pagenos, uint64_t* pagemap, size_t* reference_pagenos);
-
-static inline __attribute__((always_inline))
-bool mc_snapshot_region_linear(mc_mem_region_t region) {
-  return !region || !region->data;
-}
-
-void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* target, size_t size);
-
-void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, int process_index, void* target, size_t size);
-int mc_snapshot_region_memcmp(
-  void* addr1, mc_mem_region_t region1,
-  void* addr2, mc_mem_region_t region2, size_t size);
-int mc_snapshot_memcmp(
-  void* addr1, mc_snapshot_t snapshot1,
-  void* addr2, mc_snapshot_t snapshot2, int process_index, size_t size);
-
-static void* mc_snapshot_read_pointer(void* addr, mc_snapshot_t snapshot, int process_index);
+void mc_restore_page_snapshot_region(
+  mc_process_t process,
+  void* start_addr, size_t page_count, size_t* pagenos,
+  uint64_t* pagemap, size_t* reference_pagenos);
+
+const void* MC_region_read_fragmented(mc_mem_region_t region, void* target, const void* addr, size_t size);
+
+const void* MC_snapshot_read(mc_snapshot_t snapshot, e_adress_space_read_flags_t flags,
+  void* target, const void* addr, size_t size, int process_index);
+int MC_snapshot_region_memcmp(
+  const void* addr1, mc_mem_region_t region1,
+  const void* addr2, mc_mem_region_t region2, size_t size);
+int MC_snapshot_memcmp(
+  const void* addr1, mc_snapshot_t snapshot1,
+  const void* addr2, mc_snapshot_t snapshot2, int process_index, size_t size);
 
 static inline __attribute__ ((always_inline))
-void* mc_snapshot_read_pointer(void* addr, mc_snapshot_t snapshot, int process_index)
+const void* MC_snapshot_read_pointer(mc_snapshot_t snapshot, const void* addr, int process_index)
 {
   void* res;
-  return *(void**) mc_snapshot_read(addr, snapshot, process_index, &res, sizeof(void*));
+  return *(const void**) MC_snapshot_read(snapshot, MC_ADDRESS_SPACE_READ_FLAGS_LAZY,
+    &res, addr, sizeof(void*), process_index);
 }
 
 static inline __attribute__ ((always_inline))
-  void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot) {
+const void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot)
+{
   if(snapshot==NULL)
       xbt_die("snapshot is NULL");
-  void** addr = &(std_heap->breakval);
-  return mc_snapshot_read_pointer(addr, snapshot, MC_ANY_PROCESS_INDEX);
+  // This is &std_heap->breakval in the target process:
+  void** addr = &MC_process_get_heap(&mc_model_checker->process)->breakval;
+  // Read (std_heap->breakval) in the target process (*addr i.e. std_heap->breakval):
+  return MC_snapshot_read_pointer(snapshot, addr, MC_PROCESS_INDEX_ANY);
 }
 
 /** @brief Read memory from a snapshot region
@@ -275,9 +315,10 @@ static inline __attribute__ ((always_inline))
  *  @return Pointer where the data is located (target buffer of original location)
  */
 static inline __attribute__((always_inline))
-void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target, size_t size)
+const void* MC_region_read(mc_mem_region_t region, void* target, const void* addr, size_t size)
 {
   if (region==NULL)
+    // Should be deprecated:
     return addr;
 
   uintptr_t offset = (char*) addr - (char*) region->start_addr;
@@ -285,34 +326,39 @@ void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target,
   xbt_assert(mc_region_contain(region, addr),
     "Trying to read out of the region boundary.");
 
-  // Linear memory region:
-  if (region->data) {
-    return (char*) region->data + offset;
-  }
-
-  // Fragmented memory region:
-  else if (region->page_numbers) {
-    // Last byte of the region:
-    void* end = (char*) addr + size - 1;
-    if( mc_same_page(addr, end) ) {
-      // The memory is contained in a single page:
-      return mc_translate_address_region((uintptr_t) addr, region);
-    } else {
-      // The memory spans several pages:
-      return mc_snapshot_read_fragmented(addr, region, target, size);
+  switch (region->storage_type) {
+  case MC_REGION_STORAGE_TYPE_NONE:
+  default:
+    xbt_die("Storage type not supported");
+
+  case MC_REGION_STORAGE_TYPE_FLAT:
+    return (char*) region->flat.data + offset;
+
+  case MC_REGION_STORAGE_TYPE_CHUNKED:
+    {
+      // Last byte of the region:
+      void* end = (char*) addr + size - 1;
+      if (mc_same_page(addr, end) ) {
+        // The memory is contained in a single page:
+        return mc_translate_address_region((uintptr_t) addr, region);
+      } else {
+        // The memory spans several pages:
+        return MC_region_read_fragmented(region, target, addr, size);
+      }
     }
-  }
 
-  else {
-    xbt_die("No data available for this region");
+  // We currently do not pass the process_index to this function so we assume
+  // that the privatized region has been resolved in the callers:
+  case MC_REGION_STORAGE_TYPE_PRIVATIZED:
+    xbt_die("Storage type not supported");
   }
 }
 
 static inline __attribute__ ((always_inline))
-void* mc_snapshot_read_pointer_region(void* addr, mc_mem_region_t region)
+void* MC_region_read_pointer(mc_mem_region_t region, const void* addr)
 {
   void* res;
-  return *(void**) mc_snapshot_read_region(addr, region, &res, sizeof(void*));
+  return *(void**) MC_region_read(region, &res, addr, sizeof(void*));
 }
 
 SG_END_DECL()
diff --git a/src/mc/mc_unw.c b/src/mc/mc_unw.c
new file mode 100644 (file)
index 0000000..ee67176
--- /dev/null
@@ -0,0 +1,238 @@
+/* Copyright (c) 2015. 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. */
+
+/** \file
+ *  Libunwind support for mc_address_space objects.
+ */
+
+// We need this for the register indices:
+#define _GNU_SOURCE
+
+#include <string.h>
+
+// On x86_64, libunwind unw_context_t has the same layout as ucontext_t:
+#include <sys/ucontext.h>
+
+#include <libunwind.h>
+
+#include "mc_object_info.h"
+#include "mc_process.h"
+#include "mc_unw.h"
+
+// ***** Implementation
+
+/** Get frame unwind information (libunwind method)
+ *
+ *  Delegates to the local/ptrace implementation.
+ */
+static int find_proc_info(unw_addr_space_t as,
+              unw_word_t ip, unw_proc_info_t *pip,
+              int need_unwind_info, void* arg)
+{
+  mc_unw_context_t context = (mc_unw_context_t) arg;
+  return unw_get_accessors(context->process->unw_underlying_addr_space)->find_proc_info(
+    context->process->unw_underlying_addr_space, ip, pip,
+    need_unwind_info, context->process->unw_underlying_context
+  );
+}
+
+/** Release frame unwind information (libunwind method)
+ *
+ *  Delegates to the local/ptrace implementation.
+ */
+static void put_unwind_info(unw_addr_space_t as,
+              unw_proc_info_t *pip, void* arg)
+{
+  mc_unw_context_t context = (mc_unw_context_t) arg;
+  return unw_get_accessors(context->process->unw_underlying_addr_space)->put_unwind_info(
+    context->process->unw_underlying_addr_space, pip,
+    context->process->unw_underlying_context
+  );
+}
+
+/** (libunwind method)
+ *
+ *  Not implemented.
+ */
+static int get_dyn_info_list_addr(unw_addr_space_t as,
+              unw_word_t *dilap, void* arg)
+{
+  mc_unw_context_t context = (mc_unw_context_t) arg;
+  return unw_get_accessors(context->process->unw_underlying_addr_space)->get_dyn_info_list_addr(
+    context->process->unw_underlying_addr_space,
+    dilap,
+    context->process->unw_underlying_context
+  );
+}
+
+/** Read from the target address space memory (libunwind method)
+ *
+ *  Delegates to the `mc_process_t`.
+ */
+static int access_mem(unw_addr_space_t as,
+              unw_word_t addr, unw_word_t *valp,
+              int write, void* arg)
+{
+  mc_unw_context_t context = (mc_unw_context_t) arg;
+  if (write)
+    return -UNW_EREADONLYREG;
+  MC_address_space_read(context->address_space,
+    0, valp, (void*) addr, sizeof(unw_word_t), MC_PROCESS_INDEX_ANY);
+  // We don't handle failure gracefully.
+  return 0;
+}
+
+static void* get_reg(unw_context_t* context, unw_regnum_t regnum)
+{
+#ifdef __x86_64
+  mcontext_t* mcontext = &context->uc_mcontext;
+  switch (regnum) {
+  case UNW_X86_64_RAX: return &mcontext->gregs[REG_RAX];
+  case UNW_X86_64_RDX: return &mcontext->gregs[REG_RDX];
+  case UNW_X86_64_RCX: return &mcontext->gregs[REG_RCX];
+  case UNW_X86_64_RBX: return &mcontext->gregs[REG_RBX];
+  case UNW_X86_64_RSI: return &mcontext->gregs[REG_RSI];
+  case UNW_X86_64_RDI: return &mcontext->gregs[REG_RDI];
+  case UNW_X86_64_RBP: return &mcontext->gregs[REG_RBP];
+  case UNW_X86_64_RSP: return &mcontext->gregs[REG_RSP];
+  case UNW_X86_64_R8:  return &mcontext->gregs[REG_R8];
+  case UNW_X86_64_R9:  return &mcontext->gregs[REG_R9];
+  case UNW_X86_64_R10: return &mcontext->gregs[REG_R10];
+  case UNW_X86_64_R11: return &mcontext->gregs[REG_R11];
+  case UNW_X86_64_R12: return &mcontext->gregs[REG_R12];
+  case UNW_X86_64_R13: return &mcontext->gregs[REG_R13];
+  case UNW_X86_64_R14: return &mcontext->gregs[REG_R14];
+  case UNW_X86_64_R15: return &mcontext->gregs[REG_R15];
+  case UNW_X86_64_RIP: return &mcontext->gregs[REG_RIP];
+  default: return NULL;
+  }
+#else
+  return NULL;
+#endif
+}
+
+/** Read a standard register (libunwind method)
+ */
+static int access_reg(unw_addr_space_t as,
+              unw_regnum_t regnum, unw_word_t *valp,
+              int write, void* arg)
+{
+  mc_unw_context_t as_context = (mc_unw_context_t) arg;
+  unw_context_t* context = &as_context->context;
+  if (write)
+    return -UNW_EREADONLYREG;
+  greg_t* preg = get_reg(context, regnum);
+  if (!preg)
+    return -UNW_EBADREG;
+  *valp = *preg;
+  return 0;
+}
+
+/** Read a floating-point register (libunwind method)
+ *
+ *  FP registers are caller-saved. The values saved by functions such as
+ *  `getcontext()` is not relevant for the caller. It is not really necessary
+ *  to save and handle them.
+ */
+static int access_fpreg(unw_addr_space_t as,
+              unw_regnum_t regnum, unw_fpreg_t *fpvalp,
+              int write, void* arg)
+{
+  return -UNW_EBADREG;
+}
+
+/** Resume the execution of the context (libunwind method)
+ *
+ * We don't use this.
+ */
+static int resume(unw_addr_space_t as,
+              unw_cursor_t *cp, void* arg)
+{
+  return -UNW_EUNSPEC;
+}
+
+/** Find informations about a function (libunwind method)
+ */
+static int get_proc_name(unw_addr_space_t as,
+              unw_word_t addr, char *bufp,
+              size_t buf_len, unw_word_t *offp,
+              void* arg)
+{
+  mc_unw_context_t context = (mc_unw_context_t) arg;
+  dw_frame_t frame = MC_process_find_function(context->process, (void*) addr);
+  if (!frame)
+    return - UNW_ENOINFO;
+  *offp = (unw_word_t) frame->low_pc - addr;
+
+  strncpy(bufp, frame->name, buf_len);
+  if (bufp[buf_len - 1]) {
+    bufp[buf_len - 1] = 0;
+    return -UNW_ENOMEM;
+  }
+
+  return 0;
+}
+
+// ***** Init
+
+unw_accessors_t mc_unw_accessors =
+  {
+    .find_proc_info             = &find_proc_info,
+    .put_unwind_info            = &put_unwind_info,
+    .get_dyn_info_list_addr     = &get_dyn_info_list_addr,
+    .access_mem                 = &access_mem,
+    .access_reg                 = &access_reg,
+    .access_fpreg               = &access_fpreg,
+    .resume                     = &resume,
+    .get_proc_name              = &get_proc_name
+  };
+
+// ***** Context management
+
+int mc_unw_init_context(
+  mc_unw_context_t context, mc_process_t process, unw_context_t* c)
+{
+  context->address_space = (mc_address_space_t) process;
+  context->process = process;
+
+  // Take a copy of the context for our own purpose:
+  context->context = *c;
+#if defined(PROCESSOR_x86_64) || defined(PROCESSOR_i686)
+  // On x86_64, ucontext_t contains a pointer to itself for FP registers.
+  // We don't really need support for FR registers as they are caller saved
+  // and probably never use those fields as libunwind-x86_64 does not read
+  // FP registers from the unw_context_t
+  // but we fix the pointer in order to avoid dangling pointers:
+  context->context.uc_mcontext.fpregs = &(context->context.__fpregs_mem);
+#else
+  // Do we need to do any fixup like this?
+  #error Target CPU type is not handled.
+#endif
+
+  return 0;
+}
+
+int mc_unw_destroy_context(mc_unw_context_t context)
+{
+  context->address_space = NULL;
+  context->process = NULL;
+  return 0;
+}
+
+// ***** Cursor management
+
+int mc_unw_init_cursor(unw_cursor_t *cursor, mc_unw_context_t context)
+{
+  if (!context->process || !context->address_space)
+    return -UNW_EUNSPEC;
+  mc_address_space_t as = context->address_space;
+
+  // Use local unwinding for current process:
+  if (MC_is_process(as) && MC_process_is_self((mc_process_t) as))
+    return unw_init_local(cursor, &context->context);
+
+  return unw_init_remote(cursor, context->process->unw_addr_space, context);
+}
diff --git a/src/mc/mc_unw.h b/src/mc/mc_unw.h
new file mode 100644 (file)
index 0000000..267c850
--- /dev/null
@@ -0,0 +1,82 @@
+/* Copyright (c) 2015. 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. */
+
+#ifndef MC_UNW_H
+#define MC_UNW_H
+
+/** \file
+ *  Libunwind implementation for the model-checker
+ *
+ *  Libunwind provides an pluggable stack unwinding API: the way the current
+ *  registers and memory is accessed, the way unwinding informations is found
+ *  is pluggable.
+ *
+ *  This component implements the libunwind API for he model-checker:
+ *
+ *    * reading memory from a mc_address_space_t;
+ *
+ *    * reading stack registers from a saved snapshot (context).
+ *
+ *  Parts of the libunwind information fetching is currently handled by the
+ *  standard `libunwind` implementations (either the local one or the ptrace one)
+ *  because parsing `.eh_frame` section is not fun and `libdw` does not help
+ *  much here.
+ */
+
+#include "mc_process.h"
+
+SG_BEGIN_DECL()
+
+// ***** Libunwind namespace
+
+/** Virtual table for our `libunwind-process_vm_readv` implementation.
+ *
+ *  This implementation reuse most the code of `libunwind-ptrace` but
+ *  does not use ptrace() to read the target process memory by
+ *  `process_vm_readv()` or `/dev/${pid}/mem` if possible.
+ *
+ *  Does not support any MC-specific behaviour (privatisation, snapshots)
+ *  and `ucontext_t`.
+ *
+ *  It works with `void*` contexts allocated with `_UPT_create(pid)`.
+ */
+extern unw_accessors_t mc_unw_vmread_accessors;
+
+/** Virtual table for our `libunwind` implementation
+ *
+ *  Stack unwinding on a `mc_process_t` (for memory, unwinding information)
+ *  and `ucontext_t` (for processor registers).
+ *
+ *  It works with the `s_mc_unw_context_t` context.
+ */
+extern unw_accessors_t mc_unw_accessors;
+
+// ***** Libunwind context
+
+/** A `libunwind` context
+ */
+typedef struct s_mc_unw_context {
+  mc_address_space_t address_space;
+  mc_process_t       process;
+  unw_context_t      context;
+} s_mc_unw_context_t, *mc_unw_context_t;
+
+/** Initialises an already allocated context */
+int mc_unw_init_context(
+  mc_unw_context_t context, mc_process_t process, unw_context_t* c);
+
+/** Destroys (but not not `free`) a context */
+int mc_unw_destroy_context(mc_unw_context_t context);
+
+// ***** Libunwind cursor
+
+/** Initialises a `libunwind` cursor */
+int mc_unw_init_cursor(unw_cursor_t *cursor, mc_unw_context_t context);
+
+SG_END_DECL()
+
+#endif
diff --git a/src/mc/mc_unw_vmread.c b/src/mc/mc_unw_vmread.c
new file mode 100644 (file)
index 0000000..742359e
--- /dev/null
@@ -0,0 +1,108 @@
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include <libunwind.h>
+#include <libunwind-ptrace.h>
+
+#include "mc_unw.h"
+
+/** \file
+ *  Libunwind namespace implementation using process_vm_readv.
+ *.
+ *  This implem
+ */
+
+/** Partial structure of libunwind-ptrace context in order to get the PID
+ *
+ *  The context type for libunwind-race is an opaque type. We need to get the
+ *  PID which is the first field. This is a hack which might break if the
+ *  libunwind-ptrace structure changes.
+ */
+struct _UPT_info {
+  pid_t pid;
+  // Other things;
+};
+
+/** Get the PID of a `libunwind-ptrace` context
+ */
+static inline
+pid_t _UPT_getpid(void* arg)
+{
+  struct _UPT_info* info = arg;
+  return info->pid;
+}
+
+/** Read from the memory, avoid using `ptrace` (libunwind method)
+ */
+static int access_mem(const unw_addr_space_t as,
+              const unw_word_t addr, unw_word_t* const  valp,
+              const int write, void* const arg)
+{
+  if (write)
+    return - UNW_EINVAL;
+  ssize_t s;
+  pid_t pid = _UPT_getpid(arg);
+  size_t size = sizeof(unw_word_t);
+
+#ifdef HAVE_PROCESS_VM_READV
+  // process_vm_read implementation.
+  // This is only available since Linux 3.2.
+
+  struct iovec local = { valp, size };
+  struct iovec remote = { (void*) addr, size };
+  s = process_vm_readv(pid, &local, 1, &remote, 1, 0);
+  if (s >= 0) {
+    if (s != size)
+      return - UNW_EINVAL;
+    else
+      return 0;
+  }
+  if (s < 0 && errno != ENOSYS)
+    return - UNW_EINVAL;
+#endif
+
+  // /proc/${pid}/mem implementation.
+  // On recent kernels, we do not need to ptrace the target process.
+  // On older kernels, it is necessary to ptrace the target process.
+  size_t count = size;
+  off_t off = (off_t) addr;
+  char* buf = (char*) valp;
+  int fd = MC_process_vm_open(pid, O_RDONLY);
+  if (fd < 0)
+    return - UNW_EINVAL;
+  while (1) {
+    ssize_t s = pread(fd, buf, count, off);
+    if (s == 0) {
+      close(fd);
+      return - UNW_EINVAL;
+    }
+    if (s == -1)
+      break;
+    count -= s;
+    buf += s;
+    off += s;
+    if (count == 0) {
+      close(fd);
+      return 0;
+    }
+  }
+  close(fd);
+
+  // ptrace implementation.
+  // We need to have PTRACE_ATTACH-ed it before.
+  return _UPT_access_mem(as, addr, valp, write, arg);
+}
+
+unw_accessors_t mc_unw_vmread_accessors =
+  {
+    .find_proc_info             = &_UPT_find_proc_info,
+    .put_unwind_info            = &_UPT_put_unwind_info,
+    .get_dyn_info_list_addr     = &_UPT_get_dyn_info_list_addr,
+    .access_mem                 = &access_mem,
+    .access_reg                 = &_UPT_access_reg,
+    .access_fpreg               = &_UPT_access_fpreg,
+    .resume                     = &_UPT_resume,
+    .get_proc_name              = &_UPT_get_proc_name
+  };
index f792c80..77548d8 100644 (file)
@@ -51,9 +51,12 @@ void visited_state_free_voidp(void *s)
  */
 static mc_visited_state_t visited_state_new()
 {
+  mc_process_t process = &(mc_model_checker->process);
   mc_visited_state_t new_state = NULL;
   new_state = xbt_new0(s_mc_visited_state_t, 1);
-  new_state->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
+  new_state->heap_bytes_used = mmalloc_get_bytes_used_remote(
+    MC_process_get_heap(process)->heaplimit,
+    MC_process_get_malloc_info(process));
   new_state->nb_processes = xbt_swag_size(simix_global->process_list);
   new_state->system_state = MC_take_snapshot(mc_stats->expanded_states);
   new_state->num = mc_stats->expanded_states;
@@ -63,12 +66,15 @@ static mc_visited_state_t visited_state_new()
 
 mc_visited_pair_t MC_visited_pair_new(int pair_num, xbt_automaton_state_t automaton_state, xbt_dynar_t atomic_propositions, mc_state_t graph_state)
 {
+  mc_process_t process = &(mc_model_checker->process);
   mc_visited_pair_t pair = NULL;
   pair = xbt_new0(s_mc_visited_pair_t, 1);
   pair->graph_state = graph_state;
   if(pair->graph_state->system_state == NULL)
     pair->graph_state->system_state = MC_take_snapshot(pair_num);
-  pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
+  pair->heap_bytes_used = mmalloc_get_bytes_used_remote(
+    MC_process_get_heap(process)->heaplimit,
+    MC_process_get_malloc_info(process));
   pair->nb_processes = xbt_swag_size(simix_global->process_list);
   pair->automaton_state = automaton_state;
   pair->num = pair_num;
@@ -125,9 +131,7 @@ void MC_visited_pair_delete(mc_visited_pair_t p)
 int get_search_interval(xbt_dynar_t list, void *ref, int *min, int *max)
 {
 
-  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   int cursor = 0, previous_cursor, next_cursor;
   int nb_processes, heap_bytes_used, nb_processes_test, heap_bytes_used_test;
@@ -198,16 +202,13 @@ int get_search_interval(xbt_dynar_t list, void *ref, int *min, int *max)
           *max = next_cursor;
           next_cursor++;
         }
-        if (!mc_mem_set)
-          MC_SET_STD_HEAP;
+        mmalloc_set_current_heap(heap);
         return -1;
       }
     }
   }
 
-  if (!mc_mem_set)
-    MC_SET_STD_HEAP;
-
+  mmalloc_set_current_heap(heap);
   return cursor;
 }
 
@@ -239,9 +240,7 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
     }
   }
 
-  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   mc_visited_state_t new_state = visited_state_new();
   graph_state->system_state = new_state->system_state;
@@ -251,10 +250,7 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
   if (xbt_dynar_is_empty(visited_states)) {
 
     xbt_dynar_push(visited_states, &new_state);
-
-    if (!mc_mem_set)
-      MC_SET_STD_HEAP;
-
+    mmalloc_set_current_heap(heap);
     return NULL;
 
   } else {
@@ -311,8 +307,7 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
             xbt_dynar_insert_at(visited_states, cursor, &new_state);
             XBT_DEBUG("Replace visited state %d with the new visited state %d", state_test->num, new_state->num);
 
-            if (!mc_mem_set)
-              MC_SET_STD_HEAP;
+            mmalloc_set_current_heap(heap);
             return state_test;
           }
           cursor++;
@@ -360,11 +355,8 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
       XBT_DEBUG("Remove visited state (maximum number of stored states reached)");
     }
 
-    if (!mc_mem_set)
-      MC_SET_STD_HEAP;
-
+    mmalloc_set_current_heap(heap);
     return NULL;
-
   }
 }
 
@@ -376,9 +368,7 @@ int is_visited_pair(mc_visited_pair_t visited_pair, mc_pair_t pair) {
   if (_sg_mc_visited == 0)
     return -1;
 
-  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
-
-  MC_SET_MC_HEAP;
+  xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
 
   mc_visited_pair_t new_visited_pair = NULL;
 
@@ -452,8 +442,7 @@ int is_visited_pair(mc_visited_pair_t visited_pair, mc_pair_t pair) {
               } else {
                 MC_visited_pair_delete(pair_test);
               }
-              if (!mc_mem_set)
-                MC_SET_STD_HEAP;
+              mmalloc_set_current_heap(heap);
               return new_visited_pair->other_num;
             }
           }
@@ -495,8 +484,6 @@ int is_visited_pair(mc_visited_pair_t visited_pair, mc_pair_t pair) {
 
   }
 
-  if (!mc_mem_set)
-    MC_SET_STD_HEAP;
-
+  mmalloc_set_current_heap(heap);
   return -1;
 }
index b867a86..337ed9d 100644 (file)
@@ -4,41 +4,35 @@
 /* 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 <stdlib.h>
+
+#include <sys/types.h>
+
 #include "mc_memory_map.h"
 #include "mc_private.h"
-#include <stdlib.h>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_memory_map, mc,
                                 "Logging specific to algorithms for memory_map");
 
-memory_map_t MC_get_memory_map(void)
+memory_map_t MC_get_memory_map(pid_t pid)
 {
-  FILE *fp;                     /* File pointer to process's proc maps file */
-  char *line = NULL;            /* Temporal storage for each line that is readed */
-  ssize_t read;                 /* Number of bytes readed */
-  size_t n = 0;                 /* Amount of bytes to read by xbt_getline */
-  memory_map_t ret = NULL;      /* The memory map to return */
-
-/* The following variables are used during the parsing of the file "maps" */
-  s_map_region_t memreg;          /* temporal map region used for creating the map */
-  char *lfields[6], *tok, *endptr;
-  int i;
-
-/* Open the actual process's proc maps file and create the memory_map_t */
-/* to be returned. */
-  fp = fopen("/proc/self/maps", "r");
-
+  /* Open the actual process's proc maps file and create the memory_map_t */
+  /* to be returned. */
+  char* path = bprintf("/proc/%i/maps", (int) pid);
+  FILE *fp = fopen(path, "r");
+  free(path);
   if(fp == NULL)
     perror("fopen failed");
-
   xbt_assert(fp,
-              "Cannot open /proc/self/maps to investigate the memory map of the process. Please report this bug.");
-
+    "Cannot open %s to investigate the memory map of the process.", path);
   setbuf(fp, NULL);
 
-  ret = xbt_new0(s_memory_map_t, 1);
+  memory_map_t ret = xbt_new0(s_memory_map_t, 1);
 
   /* Read one line at the time, parse it and add it to the memory map to be returned */
+  ssize_t read; /* Number of bytes readed */
+  char* line = NULL;
+  size_t n = 0; /* Amount of bytes to read by xbt_getline */
   while ((read = xbt_getline(&line, &n, fp)) != -1) {
 
     //fprintf(stderr,"%s", line);
@@ -48,8 +42,10 @@ memory_map_t MC_get_memory_map(void)
 
     /* Tokenize the line using spaces as delimiters and store each token */
     /* in lfields array. We expect 5 tokens/fields */
+    char* lfields[6];
     lfields[0] = strtok(line, " ");
 
+    int i;
     for (i = 1; i < 6 && lfields[i - 1] != NULL; i++) {
       lfields[i] = strtok(NULL, " ");
     }
@@ -60,10 +56,12 @@ memory_map_t MC_get_memory_map(void)
 
     /* Ok we are good enough to try to get the info we need */
     /* First get the start and the end address of the map   */
-    tok = strtok(lfields[0], "-");
+    char *tok = strtok(lfields[0], "-");
     if (tok == NULL)
       xbt_abort();
 
+    s_map_region_t memreg;          /* temporal map region used for creating the map */
+    char *endptr;
     memreg.start_addr = (void *) strtoul(tok, &endptr, 16);
     /* Make sure that the entire string was an hex number */
     if (*endptr != '\0')
@@ -143,6 +141,8 @@ memory_map_t MC_get_memory_map(void)
 
     /* Create space for a new map region in the region's array and copy the */
     /* parsed stuff from the temporal memreg variable */
+    XBT_DEBUG("Found region for %s",
+      memreg.pathname ? memreg.pathname : "(null)");
     ret->regions =
         xbt_realloc(ret->regions, sizeof(memreg) * (ret->mapsize + 1));
     memcpy(ret->regions + ret->mapsize, &memreg, sizeof(memreg));
@@ -151,9 +151,7 @@ memory_map_t MC_get_memory_map(void)
   }
 
   free(line);
-
   fclose(fp);
-
   return ret;
 }
 
diff --git a/src/mc/simgrid_mc.cpp b/src/mc/simgrid_mc.cpp
new file mode 100644 (file)
index 0000000..d121fdb
--- /dev/null
@@ -0,0 +1,154 @@
+/* Copyright (c) 2015. 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 <exception>
+
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+
+#include <signal.h>
+#include <poll.h>
+
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#include <xbt/log.h>
+
+#include "simgrid/sg_config.h"
+#include "xbt_modinter.h"
+
+#include "mc_base.h"
+#include "mc_private.h"
+#include "mc_protocol.h"
+#include "mc_server.h"
+#include "mc_model_checker.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_main, mc, "Entry point for simgrid-mc");
+
+static const bool trace = true;
+
+static int do_child(int socket, char** argv)
+{
+  XBT_DEBUG("Inside the child process PID=%i", (int) getpid());
+  int res;
+
+  // Remove CLOEXEC in order to pass the socket to the exec-ed program:
+  int fdflags = fcntl(socket, F_GETFD, 0);
+  if (fdflags == -1) {
+    std::perror("simgrid-mc");
+    return MC_SERVER_ERROR;
+  }
+  if (fcntl(socket, F_SETFD, fdflags & ~FD_CLOEXEC) == -1) {
+    std::perror("simgrid-mc");
+    return MC_SERVER_ERROR;
+  }
+
+  XBT_DEBUG("CLOEXEC removed on socket %i", socket);
+
+  // Set environment:
+  setenv(MC_ENV_VARIABLE, "1", 1);
+
+  char buffer[64];
+  res = std::snprintf(buffer, sizeof(buffer), "%i", socket);
+  if ((size_t) res >= sizeof(buffer) || res == -1)
+    return MC_SERVER_ERROR;
+  setenv(MC_ENV_SOCKET_FD, buffer, 1);
+
+  execvp(argv[1], argv+1);
+  std::perror("simgrid-mc");
+  return MC_SERVER_ERROR;
+}
+
+static int do_parent(int socket, pid_t child)
+{
+  XBT_DEBUG("Inside the parent process");
+  if (mc_server)
+    xbt_die("MC server already present");
+  try {
+    mc_mode = MC_MODE_SERVER;
+    mc_server = new s_mc_server(child, socket);
+    mc_server->start();
+    MC_init_pid(child, socket);
+    mc_server->resume(&mc_model_checker->process);
+    mc_server->loop();
+    mc_server->shutdown();
+    mc_server->exit();
+  }
+  catch(std::exception& e) {
+    XBT_ERROR(e.what());
+  }
+  exit(MC_SERVER_ERROR);
+}
+
+static char** argvdup(int argc, char** argv)
+{
+  char** argv_copy = xbt_new(char*, argc+1);
+  std::memcpy(argv_copy, argv, sizeof(char*) * argc);
+  argv_copy[argc] = NULL;
+  return argv_copy;
+}
+
+int main(int argc, char** argv)
+{
+  // We need to keep the original parameters in order to pass them to the
+  // model-checked process:
+  int argc_copy = argc;
+  char** argv_copy = argvdup(argc, argv);
+  xbt_log_init(&argc_copy, argv_copy);
+  sg_config_init(&argc_copy, argv_copy);
+
+  if (argc < 2)
+    xbt_die("Missing arguments.\n");
+
+  bool server_mode = false;
+  char* env = std::getenv("SIMGRID_MC_MODE");
+  if (env) {
+    if (std::strcmp(env, "server") == 0)
+      server_mode = true;
+    else if (std::strcmp(env, "standalone") == 0)
+      server_mode = false;
+    else
+      XBT_WARN("Unrecognised value for SIMGRID_MC_MODE (server/standalone)");
+  }
+
+  if (!server_mode) {
+    setenv(MC_ENV_VARIABLE, "1", 1);
+    execvp(argv[1], argv+1);
+
+    std::perror("simgrid-mc");
+    return 127;
+  }
+
+  // Create a AF_LOCAL socketpair:
+  int res;
+
+  int sockets[2];
+  res = socketpair(AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0, sockets);
+  if (res == -1) {
+    perror("simgrid-mc");
+    return MC_SERVER_ERROR;
+  }
+
+  XBT_DEBUG("Created socketpair");
+
+  pid_t pid = fork();
+  if (pid < 0) {
+    perror("simgrid-mc");
+    return MC_SERVER_ERROR;
+  } else if (pid == 0) {
+    close(sockets[1]);
+    return do_child(sockets[0], argv);
+  } else {
+    close(sockets[0]);
+    return do_parent(sockets[1], pid);
+  }
+
+  return 0;
+}
index 3fc88bc..18b73fb 100644 (file)
@@ -695,6 +695,12 @@ void sg_config_init(int *argc, char **argv)
                      xbt_cfgelm_boolean, 1, 1, _mc_cfg_cb_hash, NULL);
     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/hash", "no");
 
+    /* Set max depth exploration */
+    xbt_cfg_register(&_sg_cfg_set, "model-check/snapshot_fds",
+                     "Whether file descriptors must be snapshoted",
+                     xbt_cfgelm_boolean, 1, 1, _mc_cfg_cb_snapshot_fds, NULL);
+    xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/snapshot_fds", "no");
+
     /* Set max depth exploration */
     xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth",
                      "Specify the max depth of exploration (default : 1000)",
index b339a4a..69806ac 100644 (file)
@@ -15,6 +15,8 @@
 
 #include "smx_private.h"
 #ifdef HAVE_MC
+#include "mc/mc_process.h"
+#include "mc/mc_model_checker.h"
 #endif
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);
@@ -162,6 +164,11 @@ const char* simcall_names[] = {
  */
 void SIMIX_simcall_handle(smx_simcall_t simcall, int value) {
   XBT_DEBUG("Handling simcall %p: %s", simcall, SIMIX_simcall_name(simcall->call));
+  #ifdef HAVE_MC
+  if (mc_model_checker) {
+    mc_model_checker->process.cache_flags = 0;
+  }
+  #endif
   SIMCALL_SET_MC_VALUE(simcall, value);
   if (simcall->issuer->context->iwannadie && simcall->call != SIMCALL_PROCESS_CLEANUP)
     return;
index 41bd69d..321a63b 100755 (executable)
@@ -281,7 +281,8 @@ if __name__=='__main__':
   
   fd.write('#include "smx_private.h"\n');
   fd.write('#ifdef HAVE_MC\n');
-  # fd.write('#include "mc/mc_private.h"\n');
+  fd.write('#include "mc/mc_process.h"\n');
+  fd.write('#include "mc/mc_model_checker.h"\n');
   fd.write('#endif\n');
   fd.write('\n');
   fd.write('XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);\n\n');
@@ -302,6 +303,11 @@ if __name__=='__main__':
   fd.write(' */\n');
   fd.write('void SIMIX_simcall_handle(smx_simcall_t simcall, int value) {\n');
   fd.write('  XBT_DEBUG("Handling simcall %p: %s", simcall, SIMIX_simcall_name(simcall->call));\n');
+  fd.write('  #ifdef HAVE_MC\n');
+  fd.write('  if (mc_model_checker) {\n');
+  fd.write('    mc_model_checker->process.cache_flags = 0;\n');
+  fd.write('  }\n');
+  fd.write('  #endif\n');
   fd.write('  SIMCALL_SET_MC_VALUE(simcall, value);\n');
   fd.write('  if (simcall->issuer->context->iwannadie && simcall->call != SIMCALL_PROCESS_CLEANUP)\n');
   fd.write('    return;\n');
index ecd64f0..29474e8 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 <stdlib.h>
+
 #include "smx_private.h"
 #include "xbt/heap.h"
 #include "xbt/sysdep.h"
@@ -15,6 +17,9 @@
 
 #ifdef HAVE_MC
 #include "mc/mc_private.h"
+#include "mc/mc_model_checker.h"
+#include "mc/mc_protocol.h"
+#include "mc/mc_client.h"
 #endif
 #include "mc/mc_record.h"
 
@@ -206,6 +211,20 @@ void SIMIX_global_init(int *argc, char **argv)
   if (sg_cfg_get_boolean("clean_atexit"))
     atexit(SIMIX_clean);
 
+#ifdef HAVE_MC
+  // The communication initialisation is done ASAP.
+  // We need to commuicate  initialisation of the different layers to the model-checker.
+  if (mc_mode == MC_MODE_NONE) {
+    if (getenv(MC_ENV_SOCKET_FD)) {
+      mc_mode = MC_MODE_CLIENT;
+      MC_client_init();
+      MC_client_hello();
+    } else {
+      mc_mode = MC_MODE_STANDALONE;
+    }
+  }
+#endif
+
   if (_sg_cfg_exit_asap)
     exit(0);
 }
index 26f7c54..7507e90 100644 (file)
@@ -638,6 +638,7 @@ void smpi_really_switch_data_segment(int dest) {
     }
   }
 
+  // FIXME, cross-process support (mmap across process when necessary)
   int current = smpi_privatisation_regions[dest].file_descriptor;
   XBT_DEBUG("Switching data frame to the one of process %d", dest);
   void* tmp = mmap (TOPAGE(start_data_exe), size_data_exe, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, current, 0);
index de303c9..9c9854c 100644 (file)
@@ -51,7 +51,7 @@ static void IB_action_init_callback(NetworkActionPtr action,RoutingEdgePtr src,
     xbt_die("could not find dst node active comms !");  
  // act_dst->rate=rate;
   
-  ((NetworkIBModel*)surf_network_model)->active_comms[action]=make_pair<IBNode*,IBNode*>(act_src, act_dst);
+  ((NetworkIBModel*)surf_network_model)->active_comms[action]=make_pair(act_src, act_dst);
   //post the action in the second dist, to retrieve in the other callback
   XBT_DEBUG("IB callback - action %p init", action);
 
index 2e79954..16b6f4e 100644 (file)
@@ -1101,4 +1101,3 @@ void Action::updateRemainingLazy(double now)
   m_lastUpdate = now;
   m_lastValue = lmm_variable_getvalue(getVariable());
 }
-
index 5c63609..a961720 100644 (file)
@@ -9,6 +9,17 @@
 #include "xbt/automaton.h"
 #include <stdio.h> /* printf */
 
+struct xbt_automaton_propositional_symbol{
+  char* pred;
+  /** Callback used to evaluate the value of the symbol */
+  int (*callback)(void*);
+  /** Additional data for the callback.
+      Alternatively it can be used as a pointer to the data. */
+  void* data;
+  //** Optional callback used to free the data field */
+  void (*free_function)(void*);
+};
+
 xbt_automaton_t xbt_automaton_new(){
   xbt_automaton_t automaton = NULL;
   automaton = xbt_new0(struct xbt_automaton, 1);
@@ -197,15 +208,72 @@ xbt_automaton_state_t xbt_automaton_get_current_state(xbt_automaton_t a){
   return a->current_state;
 }
 
-xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new(xbt_automaton_t a, const char* id, void* fct){
+static int call_simple_function(void* function)
+{
+  return ((int (*)(void)) function)();
+}
+
+xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new(xbt_automaton_t a, const char* id, int(*fct)(void)){
   xbt_automaton_propositional_symbol_t prop_symb = NULL;
   prop_symb = xbt_new0(struct xbt_automaton_propositional_symbol, 1);
   prop_symb->pred = strdup(id);
-  prop_symb->function = fct;
+  prop_symb->callback = call_simple_function;
+  prop_symb->data = fct;
+  prop_symb->free_function = NULL;
   xbt_dynar_push(a->propositional_symbols, &prop_symb);
   return prop_symb;
 }
 
+XBT_PUBLIC(xbt_automaton_propositional_symbol_t) xbt_automaton_propositional_symbol_new_pointer(xbt_automaton_t a, const char* id, int* value)
+{
+  xbt_automaton_propositional_symbol_t prop_symb = NULL;
+  prop_symb = xbt_new0(struct xbt_automaton_propositional_symbol, 1);
+  prop_symb->pred = strdup(id);
+  prop_symb->callback = NULL;
+  prop_symb->data = value;
+  prop_symb->free_function = NULL;
+  xbt_dynar_push(a->propositional_symbols, &prop_symb);
+  return prop_symb;
+}
+
+XBT_PUBLIC(xbt_automaton_propositional_symbol_t) xbt_automaton_propositional_symbol_new_callback(
+  xbt_automaton_t a, const char* id,
+  xbt_automaton_propositional_symbol_callback_type callback,
+  void* data, xbt_automaton_propositional_symbol_free_function_type free_function)
+{
+  xbt_automaton_propositional_symbol_t prop_symb = NULL;
+  prop_symb = xbt_new0(struct xbt_automaton_propositional_symbol, 1);
+  prop_symb->pred = strdup(id);
+  prop_symb->callback = callback;
+  prop_symb->data = data;
+  prop_symb->free_function = free_function;
+  xbt_dynar_push(a->propositional_symbols, &prop_symb);
+  return prop_symb;
+}
+
+XBT_PUBLIC(int) xbt_automaton_propositional_symbol_evaluate(xbt_automaton_propositional_symbol_t symbol)
+{
+  if (symbol->callback)
+    return (symbol->callback)(symbol->data);
+  else
+    return *(int*) symbol->data;
+}
+
+XBT_PUBLIC(xbt_automaton_propositional_symbol_callback_type) xbt_automaton_propositional_symbol_get_callback(xbt_automaton_propositional_symbol_t symbol)
+{
+  return symbol->callback;
+}
+
+XBT_PUBLIC(void*) xbt_automaton_propositional_symbol_get_data(xbt_automaton_propositional_symbol_t symbol)
+{
+  return symbol->data;
+}
+
+XBT_PUBLIC(const char*) xbt_automaton_propositional_symbol_get_name(xbt_automaton_propositional_symbol_t symbol)
+{
+  return symbol->pred;
+}
+
 int xbt_automaton_state_compare(xbt_automaton_state_t s1, xbt_automaton_state_t s2){
 
   /* single id for each state, id and type sufficient for comparison*/
@@ -354,7 +422,11 @@ static void xbt_automaton_propositional_symbol_free(xbt_automaton_propositional_
 }
 
 void xbt_automaton_propositional_symbol_free_voidp(void *ps){
-  xbt_automaton_propositional_symbol_free((xbt_automaton_propositional_symbol_t) * (void **) ps);
+  xbt_automaton_propositional_symbol_t symbol = (xbt_automaton_propositional_symbol_t) * (void **) ps;
+  if (symbol->free_function)
+    symbol->free_function(symbol->data);
+  xbt_free(symbol->pred);
+  xbt_automaton_propositional_symbol_free(symbol);
 }
 
 void xbt_automaton_free(xbt_automaton_t a){
index 3d58ba5..fac98b1 100644 (file)
@@ -5,11 +5,18 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 /* Redefine the classical malloc/free/realloc functions so that they fit well in the mmalloc framework */
+#define _GNU_SOURCE
 
+#include <stdlib.h>
+
+#include <dlfcn.h>
+
+#include "../../mc/mc_base.h"
 #include "mmprivate.h"
 #include "xbt_modinter.h"
 #include "internal_config.h"
 #include <math.h>
+#include "../mc/mc_protocol.h"
 
 //#define MM_LEGACY_VERBOSE 1 /* define this to see which version of malloc gets used */
 
    backwards compatibility with the non-mmap'd version. */
 xbt_mheap_t __mmalloc_default_mdp = NULL;
 
+static int __malloc_use_mmalloc;
+
+int malloc_use_mmalloc(void)
+{
+  return __malloc_use_mmalloc;
+}
 
 static xbt_mheap_t __mmalloc_current_heap = NULL;     /* The heap we are currently using. */
 
@@ -27,196 +40,133 @@ xbt_mheap_t mmalloc_get_current_heap(void)
   return __mmalloc_current_heap;
 }
 
-void mmalloc_set_current_heap(xbt_mheap_t new_heap)
+xbt_mheap_t mmalloc_set_current_heap(xbt_mheap_t new_heap)
 {
+  xbt_mheap_t heap = __mmalloc_current_heap;
   __mmalloc_current_heap = new_heap;
+  return heap;
 }
 
-
 #ifdef MMALLOC_WANT_OVERRIDE_LEGACY
-#if 0 && defined(HAVE_GNU_LD)
 
-#undef _GNU_SOURCE
-#define _GNU_SOURCE 1
-#include <dlfcn.h>
-
-static void * (*real_malloc) (size_t) = NULL;
-static void * (*real_realloc) (void*,size_t) = NULL;
-static void * (*real_free) (void*) = NULL;
+/* Fake implementations, they are used to fool dlsym:
+ * dlsym used calloc and falls back to some other mechanism
+ * if this fails.
+ */
+static void* mm_fake_calloc(size_t nmemb, size_t size) { return NULL; }
+static void* mm_fake_malloc(size_t n)                  { return NULL; }
+static void* mm_fake_realloc(void *p, size_t s)        { return NULL; }
 
-static void mm_gnuld_legacy_init(void) { /* This function is called from mmalloc_preinit(); it works even if it's static because all mm is in mm.c */
-  real_malloc = (void * (*) (size_t)) dlsym(RTLD_NEXT, "malloc");
-  real_realloc = (void * (*) (void*,size_t)) dlsym(RTLD_NEXT, "realloc");
-  real_free = (void * (*) (void*)) dlsym(RTLD_NEXT, "free");
-  __mmalloc_current_heap = __mmalloc_default_mdp;
-} 
+/* Function signatures for the main malloc functions: */
+typedef void* (*mm_malloc_t)(size_t size);
+typedef void  (*mm_free_t)(void*);
+typedef void* (*mm_calloc_t)(size_t nmemb, size_t size);
+typedef void* (*mm_realloc_t)(void *ptr, size_t size);
 
-/* Hello pimple!
- * DL needs some memory while resolving the malloc symbol, that is somehow problematic
- * To that extend, we have a little area here living in .BSS that we return if asked for memory before the malloc is resolved.
- */
-static int allocated_junk = 0; /* keep track of many blocks of our little area was already given to someone */
-#define JUNK_SIZE 8
-#define MAX_JUNK_AREAS (64 * 1024 / JUNK_SIZE)
-static char junkareas[MAX_JUNK_AREAS][JUNK_SIZE];
-
-/* This version use mmalloc if there is a current heap, or the legacy implem if not */
-static void *malloc_or_calloc(size_t n, int setzero) {
-  xbt_mheap_t mdp = __mmalloc_current_heap;
-  void *ret;
-#ifdef MM_LEGACY_VERBOSE
-  static int warned_raw = 0;
-  static int warned_mmalloc = 0;
-#endif
-
-  if (mdp) {
-    LOCK(mdp);
-    ret = mmalloc(mdp, n);
-    UNLOCK(mdp);
-    // This was already done by mmalloc:
-    if (mdp->options & XBT_MHEAP_OPTION_MEMSET) {
-      setzero = 0;
-    }
-#ifdef MM_LEGACY_VERBOSE
-    if (!warned_mmalloc) {
-      fprintf(stderr,"Using mmalloc; enabling the model-checker in cmake may have a bad impact on your simulation performance\n");
-      warned_mmalloc = 1;
-    }
-#endif
-  } else if (!real_malloc) {
-      size_t needed_areas = n / JUNK_SIZE;
-      if(needed_areas * JUNK_SIZE != n) needed_areas++;
-      if (allocated_junk+needed_areas>=MAX_JUNK_AREAS) {
-        fprintf(stderr,
-          "Panic: real malloc symbol not resolved yet, and I already gave my little private memory chunk away.\n");
-        exit(1);
-      } else {
-        size_t i = allocated_junk;
-        allocated_junk += needed_areas;
-        ret = junkareas[i];
-      }
-    }
-  else {
-#ifdef MM_LEGACY_VERBOSE
-    if (!warned_raw) {
-      fprintf(stderr,"Using system malloc after interception; you seem to be currently model-checking\n");
-      warned_raw = 1;
-    }
-#endif
-    ret = real_malloc(n);
-  }
-  if (ret && setzero) {
-    memset(ret, 0, n);
-  }
-  return ret;
-}
+/* Function pointers to the real/next implementations: */
+static mm_malloc_t mm_real_malloc   = mm_fake_malloc;
+static mm_free_t mm_real_free;
+static mm_calloc_t mm_real_calloc   = mm_fake_calloc;
+static mm_realloc_t mm_real_realloc = mm_fake_realloc;
 
-void *malloc(size_t n)
-{
-  return malloc_or_calloc(n, 0);
-}
+#define GET_HEAP() __mmalloc_current_heap
 
-void *calloc(size_t nmemb, size_t size)
+/** Constructor functions used to initialize the malloc implementation
+ */
+static void __attribute__((constructor(101))) mm_legacy_constructor()
 {
-  return malloc_or_calloc(nmemb*size, 1);
+  __malloc_use_mmalloc = getenv(MC_ENV_VARIABLE) ? 1 : 0;
+  if (__malloc_use_mmalloc) {
+    __mmalloc_current_heap = mmalloc_preinit();
+  } else {
+    mm_real_realloc  = (mm_realloc_t) dlsym(RTLD_NEXT, "realloc");
+    mm_real_malloc   = (mm_malloc_t)  dlsym(RTLD_NEXT, "malloc");
+    mm_real_free     = (mm_free_t)    dlsym(RTLD_NEXT, "free");
+    mm_real_calloc   = (mm_calloc_t)  dlsym(RTLD_NEXT, "calloc");
+  }
 }
 
-void *realloc(void *p, size_t s)
+void* malloc_no_memset(size_t n)
 {
-  xbt_mheap_t mdp = __mmalloc_current_heap;
-  void *ret;
-
-  if (mdp) {
-    LOCK(mdp);
-    ret = mrealloc(mdp, p, s);
-    UNLOCK(mdp);
-  } else {
-    ret = real_realloc(p,s);
+  if (!__malloc_use_mmalloc) {
+    return mm_real_malloc(n);
   }
 
+  xbt_mheap_t mdp = GET_HEAP();
+  if (!mdp)
+    return NULL;
+
+  LOCK(mdp);
+  void *ret = mmalloc_no_memset(mdp, n);
+  UNLOCK(mdp);
   return ret;
 }
 
-void free(void *p)
+void *malloc(size_t n)
 {
-  if (p==NULL)
-    return;
-  if (p<(void*)junkareas || p>=(void*)(junkareas[MAX_JUNK_AREAS]) ) {
-    // main use case
-
-    xbt_mheap_t mdp = __mmalloc_current_heap;
-
-    if (mdp) {
-      LOCK(mdp);
-      mfree(mdp, p);
-      UNLOCK(mdp);
-    } else {
-      real_free(p);
-    }
-  } else {
-    // We are in the junkarea.
-    // This area is used to allocate memory at initilization time.
-
-    if(allocated_junk && p==junkareas[allocated_junk-1]) {
-      // Last junkarea. We can reuse it.
-      allocated_junk--;
-    } else {
-      // We currently cannot reuse freed junkareas in the general case.
-    }
+  if (!__malloc_use_mmalloc) {
+    return mm_real_malloc(n);
   }
-}
 
-
-#else /* NO GNU_LD */
-void *malloc(size_t n)
-{
-  xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+  xbt_mheap_t mdp = GET_HEAP();
+  if (!mdp)
+    return NULL;
 
   LOCK(mdp);
   void *ret = mmalloc(mdp, n);
   UNLOCK(mdp);
-
-
   return ret;
 }
 
 void *calloc(size_t nmemb, size_t size)
 {
-  xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+  if (!__malloc_use_mmalloc) {
+    return mm_real_calloc(nmemb, size);
+  }
+
+  xbt_mheap_t mdp = GET_HEAP();
+  if (!mdp)
+    return NULL;
 
   LOCK(mdp);
   void *ret = mmalloc(mdp, nmemb*size);
   UNLOCK(mdp);
-
   // This was already done in the callee:
   if(!(mdp->options & XBT_MHEAP_OPTION_MEMSET)) {
     memset(ret, 0, nmemb * size);
   }
-
   return ret;
 }
 
 void *realloc(void *p, size_t s)
 {
-  void *ret = NULL;
-  xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+  if (!__malloc_use_mmalloc) {
+    return mm_real_realloc(p, s);
+  }
+
+  xbt_mheap_t mdp = GET_HEAP();
+  if (!mdp)
+    return NULL;
 
   LOCK(mdp);
-  ret = mrealloc(mdp, p, s);
+  void* ret = mrealloc(mdp, p, s);
   UNLOCK(mdp);
-
   return ret;
 }
 
 void free(void *p)
 {
-  if (p != NULL) {
-    xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
-
-    LOCK(mdp);
-    mfree(mdp, p);
-    UNLOCK(mdp);
+  if (!__malloc_use_mmalloc) {
+    mm_real_free(p);
+    return;
   }
+
+  if (!p)
+    return;
+
+  xbt_mheap_t mdp = GET_HEAP();
+  LOCK(mdp);
+  mfree(mdp, p);
+  UNLOCK(mdp);
 }
-#endif /* NO GNU_LD */
 #endif /* WANT_MALLOC_OVERRIDE */
index 86c3421..8490906 100644 (file)
@@ -343,10 +343,6 @@ void *mmalloc_preinit(void)
   }
   xbt_assert(__mmalloc_default_mdp != NULL);
 
-#if 0 && defined(HAVE_GNU_LD) && defined(MMALLOC_WANT_OVERRIDE_LEGACY)
-  mm_gnuld_legacy_init();
-#endif
-
   return __mmalloc_default_mdp;
 }
 
@@ -357,27 +353,31 @@ void mmalloc_postexit(void)
   // xbt_mheap_destroy_no_free(__mmalloc_default_mdp);
 }
 
-size_t mmalloc_get_bytes_used(xbt_mheap_t heap){
-  int i = 0, j = 0;
+// This is the underlying implementation of mmalloc_get_bytes_used_remote.
+// Is it used directly in order to evaluate the bytes used from a different
+// process.
+size_t mmalloc_get_bytes_used_remote(size_t heaplimit, const malloc_info* heapinfo)
+{
   int bytes = 0;
-  
-  while(i<=((struct mdesc *)heap)->heaplimit){
-    if(((struct mdesc *)heap)->heapinfo[i].type == MMALLOC_TYPE_UNFRAGMENTED){
-      if(((struct mdesc *)heap)->heapinfo[i].busy_block.busy_size > 0)
-        bytes += ((struct mdesc *)heap)->heapinfo[i].busy_block.busy_size;
-     
-    } else if(((struct mdesc *)heap)->heapinfo[i].type > 0){
-      for(j=0; j < (size_t) (BLOCKSIZE >> ((struct mdesc *)heap)->heapinfo[i].type); j++){
-        if(((struct mdesc *)heap)->heapinfo[i].busy_frag.frag_size[j] > 0)
-          bytes += ((struct mdesc *)heap)->heapinfo[i].busy_frag.frag_size[j];
+  for (size_t i=0; i<=heaplimit; ++i){
+    if (heapinfo[i].type == MMALLOC_TYPE_UNFRAGMENTED){
+      if (heapinfo[i].busy_block.busy_size > 0)
+        bytes += heapinfo[i].busy_block.busy_size;
+    } else if (heapinfo[i].type > 0) {
+      for (size_t j=0; j < (size_t) (BLOCKSIZE >> heapinfo[i].type); j++){
+        if(heapinfo[i].busy_frag.frag_size[j] > 0)
+          bytes += heapinfo[i].busy_frag.frag_size[j];
       }
     }
-    i++; 
   }
-
   return bytes;
 }
 
+size_t mmalloc_get_bytes_used(const xbt_mheap_t heap){
+  const struct mdesc* heap_data = (const struct mdesc *) heap;
+  return mmalloc_get_bytes_used_remote(heap_data->heaplimit, heap_data->heapinfo);
+}
+
 ssize_t mmalloc_get_busy_size(xbt_mheap_t heap, void *ptr){
 
   ssize_t block = ((char*)ptr - (char*)(heap->heapbase)) / BLOCKSIZE + 1;
index c652e41..8a40c48 100644 (file)
@@ -321,4 +321,11 @@ static inline int mmalloc_get_increment(malloc_info* heapinfo) {
 
 void mmcheck(xbt_mheap_t heap);
 
+int malloc_use_mmalloc(void);
+
+int mmalloc_exec_using_mm(int argc, const char** argv);
+void mmalloc_ensure_using_mm(int argc, const char** argv);
+
+size_t mmalloc_get_bytes_used_remote(size_t heaplimit, const malloc_info* heapinfo);
+
 #endif                          /* __MMPRIVATE_H */
index c355f49..d07d4a3 100644 (file)
@@ -103,9 +103,6 @@ static void xbt_preinit(void) {
     ++xbt_pagebits;
   }
 
-#ifdef MMALLOC_WANT_OVERRIDE_LEGACY
-  mmalloc_preinit();
-#endif
 #ifdef _TWO_DIGIT_EXPONENT
   /* Even printf behaves differently on Windows... */
   _set_output_format(_TWO_DIGIT_EXPONENT);
index 079e050..ed497cc 100644 (file)
@@ -10,6 +10,8 @@
 #define XBT_MODINTER_H
 #include "xbt/misc.h"
 
+SG_BEGIN_DECL()
+
 /* Modules definitions */
 void xbt_backtrace_preinit(void);
 void xbt_backtrace_postexit(void);
@@ -29,5 +31,6 @@ void xbt_os_thread_mod_postexit(void);
 void *mmalloc_preinit(void);
 void mmalloc_postexit(void);
 
+SG_END_DECL()
 
 #endif                          /* XBT_MODINTER_H */
index 8b22d4b..c7ad31c 100644 (file)
@@ -17,6 +17,7 @@
 #include "../../src/include/mc/datatypes.h"
 #include "../../src/mc/mc_object_info.h"
 #include "../../src/mc/mc_private.h"
+#include "../../src/mc/mc_model_checker.h"
 
 int test_some_array[4][5][6];
 struct some_struct { int first; int second[4][5]; } test_some_struct;
@@ -33,17 +34,6 @@ static dw_type_t find_type_by_name(mc_object_info_t info, const char* name) {
   return NULL;
 }
 
-static dw_variable_t find_global_variable_by_name(mc_object_info_t info, const char* name) {
-  unsigned int cursor = 0;
-  dw_variable_t variable;
-  xbt_dynar_foreach(info->global_variables, cursor, variable){
-    if(!strcmp(name, variable->name))
-      return variable;
-  }
-
-  return NULL;
-}
-
 static dw_frame_t find_function_by_name(mc_object_info_t info, const char* name) {
   xbt_dict_cursor_t cursor = 0;
   dw_frame_t subprogram;
@@ -96,15 +86,16 @@ static void test_local_variable(mc_object_info_t info, const char* function, con
 
 }
 
-static dw_variable_t test_global_variable(mc_object_info_t info, const char* name, void* address, long byte_size) {
-  dw_variable_t variable = find_global_variable_by_name(info, name);
+static dw_variable_t test_global_variable(mc_process_t process, mc_object_info_t info, const char* name, void* address, long byte_size) {
+  
+  dw_variable_t variable = MC_file_object_info_find_variable_by_name(info, name);
   xbt_assert(variable, "Global variable %s was not found", name);
   xbt_assert(!strcmp(variable->name, name), "Name mismatch for %s", name);
   xbt_assert(variable->global, "Variable %s is not global", name);
   xbt_assert(variable->address == address,
       "Address mismatch for %s : %p expected but %p found", name, address, variable->address);
 
-  dw_type_t type = xbt_dict_get_or_null(mc_binary_info->types, variable->type_origin);
+  dw_type_t type = xbt_dict_get_or_null(process->binary_info->types, variable->type_origin);
   xbt_assert(type!=NULL, "Missing type for %s", name);
   xbt_assert(type->byte_size = byte_size, "Byte size mismatch for %s", name);
   return variable;
@@ -124,30 +115,31 @@ int some_local_variable = 0;
 
 typedef struct foo {int i;} s_foo;
 
-static void test_type_by_name(s_foo my_foo) {
-  assert(xbt_dict_get_or_null(mc_binary_info->full_types_by_name, "struct foo"));
+static void test_type_by_name(mc_process_t process, s_foo my_foo) {
+  assert(xbt_dict_get_or_null(process->binary_info->full_types_by_name, "struct foo"));
 }
 
-int main(int argc, char** argv) {
-
-  // xbt_init(&argc, argv);
+int main(int argc, char** argv)
+{
   SIMIX_global_init(&argc, argv);
-  MC_memory_init();
-  MC_init();
 
   dw_variable_t var;
   dw_type_t type;
+  
+  s_mc_process_t p;
+  mc_process_t process = &p;
+  MC_process_init(&p, getpid(), -1);
 
-  test_global_variable(mc_binary_info, "some_local_variable", &some_local_variable, sizeof(int));
+  test_global_variable(process, process->binary_info, "some_local_variable", &some_local_variable, sizeof(int));
 
-  var = test_global_variable(mc_binary_info, "test_some_array", &test_some_array, sizeof(test_some_array));
-  type = xbt_dict_get_or_null(mc_binary_info->types, var->type_origin);
+  var = test_global_variable(process, process->binary_info, "test_some_array", &test_some_array, sizeof(test_some_array));
+  type = xbt_dict_get_or_null(process->binary_info->types, var->type_origin);
   xbt_assert(type->element_count == 6*5*4, "element_count mismatch in test_some_array : %i / %i", type->element_count, 6*5*4);
 
-  var = test_global_variable(mc_binary_info, "test_some_struct", &test_some_struct, sizeof(test_some_struct));
-  type = xbt_dict_get_or_null(mc_binary_info->types, var->type_origin);
-  assert(find_member(mc_binary_info, "first", type)->offset == 0);
-  assert(find_member(mc_binary_info, "second", type)->offset
+  var = test_global_variable(process, process->binary_info, "test_some_struct", &test_some_struct, sizeof(test_some_struct));
+  type = xbt_dict_get_or_null(process->binary_info->types, var->type_origin);
+  assert(find_member(process->binary_info, "first", type)->offset == 0);
+  assert(find_member(process->binary_info, "second", type)->offset
       == ((const char*)&test_some_struct.second) - (const char*)&test_some_struct);
 
   unw_context_t context;
@@ -155,15 +147,15 @@ int main(int argc, char** argv) {
   unw_getcontext(&context);
   unw_init_local(&cursor, &context);
 
-  test_local_variable(mc_binary_info, "main", "argc", &argc, &cursor);
+  test_local_variable(process->binary_info, "main", "argc", &argc, &cursor);
 
   {
     int lexical_block_variable = 50;
-    test_local_variable(mc_binary_info, "main", "lexical_block_variable", &lexical_block_variable, &cursor);
+    test_local_variable(process->binary_info, "main", "lexical_block_variable", &lexical_block_variable, &cursor);
   }
 
   s_foo my_foo;
-  test_type_by_name(my_foo);
+  test_type_by_name(process, my_foo);
 
   _exit(0);
 }
index 93e284b..0491dad 100644 (file)
@@ -1,5 +1,3 @@
 #! ./tesh
 
 $ $SG_TEST_EXENV ${bindir:=.}/dwarf
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
index 63b5b8f..1b79e51 100644 (file)
@@ -1,11 +1,7 @@
 #!/usr/bin/env tesh
 !expect signal SIGABRT
-$ ${bindir:=.}/random_bug  ${srcdir:=.}/../../../examples/platforms/small_platform.xml ${srcdir:=.}/random_bug.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=model-check:1 --cfg=model-check/record:1
-> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
-> [  0.000000] (0:@) Configuration change: Set 'model-check/record' to '1'
+$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/random_bug ${srcdir:=.}/../../../examples/platforms/small_platform.xml ${srcdir:=.}/random_bug.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --log=xbt_cfg.thresh:warning --cfg=model-check:1 --cfg=model-check/record:1
 > [  0.000000] (0:@) Check a safety property
-> [  0.000000] (0:@) Get debug information ...
-> [  0.000000] (0:@) Get debug information done !
 > [  0.000000] (1:app@Tremblay) **************************
 > [  0.000000] (1:app@Tremblay) *** PROPERTY NOT VALID ***
 > [  0.000000] (1:app@Tremblay) **************************
index 4f60925..977f595 100644 (file)
@@ -1,5 +1,4 @@
 #!/usr/bin/env tesh
-$ ${bindir:=.}/random_bug  ${srcdir:=.}/../../../examples/platforms/small_platform.xml ${srcdir:=.}/random_bug.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" "--cfg=model-check/replay:1/3;1/4"
-> [  0.000000] (0:@) Configuration change: Set 'model-check/replay' to '1/3;1/4'
+$ ${bindir:=.}/random_bug  ${srcdir:=.}/../../../examples/platforms/small_platform.xml ${srcdir:=.}/random_bug.xml --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" "--cfg=model-check/replay:1/3;1/4"
 > [  0.000000] (0:@) path=1/3;1/4
 > Error reached
index f004859..f10e305 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-can-deadlock10
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --log=xbt_cfg.thresh:warning --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-can-deadlock10
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -49,4 +41,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 26
 > [0.000000] [mc_global/INFO] Executed transitions = 25
 > Aborted
-
index cf03096..c8857c9 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-can-deadlock4
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --log=xbt_cfg.thresh:warning --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-can-deadlock4
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
index bae9bc7..0adf72c 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-can-deadlock5
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --log=xbt_cfg.thresh:warning --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-can-deadlock5
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -49,4 +41,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 26
 > [0.000000] [mc_global/INFO] Executed transitions = 25
 > Aborted
-
index 3f32b3c..0122655 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-can-deadlock6
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-can-deadlock6
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -49,4 +41,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 26
 > [0.000000] [mc_global/INFO] Executed transitions = 25
 > Aborted
-
index 1567e6b..fdd9a5f 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-wait-deadlock
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-wait-deadlock
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -46,4 +38,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 23
 > [0.000000] [mc_global/INFO] Executed transitions = 22
 > Aborted
-
index 9ae4cbe..9678f5f 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-waitall-deadlock2
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-waitall-deadlock2
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -49,4 +41,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 26
 > [0.000000] [mc_global/INFO] Executed transitions = 25
 > Aborted
-
index 173b558..c18b734 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-waitall-deadlock3
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-waitall-deadlock3
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -52,4 +44,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 29
 > [0.000000] [mc_global/INFO] Executed transitions = 28
 > Aborted
-
index 5a912d8..1181434 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-waitany-deadlock
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-waitany-deadlock
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -47,4 +39,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 24
 > [0.000000] [mc_global/INFO] Executed transitions = 23
 > Aborted
-
index fa30aa0..821c2c3 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-waitany-deadlock2
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/any_src-waitany-deadlock2
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -52,4 +44,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 29
 > [0.000000] [mc_global/INFO] Executed transitions = 28
 > Aborted
-
index 6e0bd50..f0f433e 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/basic-deadlock-comm_create
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun --log=xbt_cfg.thresh:warning -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/basic-deadlock-comm_create
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -47,4 +39,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Executed transitions = 22
 > (1) Got MPI_COMM_NULL
 > Aborted
-
index 585b2cf..d7810c8 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/basic-deadlock-comm_dup
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/basic-deadlock-comm_dup
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -46,4 +38,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 23
 > [0.000000] [mc_global/INFO] Executed transitions = 22
 > Aborted
-
index 13b94e3..b540f3a 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/basic-deadlock-comm_split
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/basic-deadlock-comm_split
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -59,4 +51,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Executed transitions = 34
 > (1) Derived communicator too small (size = 1)
 > Aborted
-
index 9f1e0ce..e35272a 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/basic-deadlock
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/basic-deadlock
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -46,4 +38,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 23
 > [0.000000] [mc_global/INFO] Executed transitions = 22
 > Aborted
-
index b3908f9..dbd8f7f 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/bcast-deadlock
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/bcast-deadlock
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -27,4 +19,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 4
 > [0.000000] [mc_global/INFO] Executed transitions = 3
 > Aborted
-
index 779979a..ab2f74b 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/collective-misorder-allreduce
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/collective-misorder-allreduce
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -46,4 +38,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 23
 > [0.000000] [mc_global/INFO] Executed transitions = 22
 > Aborted
-
index 9401a31..7bd71e9 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/collective-misorder
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/collective-misorder
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -68,4 +60,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 45
 > [0.000000] [mc_global/INFO] Executed transitions = 44
 > Aborted
-
index a094d85..1ccfc3c 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/complex-deadlock
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/complex-deadlock
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -49,4 +41,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 26
 > [0.000000] [mc_global/INFO] Executed transitions = 25
 > Aborted
-
index 5c9869e..2d2f1d0 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/deadlock-config
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/deadlock-config
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > WARNING: This test depends on the MPI's eager limit. Set it appropriately.
 > Initializing (0 of 3)
 > (0) is alive on Tremblay
@@ -31,4 +23,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 4
 > [0.000000] [mc_global/INFO] Executed transitions = 3
 > Aborted
-
index d4476a3..87c6758 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/finalize-deadlock
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/finalize-deadlock
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -45,4 +37,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > (1) Finished normally
 > (2) Finished normally
 > Aborted
-
index 3bc6c86..a3670b3 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/irecv-deadlock
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/irecv-deadlock
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -45,4 +37,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > [0.000000] [mc_global/INFO] Visited states = 22
 > [0.000000] [mc_global/INFO] Executed transitions = 21
 > Aborted
-
index 9cb94eb..987bd1d 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/no-error
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/no-error
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -22,4 +14,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > (0) Finished normally
 > (1) Finished normally
 > Aborted
-
index 9bb6deb..9ca59c8 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/no-error2
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/no-error2
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -27,4 +19,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > (2) Finished normally
 > (0) Finished normally
 > Aborted
-
index 5cecb65..4fc50a3 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/no-error3-any_src
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/no-error3-any_src
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -27,4 +19,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > (2) Finished normally
 > (0) Finished normally
 > Aborted
-
index 1512434..a8a6788 100644 (file)
@@ -1,17 +1,9 @@
 #! ./tesh
 
 ! expect return 134
-$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/no-error3
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/coll_selector' to 'mpich'
+$ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../../../examples/platforms/small_platform.xml --log=xbt_cfg.thresh:warning -np 3 --cfg=model-check:1 --cfg=smpi/running_power:1e9 --cfg=smpi/coll_selector:mpich ${bindir:=.}/no-error3
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 > [0.000000] [mc_global/INFO] Check a safety property
-> [0.000000] [mc_global/INFO] Get debug information ...
-> [0.000000] [mc_global/INFO] Get debug information done !
 > (0) is alive on Tremblay
 > (1) is alive on Jupiter
 > (2) is alive on Fafard
@@ -27,4 +19,3 @@ $ ${bindir:=.}/../../../../bin/smpirun -hostfile ../../hostfile -platform ../../
 > (2) Finished normally
 > (0) Finished normally
 > Aborted
-