Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'mc++'
authorGabriel Corona <gabriel.corona@loria.fr>
Fri, 21 Mar 2014 11:45:05 +0000 (12:45 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Fri, 21 Mar 2014 11:45:05 +0000 (12:45 +0100)
Conflicts:
src/simgrid/sg_config.c
src/xbt/mmalloc/mm_diff.c

13 files changed:
1  2 
CMakeLists.txt
buildtools/Cmake/AddTests.cmake
buildtools/Cmake/CompleteInFiles.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/MakeExe.cmake
buildtools/Cmake/MakeLib.cmake
src/include/mc/mc.h
src/mc/mc_memory.c
src/simgrid/sg_config.c
src/simix/smx_network.c
src/smpi/smpi_base.c
src/smpi/smpi_global.c
src/xbt/mmalloc/mm_diff.c

diff --combined CMakeLists.txt
@@@ -4,7 -4,7 +4,7 @@@ if(WIN32
    SET(CMAKE_RC_COMPILER "windres")
  endif()
  project(SimGrid C)
- if (enable_gtnets OR enable_ns3)
+ if (enable_gtnets OR enable_ns3 OR enable_model-checking)
    enable_language(CXX)
  endif()
  
@@@ -57,7 -57,7 +57,7 @@@ set(SIMGRID_VERSION_MINOR "11"
  set(SIMGRID_VERSION_PATCH "0")
  set(SIMGRID_VERSION_EXTRA "-devel") # Extra words to add to version string (e.g. -rc1)
  
 -set(SIMGRID_VERSION_DATE  "2013") # Year for copyright information
 +set(SIMGRID_VERSION_DATE  "2014") # Year for copyright information
  
  if(${SIMGRID_VERSION_PATCH} EQUAL "0")
    set(release_version "${SIMGRID_VERSION_MAJOR}.${SIMGRID_VERSION_MINOR}")
@@@ -110,37 -110,10 +110,37 @@@ if(NOT enable_memcheck
      ADD_TEST(tesh-msg-pid-ucontext              ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/pid.tesh)
    endif()
  
 +  ADD_TEST(tesh-msg-host-on-off-thread          ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/host_on_off.tesh)
 +  if(HAVE_RAWCTX)
 +    ADD_TEST(tesh-msg-host-on-off-raw           ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/host_on_off.tesh)
 +  endif()
 +  if(CONTEXT_UCONTEXT)
 +    ADD_TEST(tesh-msg-host-on-off-ucontext      ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/host_on_off.tesh)
 +  endif()
 +
 +  ADD_TEST(tesh-msg-task-destroy-cancel-thread          ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/task_destroy_cancel.tesh)
 +  if(HAVE_RAWCTX)
 +    ADD_TEST(tesh-msg-task-destroy-cancel-raw           ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/task_destroy_cancel.tesh)
 +  endif()
 +  if(CONTEXT_UCONTEXT)
 +    ADD_TEST(tesh-msg-task-destroy-cancel-ucontext      ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/task_destroy_cancel.tesh)
 +  endif()
 +
 +  ADD_TEST(tesh-msg-process-thread          ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process.tesh)
 +  if(HAVE_RAWCTX)
 +    ADD_TEST(tesh-msg-process-raw           ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process.tesh)
 +  endif()
 +  if(CONTEXT_UCONTEXT)
 +    ADD_TEST(tesh-msg-process-ucontext      ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process.tesh)
 +  endif()
 +
 +
    # these tests need the assertion mechanism
    # exclude them from memcheck, as they normally die, leaving lots of unfree'd objects
    IF(enable_debug AND NOT enable_memcheck)
 -    ADD_TEST(tesh-simdag-parser-bogus-symmetric ${TESH_COMMAND} ${TESH_OPTION} --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/simdag/platforms --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/simdag/platforms two_hosts_asymetric.tesh)
 +    ADD_TEST(tesh-parser-bogus-symmetric     ${TESH_COMMAND} ${TESH_OPTION} --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/simdag/platforms --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/simdag/platforms bogus_two_hosts_asymetric.tesh)
 +    ADD_TEST(tesh-parser-bogus-missing-gw ${TESH_COMMAND} ${TESH_OPTION} --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/simdag/platforms --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/simdag/platforms bogus_missing_gateway.tesh)
 +    ADD_TEST(tesh-disk-attachment ${TESH_COMMAND} ${TESH_OPTION} --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/simdag/platforms --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/simdag/platforms bogus_disk_attachment.tesh)
    ENDIF()
  
    ADD_TEST(tesh-simdag-bypass                   ${TESH_COMMAND} ${TESH_OPTION} --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/simdag/platforms --setenv srcdir=${CMAKE_HOME_DIRECTORY} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/simdag/platforms basic_parsing_test_bypass.tesh)
        endif()
      endif()
  
 -    ADD_TEST(smpi-energy                        ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/energy.tesh)
 +    ADD_TEST(smpi-energy-thread                 ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/energy.tesh)
      if(SMPI_F2C)
 -      ADD_TEST(smpi-energy-f77                  ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f77/energy.tesh)
 +      ADD_TEST(smpi-energy-f77-thread           ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f77/energy.tesh)
      endif()
      if(SMPI_F90)
 -      ADD_TEST(smpi-energy-f90                  ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f90/energy.tesh)
 +      ADD_TEST(smpi-energy-f90-thread           ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f90/energy.tesh)
 +    endif()
 +    if(CONTEXT_UCONTEXT)
 +      ADD_TEST(smpi-energy-ucontext             ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/energy.tesh)
 +      if(SMPI_F2C)
 +        ADD_TEST(smpi-energy-f77-ucontext       ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f77/energy.tesh)
 +      endif()
 +      if(SMPI_F90)
 +        ADD_TEST(smpi-energy-f90-ucontext       ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f90/energy.tesh)
 +      endif()
 +    endif()
 +    if(HAVE_RAWCTX)
 +      ADD_TEST(smpi-energy-raw                  ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/energy.tesh)
 +      if(SMPI_F2C)
 +        ADD_TEST(smpi-energy-f77-raw            ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f77/energy.tesh)
 +      endif()
 +      if(SMPI_F90)
 +        ADD_TEST(smpi-energy-f90-raw            ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/energy --cd ${CMAKE_BINARY_DIR}/examples/smpi/energy ${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f90/energy.tesh)
 +      endif()
      endif()
  
      if(HAVE_TRACING)
      ADD_TEST(java-pingPong                      ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/java --setenv classpath=${TESH_CLASSPATH} --cd ${CMAKE_BINARY_DIR}/examples/java ${CMAKE_HOME_DIRECTORY}/examples/java/pingPong/pingpong.tesh)
      ADD_TEST(java-priority                      ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/java --setenv classpath=${TESH_CLASSPATH} --cd ${CMAKE_BINARY_DIR}/examples/java ${CMAKE_HOME_DIRECTORY}/examples/java/priority/priority.tesh)
      ADD_TEST(java-startKillTime                 ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/java --setenv classpath=${TESH_CLASSPATH} --cd ${CMAKE_BINARY_DIR}/examples/java ${CMAKE_HOME_DIRECTORY}/examples/java/startKillTime/startKillTime.tesh)
 +    ADD_TEST(java-surf-plugin                   ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/java --setenv classpath=${TESH_CLASSPATH} --cd ${CMAKE_BINARY_DIR}/examples/java ${CMAKE_HOME_DIRECTORY}/examples/java/surfPlugin/surf_plugin.tesh)
      ADD_TEST(java-suspend                       ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/java --setenv classpath=${TESH_CLASSPATH} --cd ${CMAKE_BINARY_DIR}/examples/java ${CMAKE_HOME_DIRECTORY}/examples/java/suspend/suspend.tesh)
      if(HAVE_TRACING)
        ADD_TEST(java-tracing                     ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/java --setenv classpath=${TESH_CLASSPATH} --cd ${CMAKE_BINARY_DIR}/examples/java ${CMAKE_HOME_DIRECTORY}/examples/java/tracing/tracingPingPong.tesh)
      ADD_TEST(scala-masterslave                  ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/scala --setenv classpath=${TESH_CLASSPATH} --cd ${CMAKE_BINARY_DIR}/examples/scala ${CMAKE_HOME_DIRECTORY}/examples/scala/masterslave/masterslave.tesh)
    endif()
  
 +  ADD_TEST(stack-overflow-thread                ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/simix/stack_overflow.tesh)
 +  if(CONTEXT_UCONTEXT)
 +    ADD_TEST(stack-overflow-ucontext            ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/simix/stack_overflow.tesh)
 +  endif()
 +  if(HAVE_RAWCTX)
 +    ADD_TEST(stack-overflow-raw                 ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/simix/stack_overflow.tesh)
 +  endif()
 +
    # examples/msg/mc
    if(HAVE_MC)
      if(CONTEXT_UCONTEXT)
      endif()
    endif()
  
 +  ###
 +  ### Declare that we know that some tests are broken
 +  ###
 +  if(release)
 +    if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
 +      # These tests are known to fail on Mac OS X (the expected error message is
 +      # not shown).
 +      set_tests_properties(stack-overflow-thread PROPERTIES WILL_FAIL true)
 +      if(CONTEXT_UCONTEXT)
 +        set_tests_properties(stack-overflow-ucontext PROPERTIES WILL_FAIL true)
 +      endif()
 +      if(HAVE_RAWCTX)
 +        set_tests_properties(stack-overflow-raw PROPERTIES WILL_FAIL true)
 +      endif()
 +    endif()
 +  endif()
 +
  endif()
  
  ADD_TEST(tesh-simdag-full-links01               ${CMAKE_BINARY_DIR}/teshsuite/simdag/platforms/basic_parsing_test ${CMAKE_HOME_DIRECTORY}/teshsuite/simdag/platforms/two_clusters.xml FULL_LINK)
@@@ -704,6 -633,11 +704,11 @@@ add_test(test-surf-usag
  add_test(test-surf-usage2                       ${CMAKE_BINARY_DIR}/testsuite/surf/surf_usage2 --cfg=path:${CMAKE_HOME_DIRECTORY}/testsuite/surf/ platform.xml)
  add_test(test-surf-trace                        ${CMAKE_BINARY_DIR}/testsuite/surf/trace_usage --cfg=path:${CMAKE_HOME_DIRECTORY}/testsuite/surf/)
  
+ if(HAVE_MC)
+   add_test(mc-dwarf                             ${CMAKE_BINARY_DIR}/testsuite/mc/dwarf)
+   add_test(mc-dwarf-expression                  ${CMAKE_BINARY_DIR}/testsuite/mc/dwarf-expression)
+ endif()
  add_test(testall                                ${CMAKE_BINARY_DIR}/src/testall)
  
  if(enable_auto_install)
@@@ -84,9 -84,6 +84,9 @@@ if(enable_java
    find_package(JNI REQUIRED)
    message("-- [Java] JNI found: ${JNI_FOUND}")
    message("-- [Java] JNI include dirs: ${JNI_INCLUDE_DIRS}")
 +  find_package(SWIG REQUIRED)
 +  include(UseSWIG)
 +  message("-- [Java] Swig found: ${SWIG_FOUND}")
    set(HAVE_Java 1)
  endif()
  if(enable_scala)
@@@ -110,8 -107,6 +110,8 @@@ else(
  endif()
  
  # Checks for header libraries functions.
 +CHECK_LIBRARY_EXISTS(dl      dlopen                  "" HAVE_DLOPEN_IN_LIBDL)
 +CHECK_LIBRARY_EXISTS(execinfo backtrace              "" HAVE_BACKTRACE_IN_LIBEXECINFO)
  CHECK_LIBRARY_EXISTS(pthread pthread_create          "" pthread)
  CHECK_LIBRARY_EXISTS(pthread sem_init                "" HAVE_SEM_INIT_LIB)
  CHECK_LIBRARY_EXISTS(pthread sem_open                "" HAVE_SEM_OPEN_LIB)
@@@ -230,6 -225,7 +230,7 @@@ if(enable_model-checking AND HAVE_MMALL
    SET(HAVE_MC 1)
    SET(MMALLOC_WANT_OVERRIDE_LEGACY 1)
    include(FindLibunwind)
+   include(FindLibdw)
  else()
    if(enable_model-checking)
      message(STATUS "Warning: support for model-checking has been disabled because HAVE_MMALLOC is false")
@@@ -254,10 -250,7 +255,10 @@@ CHECK_TYPE_SIZE(void* SIZEOF_VOIDP
  ### Check for GNU dynamic linker
  CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H)
  if (HAVE_DLFCN_H)
 -    execute_process(COMMAND ${CMAKE_C_COMPILER} ${CMAKE_HOME_DIRECTORY}/buildtools/Cmake/test_prog/prog_gnu_dynlinker.c -ldl -o test_gnu_ld
 +    if(HAVE_DLOPEN_IN_LIBDL)
 +      set(DL_LIBRARY "-ldl")
 +    endif(HAVE_DLOPEN_IN_LIBDL)
 +    execute_process(COMMAND ${CMAKE_C_COMPILER} ${CMAKE_HOME_DIRECTORY}/buildtools/Cmake/test_prog/prog_gnu_dynlinker.c ${DL_LIBRARY} -o test_gnu_ld
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        OUTPUT_VARIABLE HAVE_GNU_LD_compil
      )
@@@ -460,9 -460,6 +460,9 @@@ set(JMSG_C_SR
  )
  
  set(JMSG_JAVA_SRC
 +  src/bindings/java/org/simgrid/NativeLib.java
 +  #src/bindings/java/org/simgrid/NativeException.java
 +
    src/bindings/java/org/simgrid/msg/As.java   
    src/bindings/java/org/simgrid/msg/Comm.java
    src/bindings/java/org/simgrid/msg/File.java
    src/bindings/java/org/simgrid/msg/Msg.java
    src/bindings/java/org/simgrid/msg/MsgException.java
    src/bindings/java/org/simgrid/msg/Mutex.java
 -  src/bindings/java/org/simgrid/msg/NativeException.java
 -  src/bindings/java/org/simgrid/msg/NativeLib.java
 +  src/bindings/java/org/simgrid/msg/NativeException.java    
    src/bindings/java/org/simgrid/msg/Process.java
    src/bindings/java/org/simgrid/msg/ProcessKilledError.java
    src/bindings/java/org/simgrid/msg/ProcessNotFoundException.java
    src/bindings/java/org/simgrid/msg/VM.java
  )
  
 +set(JSURF_SWIG_SRC
 +  src/bindings/java/surf.i
 +)
 +set(JSURF_JAVA_C_SRC
 +  src/bindings/java/surf_swig.cpp
 +  src/bindings/java/surf_swig.hpp
 +)
 +
 +set(JSURF_JAVA_GENERATED_SRC
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/Surf.java
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/SurfJNI.java
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/Plugin.java
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/Model.java
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/Resource.java
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/Action.java  
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/Cpu.java
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/CpuAction.java  
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/NetworkLink.java  
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/NetworkAction.java  
 +
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/LmmConstraint.java  
 +  ${CMAKE_BINARY_DIR}/src/bindings/java/org/simgrid/surf/XbtDict.java
 +) 
 +
  set(JTRACE_C_SRC
    src/bindings/java/jtrace.c
    src/bindings/java/jtrace.h
@@@ -568,6 -542,9 +568,9 @@@ set(MC_SR
    src/mc/mc_compare.c
    src/mc/mc_dpor.c
    src/mc/mc_global.c
+   src/mc/mc_dwarf
+   src/mc/mc_member.c
+   src/mc/mc_dwarf_expression.c
    src/mc/mc_liveness.c
    src/mc/mc_memory.c
    src/mc/mc_private.h
    src/mc/mc_state.c
    src/mc/memory_map.c
    src/mc/mc_pair.c
+   src/mc/mc_hash.c
+   src/mc/mc_set.cpp
    )
  
  set(headers_to_install
@@@ -901,7 -880,6 +906,7 @@@ set(EXAMPLES_CMAKEFILES_TX
    examples/java/cloud/CMakeLists.txt
    examples/java/cloud/migration/CMakeLists.txt
    examples/java/commTime/CMakeLists.txt
 +  examples/java/surfPlugin/CMakeLists.txt
    examples/java/io/CMakeLists.txt
    examples/java/kademlia/CMakeLists.txt
    examples/java/master_slave_bypass/CMakeLists.txt
@@@ -983,7 -961,6 +988,7 @@@ set(TESHSUITE_CMAKEFILES_TX
    teshsuite/smpi/mpich3-test/coll/CMakeLists.txt
    teshsuite/smpi/mpich3-test/datatype/CMakeLists.txt
    teshsuite/smpi/mpich3-test/group/CMakeLists.txt
 +  teshsuite/smpi/mpich3-test/topo/CMakeLists.txt
    teshsuite/smpi/mpich3-test/init/CMakeLists.txt
    teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt
    teshsuite/smpi/mpich3-test/f77/util/CMakeLists.txt
@@@ -1011,6 -988,7 +1016,7 @@@ set(TOOLS_CMAKEFILES_TX
  set(TESTSUITE_CMAKEFILES_TXT
    testsuite/surf/CMakeLists.txt
    testsuite/xbt/CMakeLists.txt
+   testsuite/mc/CMakeLists.txt
    )
  
  set(CMAKE_SOURCE_FILES
    buildtools/Cmake/Modules/FindGraphviz.cmake
    buildtools/Cmake/Modules/FindLibSigc++.cmake
    buildtools/Cmake/Modules/FindLibunwind.cmake
+   buildtools/Cmake/Modules/FindLibdw.cmake
    buildtools/Cmake/Modules/FindLua51Simgrid.cmake
    buildtools/Cmake/Modules/FindNS3.cmake
    buildtools/Cmake/Modules/FindRngStream.cmake
@@@ -19,7 -19,6 +19,7 @@@ add_subdirectory(${CMAKE_HOME_DIRECTORY
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/java/pingPong)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/java/priority)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/java/startKillTime)
 +add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/java/surfPlugin)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/java/suspend)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/java/tracing)
  
@@@ -98,7 -97,6 +98,7 @@@ add_subdirectory(${CMAKE_HOME_DIRECTORY
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/comm)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/datatype)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/group)
 +add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/topo)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/init)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/pt2pt)
  
@@@ -118,6 -116,7 +118,7 @@@ add_subdirectory(${CMAKE_HOME_DIRECTORY
  
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/xbt)
  
+ add_subdirectory(${CMAKE_HOME_DIRECTORY}/testsuite/mc)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/testsuite/surf)
  add_subdirectory(${CMAKE_HOME_DIRECTORY}/testsuite/xbt)
  
@@@ -20,16 -20,7 +20,16 @@@ add_dependencies(simgrid maintainer_fil
  
  # Compute the dependencies of SimGrid
  #####################################
 -set(SIMGRID_DEP "-lm -lstdc++")
 +set(SIMGRID_DEP "-lm")
 +
 +if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD"
 +    AND NOT ${CMAKE_SYSTEM_VERSION} VERSION_LESS 10.0
 +    AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
 +  # FreeBSD from 10.0 provide a internal C++ stack (unused by gcc)
 +  set(SIMGRID_DEP "${SIMGRID_DEP} -lc++")
 +else()
 +  set(SIMGRID_DEP "${SIMGRID_DEP} -lstdc++")
 +endif()
  
  if(pthread)
    if(${CONTEXT_THREADS})
@@@ -86,6 -77,9 +86,9 @@@ if(HAVE_MC
    #   (that includes FindLibunwind.cmake), so simply load it now.
    
    SET(SIMGRID_DEP "${SIMGRID_DEP} -lunwind")
+   # Same for libdw
+   SET(SIMGRID_DEP "${SIMGRID_DEP} -ldw")
    # This supposes that the host machine is either an AMD or a X86.
    # This is deeply wrong, and should be fixed by manually loading -lunwind-PLAT (FIXME)
    if(PROCESSOR_x86_64)
@@@ -96,7 -90,7 +99,7 @@@
  endif()
  
  if(MMALLOC_WANT_OVERRIDE_LEGACY AND HAVE_GNU_LD)
 -  SET(SIMGRID_DEP "${SIMGRID_DEP} -ldl")
 +  SET(SIMGRID_DEP "${SIMGRID_DEP} ${DL_LIBRARY}")
  endif()
  
  if(HAVE_NS3)
@@@ -113,10 -107,6 +116,10 @@@ if(HAVE_POSIX_GETTIME
    SET(SIMGRID_DEP "${SIMGRID_DEP} -lrt")
  endif()
  
 +if(HAVE_BACKTRACE_IN_LIBEXECINFO)
 +  SET(SIMGRID_DEP "${SIMGRID_DEP} -lexecinfo")
 +endif(HAVE_BACKTRACE_IN_LIBEXECINFO)
 +
  # Compute the dependencies of SMPI
  ##################################
  if(enable_smpi AND APPLE)
diff --combined src/include/mc/mc.h
@@@ -17,7 -17,7 +17,7 @@@
  #include "xbt/automaton.h"
  #include "xbt/dynar.h"
  
 -#define STD_HEAP_SIZE   20480000        /* Maximum size of the system's heap */
 +#define STD_HEAP_SIZE   (50*1024*1024)        /* Maximum size of the system's heap */
  
  SG_BEGIN_DECL()
  
@@@ -26,9 -26,12 +26,12 @@@ extern int _sg_do_model_check
  extern int _sg_mc_checkpoint;
  extern char* _sg_mc_property_file;
  extern int _sg_mc_timeout;
+ extern int _sg_mc_hash;
  extern int _sg_mc_max_depth;
  extern int _sg_mc_visited;
  extern char* _sg_mc_dot_output_file;
+ extern int _sg_mc_comms_determinism;
+ extern int _sg_mc_send_determinism;
  
  extern xbt_dynar_t mc_heap_comparison_ignore;
  extern xbt_dynar_t stacks_areas;
@@@ -40,9 -43,12 +43,12 @@@ void _mc_cfg_cb_reduce(const char *name
  void _mc_cfg_cb_checkpoint(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_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);
+ void _mc_cfg_cb_comms_determinism(const char *name, int pos);
+ void _mc_cfg_cb_send_determinism(const char *name, int pos);
  
  XBT_PUBLIC(void) MC_do_the_modelcheck_for_real(void);
  
diff --combined src/mc/mc_memory.c
@@@ -30,7 -30,7 +30,7 @@@ void MC_memory_init(
    raw_heap = NULL;
  #else
    /* Create the second region a page after the first one ends + safety gap */
 -  raw_heap = xbt_mheap_new(-1, (char*)(std_heap) + STD_HEAP_SIZE + getpagesize());
 +  raw_heap = xbt_mheap_new(-1, (char*)(std_heap) + STD_HEAP_SIZE + xbt_pagesize);
    xbt_assert(raw_heap != NULL);
  #endif
  }
@@@ -39,6 -39,9 +39,9 @@@
  #include "xbt_modinter.h"
  void MC_memory_exit(void)
  {
+   MC_free_object_info(&mc_binary_info);
+   MC_free_object_info(&mc_libsimgrid_info);
    if (raw_heap)
      xbt_mheap_destroy(raw_heap);
  }
diff --combined src/simgrid/sg_config.c
@@@ -388,12 -388,6 +388,12 @@@ static void _sg_cfg_cb_context_stack_si
    smx_context_stack_size = xbt_cfg_get_int(_sg_cfg_set, name) * 1024;
  }
  
 +static void _sg_cfg_cb_context_guard_size(const char *name, int pos)
 +{
 +  smx_context_guard_size_was_set = 1;
 +  smx_context_guard_size = xbt_cfg_get_int(_sg_cfg_set, name) * xbt_pagesize;
 +}
 +
  static void _sg_cfg_cb_contexts_nthreads(const char *name, int pos)
  {
    SIMIX_context_set_nthreads(xbt_cfg_get_int(_sg_cfg_set, name));
@@@ -483,7 -477,7 +483,7 @@@ void sg_config_init(int *argc, char **a
      describe_model(description, surf_plugin_description,
                     "plugin", "The plugins");
      xbt_cfg_register(&_sg_cfg_set, "plugin", description,
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__plugin, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__plugin, NULL);
  
      describe_model(description, surf_cpu_model_description,
                     "model", "The model to use for the CPU");
      xbt_cfg_register(&_sg_cfg_set, "network/sender_gap",
                       "Minimum gap between two overlapping sends",
                       xbt_cfgelm_double, 1, 1, _sg_cfg_cb__sender_gap, NULL);
 -    /* default for "network/sender_gap" is set in network.c */
 +    /* real default for "network/sender_gap" is set in network_smpi.cpp */
 +    xbt_cfg_setdefault_double(_sg_cfg_set, "network/sender_gap", NAN);
  
      xbt_cfg_register(&_sg_cfg_set, "network/latency_factor",
                       "Correction factor to apply to the provided latency (default value set by network model)",
      xbt_cfg_register(&_sg_cfg_set, "network/weight_S",
                       "Correction factor to apply to the weight of competing streams (default value set by network model)",
                       xbt_cfgelm_double, 1, 1, _sg_cfg_cb__weight_S, NULL);
 -    /* default for "network/weight_S" is set in network.c */
 +    /* real default for "network/weight_S" is set in network_*.cpp */
 +    xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", NAN);
  
      /* Inclusion path */
      xbt_cfg_register(&_sg_cfg_set, "path",
                       "Lookup path for inclusions in platform and deployment XML files",
 -                     xbt_cfgelm_string, 0, 0, _sg_cfg_cb__surf_path, NULL);
 +                     xbt_cfgelm_string, 1, 0, _sg_cfg_cb__surf_path, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "cpu/maxmin_selective_update",
                       "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
 -                     xbt_cfgelm_boolean, 0, 1, NULL, NULL);
 +                     xbt_cfgelm_boolean, 1, 1, NULL, NULL);
      xbt_cfg_setdefault_boolean(_sg_cfg_set, "cpu/maxmin_selective_update", "no");
  
      xbt_cfg_register(&_sg_cfg_set, "network/maxmin_selective_update",
                       "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
 -                     xbt_cfgelm_boolean, 0, 1, NULL, NULL);
 +                     xbt_cfgelm_boolean, 1, 1, NULL, NULL);
      xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/maxmin_selective_update", "no");
  
  #ifdef HAVE_MC
      /* do model-checking */
      xbt_cfg_register(&_sg_cfg_set, "model-check",
                       "Verify the system through model-checking instead of simulating it (EXPERIMENTAL)",
 -                     xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_model_check, NULL);
 +                     xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb_model_check, NULL);
      xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check", "no");
  
      /* do stateful model-checking */
      xbt_cfg_register(&_sg_cfg_set, "model-check/checkpoint",
                       "Specify the amount of steps between checkpoints during stateful model-checking (default: 0 => stateless verification). "
                       "If value=1, one checkpoint is saved for each step => faster verification, but huge memory consumption; higher values are good compromises between speed and memory consumption.",
 -                     xbt_cfgelm_int, 0, 1, _mc_cfg_cb_checkpoint, NULL);
 +                     xbt_cfgelm_int, 1, 1, _mc_cfg_cb_checkpoint, NULL);
      xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/checkpoint", 0);
  
      /* do liveness model-checking */
      xbt_cfg_register(&_sg_cfg_set, "model-check/property",
                       "Specify the name of the file containing the property. It must be the result of the ltl2ba program.",
 -                     xbt_cfgelm_string, 0, 1, _mc_cfg_cb_property, NULL);
 +                     xbt_cfgelm_string, 1, 1, _mc_cfg_cb_property, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/property", "");
  
 -                     xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_comms_determinism, NULL);
+     /* do communications determinism model-checking */
+     xbt_cfg_register(&_sg_cfg_set, "model-check/communications_determinism",
+                      "Enable/disable the detection of determinism in the communications schemes",
 -                     xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_send_determinism, NULL);
++                     xbt_cfgelm_boolean, 1, 1, _mc_cfg_cb_comms_determinism, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/communications_determinism", "no");
+     /* do send determinism model-checking */
+     xbt_cfg_register(&_sg_cfg_set, "model-check/send_determinism",
+                      "Enable/disable the detection of send-determinism in the communications schemes",
++                     xbt_cfgelm_boolean, 1, 1, _mc_cfg_cb_send_determinism, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/send_determinism", "no");
      /* Specify the kind of model-checking reduction */
      xbt_cfg_register(&_sg_cfg_set, "model-check/reduction",
                       "Specify the kind of exploration reduction (either none or DPOR)",
 -                     xbt_cfgelm_string, 0, 1, _mc_cfg_cb_reduce, NULL);
 +                     xbt_cfgelm_string, 1, 1, _mc_cfg_cb_reduce, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/reduction", "dpor");
  
      /* Enable/disable timeout for wait requests with model-checking */
      xbt_cfg_register(&_sg_cfg_set, "model-check/timeout",
                       "Enable/Disable timeout for wait requests",
 -                     xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_timeout, NULL);
 +                     xbt_cfgelm_boolean, 1, 1, _mc_cfg_cb_timeout, NULL);
      xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", "no");
  
 -                     xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_hash, NULL);
+     /* Enable/disable global hash computation with model-checking */
+     xbt_cfg_register(&_sg_cfg_set, "model-check/hash",
+                      "Enable/Disable state hash for state comparison",
++                     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/max_depth",
                       "Specify the max depth of exploration (default : 1000)",
 -                     xbt_cfgelm_int, 0, 1, _mc_cfg_cb_max_depth, NULL);
 +                     xbt_cfgelm_int, 1, 1, _mc_cfg_cb_max_depth, NULL);
      xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/max_depth", 1000);
  
      /* Set number of visited state stored for state comparison reduction*/
      xbt_cfg_register(&_sg_cfg_set, "model-check/visited",
                       "Specify the number of visited state stored for state comparison reduction. If value=5, the last 5 visited states are stored",
 -                     xbt_cfgelm_int, 0, 1, _mc_cfg_cb_visited, NULL);
 +                     xbt_cfgelm_int, 1, 1, _mc_cfg_cb_visited, NULL);
      xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0);
  
      /* Set file name for dot output of graph state */
      xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output",
                       "Specify the name of dot file corresponding to graph state",
 -                     xbt_cfgelm_string, 0, 1, _mc_cfg_cb_dot_output, NULL);
 +                     xbt_cfgelm_string, 1, 1, _mc_cfg_cb_dot_output, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", "");
  #endif
  
      /* do verbose-exit */
      xbt_cfg_register(&_sg_cfg_set, "verbose-exit",
                       "Activate the \"do nothing\" mode in Ctrl-C",
 -                     xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_verbose_exit, NULL);
 +                     xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb_verbose_exit, NULL);
      xbt_cfg_setdefault_boolean(_sg_cfg_set, "verbose-exit", "yes");
  
      /* context factory */
                       xbt_cfgelm_string, 1, 1, _sg_cfg_cb_context_factory, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/factory", dflt_ctx_fact);
  
 -    /* stack size of contexts in Ko */
 +    /* stack size of contexts in KiB */
      xbt_cfg_register(&_sg_cfg_set, "contexts/stack_size",
 -                     "Stack size of contexts in Kib",
 +                     "Stack size of contexts in KiB",
                       xbt_cfgelm_int, 1, 1, _sg_cfg_cb_context_stack_size, NULL);
 -    xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/stack_size", 128);
 +    xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/stack_size", 8*1024);
      /* No, it was not set yet (the above setdefault() changed this to 1). */
      smx_context_stack_size_was_set = 0;
  
 +    /* guard size for contexts stacks in memory pages */
 +    xbt_cfg_register(&_sg_cfg_set, "contexts/guard_size",
 +                     "Guard size for contexts stacks in memory pages",
 +                     xbt_cfgelm_int, 1, 1, _sg_cfg_cb_context_guard_size, NULL);
 +    xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/guard_size", 1);
 +    /* No, it was not set yet (the above setdefault() changed this to 1). */
 +    smx_context_guard_size_was_set = 0;
 +
      /* number of parallel threads for user processes */
      xbt_cfg_register(&_sg_cfg_set, "contexts/nthreads",
                       "Number of parallel threads used to execute user contexts",
  
      xbt_cfg_register(&_sg_cfg_set, "network/crosstraffic",
                       "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)",
 -                     xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb__surf_network_crosstraffic, NULL);
 +                     xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb__surf_network_crosstraffic, NULL);
      xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "no");
  
  #ifdef HAVE_GTNETS
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/gather",
                       "Which collective to use for gather",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_gather, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_gather, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
                       "Which collective to use for allgather",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgather, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_allgather, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/barrier",
                       "Which collective to use for barrier",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_barrier, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_barrier, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/reduce_scatter",
                       "Which collective to use for reduce_scatter",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce_scatter, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_reduce_scatter, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/scatter",
                       "Which collective to use for scatter",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_scatter, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_scatter, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
                       "Which collective to use for allgatherv",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgatherv, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_allgatherv, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
                       "Which collective to use for allreduce",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allreduce, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_allreduce, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
                       "Which collective to use for alltoall",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoall, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_alltoall, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/alltoallv",
                       "Which collective to use for alltoallv",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoallv, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_alltoallv, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
                       "Which collective to use for bcast",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_bcast, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_bcast, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
                       "Which collective to use for reduce",
 -                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce, NULL);
 +                     xbt_cfgelm_string, 0, 1, &_sg_cfg_cb__coll_reduce, NULL);
  #endif // HAVE_SMPI
  
      xbt_cfg_register(&_sg_cfg_set, "clean_atexit",
        xbt_cfg_setdefault_string(_sg_cfg_set, "path", initial_path);
      }
  
 +    xbt_cfg_check(_sg_cfg_set);
      _sg_cfg_init_status = 1;
  
      sg_config_cmd_line(argc, argv);
diff --combined src/simix/smx_network.c
@@@ -31,8 -31,6 +31,6 @@@ static void SIMIX_comm_start(smx_action
  void SIMIX_network_init(void)
  {
    rdv_points = xbt_dict_new_homogeneous(SIMIX_rdv_free);
-   if(MC_is_active())
-     MC_ignore_global_variable("smx_total_comms");
  }
  
  void SIMIX_network_exit(void)
@@@ -361,7 -359,7 +359,7 @@@ void SIMIX_pre_comm_send(smx_simcall_t 
    smx_action_t comm = SIMIX_comm_isend(simcall->issuer, rdv, task_size, rate,
                                       src_buff, src_buff_size, match_fun, NULL,
                                       data, 0);
 -  simcall->mc_value = 0;
 +  SIMCALL_SET_MC_VALUE(simcall, 0);
    SIMIX_pre_comm_wait(simcall, comm, timeout);
  }
  smx_action_t SIMIX_pre_comm_isend(smx_simcall_t simcall, smx_rdv_t rdv,
@@@ -456,7 -454,7 +454,7 @@@ void SIMIX_pre_comm_recv(smx_simcall_t 
  {
    smx_action_t comm = SIMIX_comm_irecv(simcall->issuer, rdv, dst_buff,
                                       dst_buff_size, match_fun, data, rate);
 -  simcall->mc_value = 0;
 +  SIMCALL_SET_MC_VALUE(simcall, 0);
    SIMIX_pre_comm_wait(simcall, comm, timeout);
  }
  
@@@ -604,7 -602,7 +602,7 @@@ void SIMIX_pre_comm_wait(smx_simcall_t 
    simcall->issuer->waiting_action = action;
  
    if (MC_is_active()) {
 -    int idx = simcall->mc_value;
 +    int idx = SIMCALL_GET_MC_VALUE(simcall);
      if (idx == 0) {
        action->state = SIMIX_DONE;
      } else {
@@@ -668,7 -666,7 +666,7 @@@ void SIMIX_pre_comm_testany(smx_simcall
    simcall_comm_testany__set__result(simcall, -1);
  
    if (MC_is_active()){
 -    int idx = simcall->mc_value;
 +    int idx = SIMCALL_GET_MC_VALUE(simcall);
      if(idx == -1){
        SIMIX_simcall_answer(simcall);
      }else{
@@@ -698,7 -696,7 +696,7 @@@ void SIMIX_pre_comm_waitany(smx_simcall
    unsigned int cursor = 0;
  
    if (MC_is_active()){
 -    int idx = simcall->mc_value;
 +    int idx = SIMCALL_GET_MC_VALUE(simcall);
      action = xbt_dynar_get_as(actions, idx, smx_action_t);
      xbt_fifo_push(action->simcalls, simcall);
      simcall_comm_waitany__set__result(simcall, idx);
diff --combined src/smpi/smpi_base.c
@@@ -226,11 -226,8 +226,11 @@@ static MPI_Request build_request(void *
    request->truncated = 0;
    request->real_size = 0;
    request->real_tag = 0;
 +  if(flags & PERSISTENT)
 +    request->refcount = 1;
 +  else
 +    request->refcount = 0;
  
 -  request->refcount=1;
  #ifdef HAVE_TRACING
    request->send = 0;
    request->recv = 0;
@@@ -293,6 -290,7 +293,6 @@@ MPI_Request smpi_mpi_send_init(void *bu
    MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */
    request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag,
                            comm, PERSISTENT | SEND | PREPARED);
 -  request->refcount++;
    return request;
  }
  
@@@ -302,6 -300,7 +302,6 @@@ MPI_Request smpi_mpi_ssend_init(void *b
    MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */
    request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag,
                            comm, PERSISTENT | SSEND | SEND | PREPARED);
 -  request->refcount++;
    return request;
  }
  
@@@ -311,6 -310,7 +311,6 @@@ MPI_Request smpi_mpi_recv_init(void *bu
    MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */
    request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag,
                            comm, PERSISTENT | RECV | PREPARED);
 -  request->refcount++;
    return request;
  }
  
@@@ -320,9 -320,6 +320,9 @@@ void smpi_mpi_start(MPI_Request request
  
    xbt_assert(!request->action, "Cannot (re)start a non-finished communication");
    request->flags &= ~PREPARED;
 +  request->flags &= ~FINISHED;
 +  request->refcount++;
 +
    if (request->flags & RECV) {
      print_request("New recv", request);
      //FIXME: if receive is posted with a large size, but send is smaller, mailboxes may not match !
        XBT_DEBUG("Send request %p is not in the permanent receive mailbox (buf: %p)",request,request->buf);
        mailbox = smpi_process_remote_mailbox(receiver);
      }
 +
 +    void* buf = request->buf;
      if ( (! (request->flags & SSEND)) && (request->size < sg_cfg_get_int("smpi/send_is_detached_thres"))) {
        void *oldbuf = NULL;
        request->detached = 1;
        if(request->old_type->has_subtype == 0){
          oldbuf = request->buf;
          if (!_xbt_replay_is_active() && oldbuf && request->size!=0){
 -          request->buf = xbt_malloc(request->size);
 -          memcpy(request->buf,oldbuf,request->size);
 +          buf = xbt_malloc(request->size);
 +          memcpy(buf,oldbuf,request->size);
          }
        }
        XBT_DEBUG("Send request %p is detached; buf %p copied into %p",request,oldbuf,request->buf);
      smpi_comm_use(request->comm);
  
      //if we are giving back the control to the user without waiting for completion, we have to inject timings
 -    double sleeptime =0.0;
 +    double sleeptime = 0.0;
      if(request->detached || (request->flags & (ISEND|SSEND))){// issend should be treated as isend
        //isend and send timings may be different
        sleeptime = (request->flags & ISEND)? smpi_ois(request->size) : smpi_os(request->size);
      }
  
 -    if(sleeptime!=0.0){
 +    if(sleeptime != 0.0){
          simcall_process_sleep(sleeptime);
          XBT_DEBUG("sending size of %zu : sleep %f ", request->size, smpi_os(request->size));
      }
  
      request->action =
        simcall_comm_isend(mailbox, request->size, -1.0,
 -                         request->buf, request->real_size,
 +                         buf, request->real_size,
                           &match_send,
                           &xbt_free, // how to free the userdata if a detached send fails
                           request,
@@@ -442,6 -437,7 +442,6 @@@ void smpi_mpi_request_free(MPI_Request 
          *request = MPI_REQUEST_NULL;
      }else{
          print_request("Decrementing", (*request));
 -
      }
    }else{
        xbt_die("freeing an already free request");
@@@ -453,7 -449,7 +453,7 @@@ MPI_Request smpi_isend_init(void *buf, 
  {
    MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */
    request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf , count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag,
 -                          comm, NON_PERSISTENT | ISEND | SEND | PREPARED);
 +                          comm, PERSISTENT | ISEND | SEND | PREPARED);
    return request;
  }
  
@@@ -484,7 -480,7 +484,7 @@@ MPI_Request smpi_irecv_init(void *buf, 
  {
    MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */
    request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag,
 -                          comm, NON_PERSISTENT | RECV | PREPARED);
 +                          comm, PERSISTENT | RECV | PREPARED);
    return request;
  }
  
@@@ -552,8 -548,6 +552,8 @@@ void smpi_mpi_sendrecv(void *sendbuf, i
      smpi_irecv_init(recvbuf, recvcount, recvtype, src, recvtag, comm);
    smpi_mpi_startall(2, requests);
    smpi_mpi_waitall(2, requests, stats);
 +  smpi_mpi_request_free(&requests[0]);
 +  smpi_mpi_request_free(&requests[1]);
    if(status != MPI_STATUS_IGNORE) {
      // Copy receive status
      *status = stats[1];
@@@ -570,8 -564,7 +570,8 @@@ static void finish_wait(MPI_Request * r
    MPI_Request req = *request;
    smpi_empty_status(status);
  
 -  if(!(req->detached && req->flags & SEND) && !(req->flags & PREPARED)){
 +  if(!(req->detached && req->flags & SEND)
 +      && !(req->flags & PREPARED)){
      if(status != MPI_STATUS_IGNORE) {
        int src = req->src == MPI_ANY_SOURCE ? req->real_src : req->src;
        status->MPI_SOURCE = smpi_group_rank(smpi_comm_group(req->comm), src);
    if(req->detached_sender!=NULL){
      smpi_mpi_request_free(&(req->detached_sender));
    }
 -
 -  if(req->flags & NON_PERSISTENT) {
 -    smpi_mpi_request_free(request);
 -  } else {
 +  if(req->flags & PERSISTENT)
      req->action = NULL;
 -  }
 +  req->flags |= FINISHED;
 +
 +  smpi_mpi_request_free(request);
 +
  }
  
  int smpi_mpi_test(MPI_Request * request, MPI_Status * status) {
        flag = simcall_comm_test((*request)->action);
      if (flag) {
        finish_wait(request, status);
 +      if (*request != MPI_REQUEST_NULL && !((*request)->flags & PERSISTENT))
        *request = MPI_REQUEST_NULL;
      }
    }
@@@ -665,7 -657,6 +665,7 @@@ int smpi_mpi_testany(int count, MPI_Req
      if(i != -1) {
        *index = map[i];
        finish_wait(&requests[*index], status);
 +      if (requests[*index] != MPI_REQUEST_NULL && (requests[*index]->flags & NON_PERSISTENT))
        requests[*index] = MPI_REQUEST_NULL;
        flag = 1;
      }
@@@ -718,7 -709,7 +718,7 @@@ void smpi_mpi_probe(int source, int tag
  void smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status){
  
    MPI_Request request =build_request(NULL, 0, MPI_CHAR, source == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), source), smpi_comm_rank(comm), tag,
 -            comm, NON_PERSISTENT | RECV);
 +            comm, PERSISTENT | RECV);
  
    //to avoid deadlock, we have to sleep some time here, or the timer won't advance and we will only do iprobe simcalls
    double sleeptime= sg_cfg_get_double("smpi/iprobe");
@@@ -774,14 -765,13 +774,14 @@@ void smpi_mpi_wait(MPI_Request * reques
    if ((*request)->action != NULL) { // this is not a detached send
      simcall_comm_wait((*request)->action, -1.0);
  #ifdef HAVE_MC
-   if(MC_is_active())
+   if(MC_is_active() && (*request)->action)
      (*request)->action->comm.dst_data = NULL; // dangling pointer : dst_data is freed with a wait, need to set it to NULL for system state comparison
  #endif
    }
  
    finish_wait(request, status);
 -  *request = MPI_REQUEST_NULL;
 +  if (*request != MPI_REQUEST_NULL && ((*request)->flags & NON_PERSISTENT))
 +      *request = MPI_REQUEST_NULL;
    // FIXME for a detached send, finish_wait is not called:
  }
  
@@@ -800,9 -790,7 +800,9 @@@ int smpi_mpi_waitany(int count, MPI_Req
      size = 0;
      XBT_DEBUG("Wait for one of %d", count);
      for(i = 0; i < count; i++) {
 -      if (requests[i] != MPI_REQUEST_NULL && !(requests[i]->flags & PREPARED)) {
 +      if (requests[i] != MPI_REQUEST_NULL
 +          && !(requests[i]->flags & PREPARED)
 +          && !(requests[i]->flags & FINISHED)) {
          if (requests[i]->action != NULL) {
            XBT_DEBUG("Waiting any %p ", requests[i]);
            xbt_dynar_push(comms, &requests[i]->action);
           size=0;//so we free the dynar but don't do the waitany call
           index=i;
           finish_wait(&requests[i], status);//cleanup if refcount = 0
 +         if (requests[i] != MPI_REQUEST_NULL && (requests[i]->flags & NON_PERSISTENT))
           requests[i]=MPI_REQUEST_NULL;//set to null
           break;
           }
        if (i != -1) {
          index = map[i];
          finish_wait(&requests[index], status);
 +        if (requests[i] != MPI_REQUEST_NULL && (requests[i]->flags & NON_PERSISTENT))
          requests[index] = MPI_REQUEST_NULL;
        }
      }
@@@ -860,7 -846,6 +860,7 @@@ int smpi_mpi_waitall(int count, MPI_Req
      }
    }
    for(c = 0; c < count; c++) {
 +
      if (MC_is_active()) {
        smpi_mpi_wait(&requests[c], pstat);
        index = c;
        index = smpi_mpi_waitany(count, requests, pstat);
        if (index == MPI_UNDEFINED)
          break;
 +      if (requests[index] != MPI_REQUEST_NULL && (requests[index]->flags & NON_PERSISTENT))
        requests[index]=MPI_REQUEST_NULL;
      }
      if (status != MPI_STATUSES_IGNORE) {
@@@ -898,7 -882,6 +898,7 @@@ int smpi_mpi_waitsome(int incount, MPI_
        if(status != MPI_STATUSES_IGNORE) {
          status[index] = *pstat;
        }
 +     if (requests[index] != MPI_REQUEST_NULL && (requests[index]->flags & NON_PERSISTENT))
       requests[index]=MPI_REQUEST_NULL;
      }else{
        return MPI_UNDEFINED;
@@@ -924,8 -907,8 +924,8 @@@ int smpi_mpi_testsome(int incount, MPI_
           if(status != MPI_STATUSES_IGNORE) {
             status[i] = *pstat;
           }
 +         if ((requests[i] != MPI_REQUEST_NULL) && requests[i]->flags & NON_PERSISTENT)
           requests[i]=MPI_REQUEST_NULL;
 -
        }
      }else{
        count_dead++;
@@@ -982,9 -965,6 +982,9 @@@ void smpi_mpi_gather(void *sendbuf, in
      // Wait for completion of irecv's.
      smpi_mpi_startall(size - 1, requests);
      smpi_mpi_waitall(size - 1, requests, MPI_STATUS_IGNORE);
 +    for(src = 0; src < size-1; src++) {
 +      smpi_mpi_request_free(&requests[src]);
 +    }
      xbt_free(requests);
    }
  }
@@@ -1049,9 -1029,6 +1049,9 @@@ void smpi_mpi_gatherv(void *sendbuf, in
      // Wait for completion of irecv's.
      smpi_mpi_startall(size - 1, requests);
      smpi_mpi_waitall(size - 1, requests, MPI_STATUS_IGNORE);
 +    for(src = 0; src < size-1; src++) {
 +      smpi_mpi_request_free(&requests[src]);
 +    }
      xbt_free(requests);
    }
  }
@@@ -1092,9 -1069,6 +1092,9 @@@ void smpi_mpi_allgather(void *sendbuf, 
    // Wait for completion of all comms.
    smpi_mpi_startall(2 * (size - 1), requests);
    smpi_mpi_waitall(2 * (size - 1), requests, MPI_STATUS_IGNORE);
 +  for(other = 0; other < 2*(size-1); other++) {
 +    smpi_mpi_request_free(&requests[other]);
 +  }
    xbt_free(requests);
  }
  
@@@ -1134,9 -1108,6 +1134,9 @@@ void smpi_mpi_allgatherv(void *sendbuf
    // Wait for completion of all comms.
    smpi_mpi_startall(2 * (size - 1), requests);
    smpi_mpi_waitall(2 * (size - 1), requests, MPI_STATUS_IGNORE);
 +  for(other = 0; other < 2*(size-1); other++) {
 +    smpi_mpi_request_free(&requests[other]);
 +  }
    xbt_free(requests);
  }
  
@@@ -1177,9 -1148,6 +1177,9 @@@ void smpi_mpi_scatter(void *sendbuf, in
      // Wait for completion of isend's.
      smpi_mpi_startall(size - 1, requests);
      smpi_mpi_waitall(size - 1, requests, MPI_STATUS_IGNORE);
 +    for(dst = 0; dst < size-1; dst++) {
 +      smpi_mpi_request_free(&requests[dst]);
 +    }
      xbt_free(requests);
    }
  }
@@@ -1221,9 -1189,6 +1221,9 @@@ void smpi_mpi_scatterv(void *sendbuf, i
      // Wait for completion of isend's.
      smpi_mpi_startall(size - 1, requests);
      smpi_mpi_waitall(size - 1, requests, MPI_STATUS_IGNORE);
 +    for(dst = 0; dst < size-1; dst++) {
 +      smpi_mpi_request_free(&requests[dst]);
 +    }
      xbt_free(requests);
    }
  }
@@@ -1286,8 -1251,6 +1286,8 @@@ void smpi_mpi_reduce(void *sendbuf, voi
        XBT_DEBUG("finished waiting any request with index %d", index);
        if(index == MPI_UNDEFINED) {
          break;
 +      }else{
 +        smpi_mpi_request_free(&requests[index]);
        }
        if(op) /* op can be MPI_OP_NULL that does nothing */
          smpi_op_apply(op, tmpbufs[index], recvbuf, &count, &datatype);
@@@ -1373,9 -1336,6 +1373,9 @@@ void smpi_mpi_scan(void *sendbuf, void 
    for(index = 0; index < rank; index++) {
      xbt_free(tmpbufs[index]);
    }
 +  for(index = 0; index < size-1; index++) {
 +    smpi_mpi_request_free(&requests[index]);
 +  }
    xbt_free(tmpbufs);
    xbt_free(requests);
  }
@@@ -1445,9 -1405,6 +1445,9 @@@ void smpi_mpi_exscan(void *sendbuf, voi
    for(index = 0; index < rank; index++) {
      xbt_free(tmpbufs[index]);
    }
 +  for(index = 0; index < size-1; index++) {
 +    smpi_mpi_request_free(&requests[index]);
 +  }
    xbt_free(tmpbufs);
    xbt_free(requests);
  }
diff --combined src/smpi/smpi_global.c
@@@ -86,8 -86,6 +86,8 @@@ void smpi_process_init(int *argc, char 
      simcall_rdv_set_receiver(data->mailbox_small, proc);
      XBT_DEBUG("<%d> New process in the game: %p", index, proc);
    }
 +  if (smpi_process_data() == NULL)
 +    xbt_die("smpi_process_data() returned NULL. You probably gave a NULL parameter to MPI_Init. Although it's required by MPI-2, this is currently not supported by SMPI.");
  }
  
  void smpi_process_destroy(void)
   */
  void smpi_process_finalize(void)
  {
+ #if 0
+   // wait for all pending asynchronous comms to finish
+   while (SIMIX_process_has_pending_comms(SIMIX_process_self())) {
+     simcall_process_sleep(0.01);
+   }
+ #else
    int i;
    int size = smpi_comm_size(MPI_COMM_WORLD);
    int rank = smpi_comm_rank(MPI_COMM_WORLD);
      smpi_mpi_waitall( size-1, requests+1, MPI_STATUSES_IGNORE );
      free( requests );
    }
+ #endif
  }
  
  /**
@@@ -11,6 -11,7 +11,7 @@@
  #include "mc/mc.h"
  #include "xbt/mmalloc.h"
  #include "mc/datatypes.h"
+ #include "mc/mc_private.h"
  
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mm_diff, xbt,
                                  "Logging specific to mm_diff in mmalloc");
@@@ -132,12 -133,18 +133,18 @@@ static int compare_backtrace(int b1, in
  
  typedef char* type_name;
  
- __thread void *s_heap = NULL, *heapbase1 = NULL, *heapbase2 = NULL;
- __thread malloc_info *heapinfo1 = NULL, *heapinfo2 = NULL;
- __thread size_t heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
- __thread xbt_dynar_t to_ignore1 = NULL, to_ignore2 = NULL;
- __thread heap_area_t **equals_to1, **equals_to2;
- __thread type_name **types1, **types2;
+ struct s_mm_diff {
+   void *s_heap, *heapbase1, *heapbase2;
+   malloc_info *heapinfo1, *heapinfo2;
+   size_t heaplimit;
+   // Number of blocks in the heaps:
+   size_t heapsize1, heapsize2;
+   xbt_dynar_t to_ignore1, to_ignore2;
+   heap_area_t **equals_to1, **equals_to2;
+   dw_type_t **types1, **types2;
+ };
+ __thread struct s_mm_diff* mm_diff_info = NULL;
  
  /*********************************** Free functions ************************************/
  
@@@ -242,7 -249,7 +249,7 @@@ static int is_block_stack(int block)
    return 0;
  }
  
- static void match_equals(xbt_dynar_t list){
+ static void match_equals(struct s_mm_diff *state, xbt_dynar_t list){
  
    unsigned int cursor = 0;
    heap_area_pair_t current_pair;
  
      if(current_pair->fragment1 != -1){
  
-       if(equals_to1[current_pair->block1][current_pair->fragment1] != NULL){
-         previous_area = equals_to1[current_pair->block1][current_pair->fragment1];
-         heap_area_free(equals_to2[previous_area->block][previous_area->fragment]);
-         equals_to2[previous_area->block][previous_area->fragment] = NULL;
+       if(state->equals_to1[current_pair->block1][current_pair->fragment1] != NULL){
+         previous_area = state->equals_to1[current_pair->block1][current_pair->fragment1];
+         heap_area_free(state->equals_to2[previous_area->block][previous_area->fragment]);
+         state->equals_to2[previous_area->block][previous_area->fragment] = NULL;
          heap_area_free(previous_area);
        }
-       if(equals_to2[current_pair->block2][current_pair->fragment2] != NULL){
-         previous_area = equals_to2[current_pair->block2][current_pair->fragment2];
-         heap_area_free(equals_to1[previous_area->block][previous_area->fragment]);
-         equals_to1[previous_area->block][previous_area->fragment] = NULL;
+       if(state->equals_to2[current_pair->block2][current_pair->fragment2] != NULL){
+         previous_area = state->equals_to2[current_pair->block2][current_pair->fragment2];
+         heap_area_free(state->equals_to1[previous_area->block][previous_area->fragment]);
+         state->equals_to1[previous_area->block][previous_area->fragment] = NULL;
          heap_area_free(previous_area);
        }
  
-       equals_to1[current_pair->block1][current_pair->fragment1] = new_heap_area(current_pair->block2, current_pair->fragment2);
-       equals_to2[current_pair->block2][current_pair->fragment2] = new_heap_area(current_pair->block1, current_pair->fragment1);
+       state->equals_to1[current_pair->block1][current_pair->fragment1] = new_heap_area(current_pair->block2, current_pair->fragment2);
+       state->equals_to2[current_pair->block2][current_pair->fragment2] = new_heap_area(current_pair->block1, current_pair->fragment1);
        
      }else{
  
-       if(equals_to1[current_pair->block1][0] != NULL){
-         previous_area = equals_to1[current_pair->block1][0];
-         heap_area_free(equals_to2[previous_area->block][0]);
-         equals_to2[previous_area->block][0] = NULL;
+       if(state->equals_to1[current_pair->block1][0] != NULL){
+         previous_area = state->equals_to1[current_pair->block1][0];
+         heap_area_free(state->equals_to2[previous_area->block][0]);
+         state->equals_to2[previous_area->block][0] = NULL;
          heap_area_free(previous_area);
        }
-       if(equals_to2[current_pair->block2][0] != NULL){
-         previous_area = equals_to2[current_pair->block2][0];
-         heap_area_free(equals_to1[previous_area->block][0]);
-         equals_to1[previous_area->block][0] = NULL;
+       if(state->equals_to2[current_pair->block2][0] != NULL){
+         previous_area = state->equals_to2[current_pair->block2][0];
+         heap_area_free(state->equals_to1[previous_area->block][0]);
+         state->equals_to1[previous_area->block][0] = NULL;
          heap_area_free(previous_area);
        }
  
-       equals_to1[current_pair->block1][0] = new_heap_area(current_pair->block2, current_pair->fragment2);
-       equals_to2[current_pair->block2][0] = new_heap_area(current_pair->block1, current_pair->fragment1);
+       state->equals_to1[current_pair->block1][0] = new_heap_area(current_pair->block2, current_pair->fragment2);
+       state->equals_to2[current_pair->block2][0] = new_heap_area(current_pair->block1, current_pair->fragment1);
  
      }
  
    }
  }
  
- static int equal_blocks(int b1, int b2){
+ /** Check whether two blocks are known to be matching
+  *
+  *  @param state  State used
+  *  @param b1     Block of state 1
+  *  @param b2     Block of state 2
+  *  @return       if the blocks are known to be matching
+  */
+ static int equal_blocks(struct s_mm_diff *state, int b1, int b2){
    
-   if(equals_to1[b1][0]->block == b2 && equals_to2[b2][0]->block == b1)
+   if(state->equals_to1[b1][0]->block == b2 && state->equals_to2[b2][0]->block == b1)
      return 1;
  
    return 0;
  }
  
- static int equal_fragments(int b1, int f1, int b2, int f2){
+ /** Check whether two fragments are known to be matching
+  *
+  *  @param state  State used
+  *  @param b1     Block of state 1
+  *  @param f1     Fragment of state 1
+  *  @param b2     Block of state 2
+  *  @param f2     Fragment of state 2
+  *  @return       if the fragments are known to be matching
+  */
+ static int equal_fragments(struct s_mm_diff *state, int b1, int f1, int b2, int f2){
    
-   if(equals_to1[b1][f1]->block == b2 && equals_to1[b1][f1]->fragment == f2 && equals_to2[b2][f2]->block == b1 && equals_to2[b2][f2]->fragment == f1)
+   if(state->equals_to1[b1][f1]->block == b2
+     && state->equals_to1[b1][f1]->fragment == f2
+     && state->equals_to2[b2][f2]->block == b1
+     && state->equals_to2[b2][f2]->fragment == f1)
      return 1;
  
    return 0;
  }
  
  int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t i1, xbt_dynar_t i2){
+   if(mm_diff_info==NULL) {
+     mm_diff_info = xbt_new0(struct s_mm_diff, 1);
+   }
+   struct s_mm_diff *state = mm_diff_info;
  
-   if((((struct mdesc *)heap1)->heaplimit != ((struct mdesc *)heap2)->heaplimit) || ((((struct mdesc *)heap1)->heapsize != ((struct mdesc *)heap2)->heapsize) ))
+   if((((struct mdesc *)heap1)->heaplimit != ((struct mdesc *)heap2)->heaplimit)
+     || ((((struct mdesc *)heap1)->heapsize != ((struct mdesc *)heap2)->heapsize) ))
      return -1;
  
    int i, j;
  
-   heaplimit = ((struct mdesc *)heap1)->heaplimit;
+   state->heaplimit = ((struct mdesc *)heap1)->heaplimit;
  
-   s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
 -  state->s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
++  state->s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
  
-   heapbase1 = (char *)heap1 + BLOCKSIZE;
-   heapbase2 = (char *)heap2 + BLOCKSIZE;
+   state->heapbase1 = (char *)heap1 + BLOCKSIZE;
+   state->heapbase2 = (char *)heap2 + BLOCKSIZE;
  
-   heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)((struct mdesc *)heap1)->heapinfo - (char *)s_heap)));
-   heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)((struct mdesc *)heap2)->heapinfo - (char *)s_heap)));
+   state->heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)((struct mdesc *)heap1)->heapinfo - (char *)state->s_heap)));
+   state->heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)((struct mdesc *)heap2)->heapinfo - (char *)state->s_heap)));
  
-   heapsize1 = heap1->heapsize;
-   heapsize2 = heap2->heapsize;
+   state->heapsize1 = heap1->heapsize;
+   state->heapsize2 = heap2->heapsize;
  
-   to_ignore1 = i1;
-   to_ignore2 = i2;
+   state->to_ignore1 = i1;
+   state-> to_ignore2 = i2;
  
-   equals_to1 = malloc(heaplimit * sizeof(heap_area_t *));
-   types1 = malloc(heaplimit * sizeof(type_name *));
-   for(i=0; i<=heaplimit; i++){
-     equals_to1[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t));
-     types1[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(type_name));
+   state->equals_to1 = malloc(state->heaplimit * sizeof(heap_area_t *));
+   state->types1 = malloc(state->heaplimit * sizeof(type_name *));
+   for(i=0; i<=state->heaplimit; i++){
+     state->equals_to1[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t));
+     state->types1[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(type_name));
      for(j=0; j<MAX_FRAGMENT_PER_BLOCK; j++){
-       equals_to1[i][j] = NULL;
-       types1[i][j] = NULL;
+       state->equals_to1[i][j] = NULL;
+       state->types1[i][j] = NULL;
      }      
    }
  
-   equals_to2 = malloc(heaplimit * sizeof(heap_area_t *));
-   types2 = malloc(heaplimit * sizeof(type_name *));
-   for(i=0; i<=heaplimit; i++){
-     equals_to2[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t));
-     types2[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(type_name));
+   state->equals_to2 = malloc(state->heaplimit * sizeof(heap_area_t *));
+   state->types2 = malloc(state->heaplimit * sizeof(type_name *));
+   for(i=0; i<=state->heaplimit; i++){
+     state->equals_to2[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t));
+     state->types2[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(type_name));
      for(j=0; j<MAX_FRAGMENT_PER_BLOCK; j++){
-       equals_to2[i][j] = NULL;
-       types2[i][j] = NULL;
+       state->equals_to2[i][j] = NULL;
+       state->types2[i][j] = NULL;
      }
    }
  
    if(MC_is_active()){
-     MC_ignore_global_variable("heaplimit");
-     MC_ignore_global_variable("s_heap");
-     MC_ignore_global_variable("heapbase1");
-     MC_ignore_global_variable("heapbase2");
-     MC_ignore_global_variable("heapinfo1");
-     MC_ignore_global_variable("heapinfo2");
-     MC_ignore_global_variable("heapsize1");
-     MC_ignore_global_variable("heapsize2");
-     MC_ignore_global_variable("to_ignore1");
-     MC_ignore_global_variable("to_ignore2");
-     MC_ignore_global_variable("equals_to1");
-     MC_ignore_global_variable("equals_to2");
-     MC_ignore_global_variable("types1");
-     MC_ignore_global_variable("types2");
+     MC_ignore_global_variable("mm_diff_info");
    }
  
    return 0;
  
  void reset_heap_information(){
  
+   struct s_mm_diff *state = mm_diff_info;
    size_t i = 0, j;
  
-   for(i=0; i<=heaplimit; i++){
+   for(i=0; i<=state->heaplimit; i++){
      for(j=0; j<MAX_FRAGMENT_PER_BLOCK;j++){
-       heap_area_free(equals_to1[i][j]);
-       equals_to1[i][j] = NULL;
-       heap_area_free(equals_to2[i][j]);
-       equals_to2[i][j] = NULL;
-       xbt_free(types1[i][j]);
-       types1[i][j] = NULL;
-       xbt_free(types2[i][j]);
-       types2[i][j] = NULL;
+       heap_area_free(state->equals_to1[i][j]);
+       state->equals_to1[i][j] = NULL;
+       heap_area_free(state->equals_to2[i][j]);
+       state-> equals_to2[i][j] = NULL;
+       state->types1[i][j] = NULL;
+       state->types2[i][j] = NULL;
      }
-     free(equals_to1[i]);
-     free(equals_to2[i]);
-     free(types1[i]);
-     free(types2[i]);
+     free(state->equals_to1[i]);
+     free(state->equals_to2[i]);
+     free(state->types1[i]);
+     free(state->types2[i]);
    }
  
-   free(equals_to1);
-   free(equals_to2);
-   free(types1);
-   free(types2);
+   free(state->equals_to1);
+   free(state->equals_to2);
+   free(state->types1);
+   free(state->types2);
  
-   s_heap = NULL, heapbase1 = NULL, heapbase2 = NULL;
-   heapinfo1 = NULL, heapinfo2 = NULL;
-   heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
-   to_ignore1 = NULL, to_ignore2 = NULL;
-   equals_to1 = NULL, equals_to2 = NULL;
-   types1 = NULL, types2 = NULL;
+   state->s_heap = NULL, state->heapbase1 = NULL, state->heapbase2 = NULL;
+   state->heapinfo1 = NULL, state->heapinfo2 = NULL;
+   state->heaplimit = 0, state->heapsize1 = 0, state->heapsize2 = 0;
+   state->to_ignore1 = NULL, state->to_ignore2 = NULL;
+   state->equals_to1 = NULL, state->equals_to2 = NULL;
+   state->types1 = NULL, state->types2 = NULL;
  
  }
  
- int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dict_t all_types, xbt_dict_t other_types){
+ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_mheap_t heap1, xbt_mheap_t heap2){
+   struct s_mm_diff *state = mm_diff_info;
  
    if(heap1 == NULL && heap2 == NULL){
      XBT_DEBUG("Malloc descriptors null");
  
    i1 = 1;
  
-   while(i1 <= heaplimit){
+   while(i1 <= state->heaplimit){
  
-     if(heapinfo1[i1].type == -1){ /* Free block */
+     if(state->heapinfo1[i1].type == -1){ /* Free block */
        i1++;
        continue;
      }
  
-     addr_block1 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
+     addr_block1 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
  
-     if(heapinfo1[i1].type == 0){  /* Large block */
+     if(state->heapinfo1[i1].type == 0){  /* Large block */
        
        if(is_stack(addr_block1)){
-         for(k=0; k < heapinfo1[i1].busy_block.size; k++)
-           equals_to1[i1+k][0] = new_heap_area(i1, -1);
-         for(k=0; k < heapinfo2[i1].busy_block.size; k++)
-           equals_to2[i1+k][0] = new_heap_area(i1, -1);
-         i1 += heapinfo1[i1].busy_block.size;
+         for(k=0; k < state->heapinfo1[i1].busy_block.size; k++)
+           state->equals_to1[i1+k][0] = new_heap_area(i1, -1);
+         for(k=0; k < state->heapinfo2[i1].busy_block.size; k++)
+           state->equals_to2[i1+k][0] = new_heap_area(i1, -1);
+         i1 += state->heapinfo1[i1].busy_block.size;
          continue;
        }
  
-       if(equals_to1[i1][0] != NULL){
+       if(state->equals_to1[i1][0] != NULL){
          i1++;
          continue;
        }
        res_compare = 0;
    
        /* Try first to associate to same block in the other heap */
-       if(heapinfo2[i1].type == heapinfo1[i1].type){
+       if(state->heapinfo2[i1].type == state->heapinfo1[i1].type){
  
-         if(equals_to2[i1][0] == NULL){
+         if(state->equals_to2[i1][0] == NULL){
  
-           addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
+           addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
          
-           res_compare = compare_heap_area(addr_block1, addr_block2, NULL, all_types, other_types, NULL, 0);
+           res_compare = compare_heap_area(addr_block1, addr_block2, snapshot1, snapshot2, NULL, NULL, 0);
          
            if(res_compare != 1){
-             for(k=1; k < heapinfo2[i1].busy_block.size; k++)
-               equals_to2[i1+k][0] = new_heap_area(i1, -1);
-             for(k=1; k < heapinfo1[i1].busy_block.size; k++)
-               equals_to1[i1+k][0] = new_heap_area(i1, -1);
+             for(k=1; k < state->heapinfo2[i1].busy_block.size; k++)
+               state->equals_to2[i1+k][0] = new_heap_area(i1, -1);
+             for(k=1; k < state->heapinfo1[i1].busy_block.size; k++)
+               state->equals_to1[i1+k][0] = new_heap_area(i1, -1);
              equal = 1;
-             i1 += heapinfo1[i1].busy_block.size;
+             i1 += state->heapinfo1[i1].busy_block.size;
            }
          
            xbt_dynar_reset(previous);
          
        }
  
-       while(i2 <= heaplimit && !equal){
+       while(i2 <= state->heaplimit && !equal){
  
-         addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));        
+         addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
             
          if(i2 == i1){
            i2++;
            continue;
          }
  
-         if(heapinfo2[i2].type != 0){
+         if(state->heapinfo2[i2].type != 0){
            i2++;
            continue;
          }
      
-         if(equals_to2[i2][0] != NULL){  
+         if(state->equals_to2[i2][0] != NULL){
            i2++;
            continue;
          }
            
-         res_compare = compare_heap_area(addr_block1, addr_block2, NULL, all_types, other_types, NULL, 0);
+         res_compare = compare_heap_area(addr_block1, addr_block2, snapshot1, snapshot2, NULL, NULL, 0);
          
          if(res_compare != 1 ){
-           for(k=1; k < heapinfo2[i2].busy_block.size; k++)
-             equals_to2[i2+k][0] = new_heap_area(i1, -1);
-           for(k=1; k < heapinfo1[i1].busy_block.size; k++)
-             equals_to1[i1+k][0] = new_heap_area(i2, -1);
+           for(k=1; k < state->heapinfo2[i2].busy_block.size; k++)
+             state->equals_to2[i2+k][0] = new_heap_area(i1, -1);
+           for(k=1; k < state->heapinfo1[i1].busy_block.size; k++)
+             state->equals_to1[i1+k][0] = new_heap_area(i2, -1);
            equal = 1;
-           i1 += heapinfo1[i1].busy_block.size;
+           i1 += state->heapinfo1[i1].busy_block.size;
          }
  
          xbt_dynar_reset(previous);
        }
  
        if(!equal){
-         XBT_DEBUG("Block %zu not found (size_used = %zu, addr = %p)", i1, heapinfo1[i1].busy_block.busy_size, addr_block1);
-         i1 = heaplimit + 1;
+         XBT_DEBUG("Block %zu not found (size_used = %zu, addr = %p)", i1, state->heapinfo1[i1].busy_block.busy_size, addr_block1);
+         i1 = state->heaplimit + 1;
          nb_diff1++;
            //i1++;
        }
        
      }else{ /* Fragmented block */
  
-       for(j1=0; j1 < (size_t) (BLOCKSIZE >> heapinfo1[i1].type); j1++){
+       for(j1=0; j1 < (size_t) (BLOCKSIZE >> state->heapinfo1[i1].type); j1++){
  
-         if(heapinfo1[i1].busy_frag.frag_size[j1] == -1) /* Free fragment */
+         if(state->heapinfo1[i1].busy_frag.frag_size[j1] == -1) /* Free fragment */
            continue;
  
-         if(equals_to1[i1][j1] != NULL)
+         if(state->equals_to1[i1][j1] != NULL)
            continue;
  
-         addr_frag1 = (void*) ((char *)addr_block1 + (j1 << heapinfo1[i1].type));
+         addr_frag1 = (void*) ((char *)addr_block1 + (j1 << state->heapinfo1[i1].type));
  
          i2 = 1;
          equal = 0;
          
          /* Try first to associate to same fragment in the other heap */
-         if(heapinfo2[i1].type == heapinfo1[i1].type){
+         if(state->heapinfo2[i1].type == state->heapinfo1[i1].type){
  
-           if(equals_to2[i1][j1] == NULL){
+           if(state->equals_to2[i1][j1] == NULL){
  
-             addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
-             addr_frag2 = (void*) ((char *)addr_block2 + (j1 << ((xbt_mheap_t)s_heap)->heapinfo[i1].type));
+             addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
+             addr_frag2 = (void*) ((char *)addr_block2 + (j1 << ((xbt_mheap_t)state->s_heap)->heapinfo[i1].type));
  
-             res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, all_types, other_types, NULL, 0);
+             res_compare = compare_heap_area(addr_frag1, addr_frag2, snapshot1, snapshot2, NULL, NULL, 0);
  
              if(res_compare !=  1)
                equal = 1;
  
          }
  
-         while(i2 <= heaplimit && !equal){
+         while(i2 <= state->heaplimit && !equal){
  
-           if(heapinfo2[i2].type <= 0){
+           if(state->heapinfo2[i2].type <= 0){
              i2++;
              continue;
            }
  
-           for(j2=0; j2 < (size_t) (BLOCKSIZE >> heapinfo2[i2].type); j2++){
+           for(j2=0; j2 < (size_t) (BLOCKSIZE >> state->heapinfo2[i2].type); j2++){
  
              if(i2 == i1 && j2 == j1)
                continue;
             
-             if(equals_to2[i2][j2] != NULL)
+             if(state->equals_to2[i2][j2] != NULL)
                continue;
                            
-             addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
-             addr_frag2 = (void*) ((char *)addr_block2 + (j2 <<((xbt_mheap_t)s_heap)->heapinfo[i2].type));
+             addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
+             addr_frag2 = (void*) ((char *)addr_block2 + (j2 <<((xbt_mheap_t)state->s_heap)->heapinfo[i2].type));
  
-             res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, all_types, other_types, NULL, 0);
+             res_compare = compare_heap_area(addr_frag1, addr_frag2, snapshot2, snapshot2, NULL, NULL, 0);
              
              if(res_compare != 1){
                equal = 1;
          }
  
          if(!equal){
-           XBT_DEBUG("Block %zu, fragment %zu not found (size_used = %zd, address = %p)\n", i1, j1, heapinfo1[i1].busy_frag.frag_size[j1], addr_frag1);
-           i2 = heaplimit + 1;
-           i1 = heaplimit + 1;
+           XBT_DEBUG("Block %zu, fragment %zu not found (size_used = %zd, address = %p)\n", i1, j1, state->heapinfo1[i1].busy_frag.frag_size[j1], addr_frag1);
+           i2 = state->heaplimit + 1;
+           i1 = state->heaplimit + 1;
            nb_diff1++;
            break;
          }
    size_t i = 1, j = 0;
    void *real_addr_frag1 = NULL, *real_addr_block1 = NULL, *real_addr_block2 = NULL, *real_addr_frag2 = NULL;
   
-   while(i<=heaplimit){
-     if(heapinfo1[i].type == 0){
-       if(i1 == heaplimit){
-         if(heapinfo1[i].busy_block.busy_size > 0){
-           if(equals_to1[i][0] == NULL){            
+   while(i<=state->heaplimit){
+     if(state->heapinfo1[i].type == 0){
+       if(i1 == state->heaplimit){
+         if(state->heapinfo1[i].busy_block.busy_size > 0){
+           if(state->equals_to1[i][0] == NULL){
              if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
-               addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
-               XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block1, heapinfo1[i].busy_block.busy_size);
+               addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
+               XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block1, state->heapinfo1[i].busy_block.busy_size);
                //mmalloc_backtrace_block_display((void*)heapinfo1, i);
              }
              nb_diff1++;
          }
        }
      }
-     if(heapinfo1[i].type > 0){
-       addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
-       real_addr_block1 =  ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)s_heap)->heapbase));
-       for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
-         if(i1== heaplimit){
-           if(heapinfo1[i].busy_frag.frag_size[j] > 0){
-             if(equals_to1[i][j] == NULL){
+     if(state->heapinfo1[i].type > 0){
+       addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
+       real_addr_block1 =  ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)state->s_heap)->heapbase));
+       for(j=0; j < (size_t) (BLOCKSIZE >> state->heapinfo1[i].type); j++){
+         if(i1== state->heaplimit){
+           if(state->heapinfo1[i].busy_frag.frag_size[j] > 0){
+             if(state->equals_to1[i][j] == NULL){
                if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
-                 addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
-                 real_addr_frag1 = (void*) ((char *)real_addr_block1 + (j << ((struct mdesc *)s_heap)->heapinfo[i].type));
-                 XBT_DEBUG("Block %zu, Fragment %zu (%p - %p) not found (size used = %zd)", i, j, addr_frag1, real_addr_frag1, heapinfo1[i].busy_frag.frag_size[j]);
+                 addr_frag1 = (void*) ((char *)addr_block1 + (j << state->heapinfo1[i].type));
+                 real_addr_frag1 = (void*) ((char *)real_addr_block1 + (j << ((struct mdesc *)state->s_heap)->heapinfo[i].type));
+                 XBT_DEBUG("Block %zu, Fragment %zu (%p - %p) not found (size used = %zd)", i, j, addr_frag1, real_addr_frag1, state->heapinfo1[i].busy_frag.frag_size[j]);
                  //mmalloc_backtrace_fragment_display((void*)heapinfo1, i, j);
                }
                nb_diff1++;
      i++; 
    }
  
-   if(i1 == heaplimit)
+   if(i1 == state->heaplimit)
      XBT_DEBUG("Number of blocks/fragments not found in heap1 : %d", nb_diff1);
  
    i = 1;
  
-   while(i<=heaplimit){
-     if(heapinfo2[i].type == 0){
-       if(i1 == heaplimit){
-         if(heapinfo2[i].busy_block.busy_size > 0){
-           if(equals_to2[i][0] == NULL){
+   while(i<=state->heaplimit){
+     if(state->heapinfo2[i].type == 0){
+       if(i1 == state->heaplimit){
+         if(state->heapinfo2[i].busy_block.busy_size > 0){
+           if(state->equals_to2[i][0] == NULL){
              if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
-               addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
-               XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block2, heapinfo2[i].busy_block.busy_size);
+               addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase2));
+               XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block2, state->heapinfo2[i].busy_block.busy_size);
                //mmalloc_backtrace_block_display((void*)heapinfo2, i);
              }
              nb_diff2++;
          }
        }
      }
-     if(heapinfo2[i].type > 0){
-       addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
-       real_addr_block2 =  ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)s_heap)->heapbase));
-       for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo2[i].type); j++){
-         if(i1 == heaplimit){
-           if(heapinfo2[i].busy_frag.frag_size[j] > 0){
-             if(equals_to2[i][j] == NULL){
+     if(state->heapinfo2[i].type > 0){
+       addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase2));
+       real_addr_block2 =  ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)state->s_heap)->heapbase));
+       for(j=0; j < (size_t) (BLOCKSIZE >> state->heapinfo2[i].type); j++){
+         if(i1 == state->heaplimit){
+           if(state->heapinfo2[i].busy_frag.frag_size[j] > 0){
+             if(state->equals_to2[i][j] == NULL){
                if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
-                 addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
-                 real_addr_frag2 = (void*) ((char *)real_addr_block2 + (j << ((struct mdesc *)s_heap)->heapinfo[i].type));
-                 XBT_DEBUG( "Block %zu, Fragment %zu (%p - %p) not found (size used = %zd)", i, j, addr_frag2, real_addr_frag2, heapinfo2[i].busy_frag.frag_size[j]);
+                 addr_frag2 = (void*) ((char *)addr_block2 + (j << state->heapinfo2[i].type));
+                 real_addr_frag2 = (void*) ((char *)real_addr_block2 + (j << ((struct mdesc *)state->s_heap)->heapinfo[i].type));
+                 XBT_DEBUG( "Block %zu, Fragment %zu (%p - %p) not found (size used = %zd)", i, j, addr_frag2, real_addr_frag2, state->heapinfo2[i].busy_frag.frag_size[j]);
                  //mmalloc_backtrace_fragment_display((void*)heapinfo2, i, j);
                }
                nb_diff2++;
      i++; 
    }
  
-   if(i1 == heaplimit)
+   if(i1 == state->heaplimit)
      XBT_DEBUG("Number of blocks/fragments not found in heap2 : %d", nb_diff2);
  
    xbt_dynar_free(&previous);
    return ((nb_diff1 > 0) || (nb_diff2 > 0));
  }
  
- static int compare_heap_area_without_type(void *real_area1, void *real_area2, void *area1, void *area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, int size, int check_ignore){
+ /**
+  *
+  * @param state
+  * @param real_area1     Process address for state 1
+  * @param real_area2     Process address for state 2
+  * @param area1          Snapshot address for state 1
+  * @param area2          Snapshot address for state 2
+  * @param snapshot1      Snapshot of state 1
+  * @param snapshot2      Snapshot of state 2
+  * @param previous
+  * @param size
+  * @param check_ignore
+  */
+ static int compare_heap_area_without_type(struct s_mm_diff *state, void *real_area1, void *real_area2, void *area1, void *area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_dynar_t previous, int size, int check_ignore){
  
    int i = 0;
    void *addr_pointed1, *addr_pointed2;
-   int pointer_align, ignore1, ignore2, res_compare;
+   int pointer_align, res_compare;
+   ssize_t ignore1, ignore2;
  
    while(i<size){
  
      if(check_ignore > 0){
-       if((ignore1 = heap_comparison_ignore_size(to_ignore1, (char *)real_area1 + i)) != -1){
-         if((ignore2 = heap_comparison_ignore_size(to_ignore2, (char *)real_area2 + i))  == ignore1){
+       if((ignore1 = heap_comparison_ignore_size(state->to_ignore1, (char *)real_area1 + i)) != -1){
+         if((ignore2 = heap_comparison_ignore_size(state->to_ignore2, (char *)real_area2 + i))  == ignore1){
            if(ignore1 == 0){
              check_ignore--;
              return 0;
        if(addr_pointed1 > maestro_stack_start && addr_pointed1 < maestro_stack_end && addr_pointed2 > maestro_stack_start && addr_pointed2 < maestro_stack_end){
          i = pointer_align + sizeof(void *);
          continue;
-       }else if((addr_pointed1 > s_heap) && ((char *)addr_pointed1 < (char *)s_heap + STD_HEAP_SIZE) 
-                && (addr_pointed2 > s_heap) && ((char *)addr_pointed2 < (char *)s_heap + STD_HEAP_SIZE)){
-         res_compare = compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, NULL, 0); 
+       }else if((addr_pointed1 > state->s_heap) && ((char *)addr_pointed1 < (char *)state->s_heap + STD_HEAP_SIZE)
+                && (addr_pointed2 > state->s_heap) && ((char *)addr_pointed2 < (char *)state->s_heap + STD_HEAP_SIZE)){
+         res_compare = compare_heap_area(addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, NULL, 0);
          if(res_compare == 1){
            return res_compare;
          }
   
  }
  
- static int compare_heap_area_with_type(void *real_area1, void *real_area2, void *area1, void *area2, 
-                                        xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type_id, 
+ /**
+  *
+  * @param state
+  * @param real_area1     Process address for state 1
+  * @param real_area2     Process address for state 2
+  * @param area1          Snapshot address for state 1
+  * @param area2          Snapshot address for state 2
+  * @param snapshot1      Snapshot of state 1
+  * @param snapshot2      Snapshot of state 2
+  * @param previous
+  * @param type_id
+  * @param area_size      either a byte_size or an elements_count (?)
+  * @param check_ignore
+  * @param pointer_level
+  * @return               0 (same), 1 (different), -1 (unknown)
+  */
+ static int compare_heap_area_with_type(struct s_mm_diff *state, void *real_area1, void *real_area2, void *area1, void *area2,
+                                        mc_snapshot_t snapshot1, mc_snapshot_t snapshot2,
+                                        xbt_dynar_t previous, dw_type_t type,
                                         int area_size, int check_ignore, int pointer_level){
  
    if(is_stack(real_area1) && is_stack(real_area2))
      return 0;
  
-   size_t ignore1, ignore2;
+   ssize_t ignore1, ignore2;
  
-   if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2))  == ignore1)){
+   if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(state->to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(state->to_ignore2, real_area2))  == ignore1)){
      return 0;
    }
    
-   dw_type_t type = xbt_dict_get_or_null(all_types, type_id);
    dw_type_t subtype, subsubtype;
-   int res, elm_size, i, switch_types = 0;
+   int res, elm_size, i;
    unsigned int cursor = 0;
    dw_type_t member;
    void *addr_pointed1, *addr_pointed2;;
-   char *type_desc;
  
    switch(type->type){
-   case e_dw_base_type:
-     if(strcmp(type->name, "char") == 0){ /* String, hence random (arbitrary ?) size */
+   case DW_TAG_unspecified_type:
+     return 1;
+   case DW_TAG_base_type:
+     if(type->name!=NULL && strcmp(type->name, "char") == 0){ /* String, hence random (arbitrary ?) size */
        if(real_area1 == real_area2)
          return -1;
        else
          return (memcmp(area1, area2, area_size) != 0);
      }else{
-       if(area_size != -1 && type->size != area_size)
+       if(area_size != -1 && type->byte_size != area_size)
          return -1;
        else{
-         return  (memcmp(area1, area2, type->size) != 0);
+         return  (memcmp(area1, area2, type->byte_size) != 0);
        }
      }
      break;
-   case e_dw_enumeration_type:
-     if(area_size != -1 && type->size != area_size)
+   case DW_TAG_enumeration_type:
+     if(area_size != -1 && type->byte_size != area_size)
        return -1;
      else
-       return (memcmp(area1, area2, type->size) != 0);
-     break;
-   case e_dw_typedef:
-     return compare_heap_area_with_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->dw_type_id, area_size, check_ignore, pointer_level);
+       return (memcmp(area1, area2, type->byte_size) != 0);
      break;
-   case e_dw_const_type:
-     return 0;
+   case DW_TAG_typedef:
+   case DW_TAG_const_type:
+   case DW_TAG_volatile_type:
+     return compare_heap_area_with_type(state, real_area1, real_area2, area1, area2, snapshot1, snapshot2, previous, type->subtype, area_size, check_ignore, pointer_level);
      break;
-   case e_dw_array_type:
-     subtype = xbt_dict_get_or_null(all_types, type->dw_type_id);
+   case DW_TAG_array_type:
+     subtype = type->subtype;
      switch(subtype->type){
-     case e_dw_base_type:
-     case e_dw_enumeration_type:
-     case e_dw_pointer_type:
-     case e_dw_structure_type:
-     case e_dw_union_type:
-       if(subtype->size == 0){ /*declaration of the type, need the complete description */
-         type_desc = get_type_description(all_types, subtype->name);
-         if(type_desc){
-           subtype = xbt_dict_get_or_null(all_types, type_desc);
-         }else{
-           subtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name));
-           switch_types = 1;
-         }
-       }
-       elm_size = subtype->size;
+     case DW_TAG_unspecified_type:
+       return 1;
+     case DW_TAG_base_type:
+     case DW_TAG_enumeration_type:
+     case DW_TAG_pointer_type:
+     case DW_TAG_reference_type:
+     case DW_TAG_rvalue_reference_type:
+     case DW_TAG_structure_type:
+     case DW_TAG_class_type:
+     case DW_TAG_union_type:
+       if(subtype->full_type)
+         subtype = subtype->full_type;
+       elm_size = subtype->byte_size;
        break;
-     case e_dw_typedef:
-     case e_dw_volatile_type:
-       subsubtype = xbt_dict_get_or_null(all_types, subtype->dw_type_id);
-       if(subsubtype->size == 0){ /*declaration of the type, need the complete description */
-         type_desc = get_type_description(all_types, subsubtype->name);
-         if(type_desc){
-           subsubtype = xbt_dict_get_or_null(all_types, type_desc);
-         }else{
-           subsubtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name));
-           switch_types = 1;
-         }
-       }
-       elm_size = subsubtype->size;
+     // TODO, just remove the type indirection?
+     case DW_TAG_const_type:
+     case DW_TAG_typedef:
+     case DW_TAG_volatile_type:
+       subsubtype = subtype->subtype;
+       if(subsubtype->full_type)
+         subsubtype = subsubtype->full_type;
+       elm_size = subsubtype->byte_size;
        break;
      default : 
        return 0;
        break;
      }
-     for(i=0; i<type->size; i++){ 
-       if(switch_types)
-         res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, other_types, all_types, type->dw_type_id, type->size, check_ignore, pointer_level);
-       else
-         res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, all_types, other_types, type->dw_type_id, type->size, check_ignore, pointer_level);
+     for(i=0; i<type->element_count; i++){
+       // TODO, add support for variable stride (DW_AT_byte_stride)
+       res = compare_heap_area_with_type(state, (char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), snapshot1, snapshot2, previous, type->subtype, subtype->byte_size, check_ignore, pointer_level);
        if(res == 1)
          return res;
      }
      break;
-   case e_dw_pointer_type:
-     if(type->dw_type_id && ((dw_type_t)xbt_dict_get_or_null(all_types, type->dw_type_id))->type == e_dw_subroutine_type){
+   case DW_TAG_reference_type:
+   case DW_TAG_rvalue_reference_type:
+   case DW_TAG_pointer_type:
+     if(type->subtype && type->subtype->type == DW_TAG_subroutine_type){
        addr_pointed1 = *((void **)(area1)); 
        addr_pointed2 = *((void **)(area2));
        return (addr_pointed1 != addr_pointed2);;
          for(i=0; i<(area_size/sizeof(void *)); i++){ 
            addr_pointed1 = *((void **)((char *)area1 + (i*sizeof(void *)))); 
            addr_pointed2 = *((void **)((char *)area2 + (i*sizeof(void *)))); 
-           if(addr_pointed1 > s_heap && (char *)addr_pointed1 < (char*) s_heap + STD_HEAP_SIZE && addr_pointed2 > s_heap && (char *)addr_pointed2 < (char*) s_heap + STD_HEAP_SIZE)
-             res =  compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, type->dw_type_id, pointer_level); 
+           if(addr_pointed1 > state->s_heap && (char *)addr_pointed1 < (char*) state->s_heap + STD_HEAP_SIZE && addr_pointed2 > state->s_heap && (char *)addr_pointed2 < (char*) state->s_heap + STD_HEAP_SIZE)
+             res =  compare_heap_area(addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, type->subtype, pointer_level);
            else
              res =  (addr_pointed1 != addr_pointed2);
            if(res == 1)
        }else{
          addr_pointed1 = *((void **)(area1)); 
          addr_pointed2 = *((void **)(area2));
-         if(addr_pointed1 > s_heap && (char *)addr_pointed1 < (char*) s_heap + STD_HEAP_SIZE && addr_pointed2 > s_heap && (char *)addr_pointed2 < (char*) s_heap + STD_HEAP_SIZE)
-           return compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, type->dw_type_id, pointer_level); 
+         if(addr_pointed1 > state->s_heap && (char *)addr_pointed1 < (char*) state->s_heap + STD_HEAP_SIZE && addr_pointed2 > state->s_heap && (char *)addr_pointed2 < (char*) state->s_heap + STD_HEAP_SIZE)
+           return compare_heap_area(addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, type->subtype, pointer_level);
          else
            return  (addr_pointed1 != addr_pointed2);
        }
      }
      break;
-   case e_dw_structure_type:
-     if(type->size == 0){ /*declaration of the structure, need the complete description */
-       type_desc = get_type_description(all_types, type->name);
-       if(type_desc){
-         type = xbt_dict_get_or_null(all_types, type_desc);
-       }else{
-         type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
-         switch_types = 1;
-       }
-     }
-     if(area_size != -1 && type->size != area_size){
-       if(area_size>type->size && area_size%type->size == 0){
-         for(i=0; i<(area_size/type->size); i++){ 
-           if(switch_types)
-             res = compare_heap_area_with_type((char *)real_area1 + (i*type->size), (char *)real_area2 + (i*type->size), (char *)area1 + (i*type->size), (char *)area2 + (i*type->size), previous, other_types, all_types, type_id, -1, check_ignore, 0); 
-           else
-             res = compare_heap_area_with_type((char *)real_area1 + (i*type->size), (char *)real_area2 + (i*type->size), (char *)area1 + (i*type->size), (char *)area2 + (i*type->size), previous, all_types, other_types, type_id, -1, check_ignore, 0); 
+   case DW_TAG_structure_type:
+   case DW_TAG_class_type:
+     if(type->full_type)
+       type = type->full_type;
+     if(area_size != -1 && type->byte_size != area_size){
+       if(area_size>type->byte_size && area_size%type->byte_size == 0){
+         for(i=0; i<(area_size/type->byte_size); i++){
+           res = compare_heap_area_with_type(state, (char *)real_area1 + (i*type->byte_size), (char *)real_area2 + (i*type->byte_size), (char *)area1 + (i*type->byte_size), (char *)area2 + (i*type->byte_size), snapshot1, snapshot2, previous, type, -1, check_ignore, 0);
            if(res == 1)
              return res;
          }
        }
      }else{
        cursor = 0;
-       xbt_dynar_foreach(type->members, cursor, member){ 
-         if(switch_types)
-           res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, other_types, all_types, member->dw_type_id, -1, check_ignore, 0);
-         else
-           res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, all_types, other_types, member->dw_type_id, -1, check_ignore, 0);  
+       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);
+         char* real_member2 = mc_member_resolve(real_area2, type, member, snapshot2);
+         char* member1 = mc_translate_address((uintptr_t)real_member1, snapshot1);
+         char* member2 = mc_translate_address((uintptr_t)real_member2, snapshot2);
+         res = compare_heap_area_with_type(state, real_member1, real_member2, member1, member2, snapshot1, snapshot2, previous, member->subtype, -1, check_ignore, 0);
          if(res == 1){
            return res;
          }
        }
      }
      break;
-   case e_dw_union_type:
-     return compare_heap_area_without_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->size, check_ignore);
-     break;
-   case e_dw_volatile_type:
-     return compare_heap_area_with_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->dw_type_id, area_size, check_ignore, pointer_level);
+   case DW_TAG_union_type:
+     return compare_heap_area_without_type(state, real_area1, real_area2, area1, area2, snapshot1, snapshot2, previous, type->byte_size, check_ignore);
      break;
    default:
      break;
  
  }
  
- static char* get_offset_type(char* type_id, int offset, xbt_dict_t all_types, xbt_dict_t other_types, int area_size, int *switch_type){
-   dw_type_t type = xbt_dict_get_or_null(all_types, type_id);
-   if(type == NULL){
-     type = xbt_dict_get_or_null(other_types, type_id);
-     *switch_type = 1;
-   }
-   char* type_desc;
+ /** Infer the type of a part of the block from the type of the block
+  *
+  * TODO, handle DW_TAG_array_type as well as arrays of the object ((*p)[5], p[5])
+  *
+  * TODO, handle subfields ((*p).bar.foo, (*p)[5].bar…)
+  *
+  * @param  type_id            DWARF type ID of the root address
+  * @param  area_size
+  * @return                    DWARF type ID for given offset
+  */
+ static dw_type_t get_offset_type(void* real_base_address, dw_type_t type, int offset, int area_size, mc_snapshot_t snapshot){
+   // Beginning of the block, the infered variable type if the type of the block:
+   if(offset==0)
+     return type;
    switch(type->type){
-   case e_dw_structure_type :
-     if(type->size == 0){ /*declaration of the structure, need the complete description */
-       if(*switch_type == 0){
-         type_desc = get_type_description(all_types, type->name);
-         if(type_desc){
-           type = xbt_dict_get_or_null(all_types, type_desc);
-         }else{
-           type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
-           *switch_type = 1;
-         }
-       }else{
-         type_desc = get_type_description(other_types, type->name);
-         if(type_desc){
-           type = xbt_dict_get_or_null(other_types, type_desc);
-         }else{
-           type = xbt_dict_get_or_null(all_types, get_type_description(other_types, type->name));
-           *switch_type = 0;
-         }
-       }
+   case DW_TAG_structure_type :
+   case DW_TAG_class_type:
+     if(type->full_type)
+       type = type->full_type;
      
-     }
-     if(area_size != -1 && type->size != area_size){
-       if(area_size>type->size && area_size%type->size == 0)
-         return type_id;
+     if(area_size != -1 && type->byte_size != area_size){
+       if(area_size>type->byte_size && area_size%type->byte_size == 0)
+         return type;
        else
          return NULL;
      }else{
        unsigned int cursor = 0;
        dw_type_t member;
        xbt_dynar_foreach(type->members, cursor, member){ 
-         if(member->offset == offset)
-           return member->dw_type_id;
+         if(!member->location.size) {
+           // We have the offset, use it directly (shortcut):
+           if(member->offset == offset)
+             return member->subtype;
+         } else {
+           char* real_member = mc_member_resolve(real_base_address, type, member, snapshot);
+           if(real_member - (char*)real_base_address == offset)
+             return member->subtype;
+         }
        }
        return NULL;
      }
    }
  }
  
- int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type_id, int pointer_level){
+ /**
+  *
+  * @param area1          Process address for state 1
+  * @param area2          Process address for state 2
+  * @param snapshot1      Snapshot of state 1
+  * @param snapshot2      Snapshot of state 2
+  * @param previous       Pairs of blocks already compared on the current path (or NULL)
+  * @param type_id        Type of variable
+  * @param pointer_level
+  * @return 0 (same), 1 (different), -1
+  */
+ int compare_heap_area(void *area1, void* area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_dynar_t previous, dw_type_t type, int pointer_level){
+   struct s_mm_diff* state = mm_diff_info;
  
    int res_compare;
    ssize_t block1, frag1, block2, frag2;
  
    void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2, *real_addr_block1, *real_addr_block2,  *real_addr_frag1, *real_addr_frag2;
    void *area1_to_compare, *area2_to_compare;
-   dw_type_t type = NULL;
-   char *type_desc;
    int type_size = -1;
    int offset1 =0, offset2 = 0;
    int new_size1 = -1, new_size2 = -1;
-   char *new_type_id1 = NULL, *new_type_id2 = NULL;
-   int switch_type = 0;
+   dw_type_t new_type1 = NULL, new_type2 = NULL;
  
    int match_pairs = 0;
  
      match_pairs = 1;
    }
  
-   block1 = ((char*)area1 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
-   block2 = ((char*)area2 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
+   // Get block number:
+   block1 = ((char*)area1 - (char*)((xbt_mheap_t)state->s_heap)->heapbase) / BLOCKSIZE + 1;
+   block2 = ((char*)area2 - (char*)((xbt_mheap_t)state->s_heap)->heapbase) / BLOCKSIZE + 1;
  
+   // If either block is a stack block:
    if(is_block_stack((int)block1) && is_block_stack((int)block2)){
      add_heap_area_pair(previous, block1, -1, block2, -1);
      if(match_pairs){
-       match_equals(previous);
+       match_equals(state, previous);
        xbt_dynar_free(&previous);
      }
      return 0;
    }
  
-   if(((char *)area1 < (char*)((xbt_mheap_t)s_heap)->heapbase)  || (block1 > heapsize1) || (block1 < 1) || ((char *)area2 < (char*)((xbt_mheap_t)s_heap)->heapbase) || (block2 > heapsize2) || (block2 < 1)){
+   // If either block is not in the expected area of memory:
+   if(((char *)area1 < (char*)((xbt_mheap_t)state->s_heap)->heapbase)  || (block1 > state->heapsize1) || (block1 < 1)
+     || ((char *)area2 < (char*)((xbt_mheap_t)state->s_heap)->heapbase) || (block2 > state->heapsize2) || (block2 < 1)){
      if(match_pairs){
        xbt_dynar_free(&previous);
      }
      return 1;
    }
  
-   addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)heapbase1));
-   addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)heapbase2));
+   // Snapshot address of the block:
+   addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
+   addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)state->heapbase2));
  
-   real_addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
-   real_addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
+   // Process address of the block:
+   real_addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
+   real_addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
  
-   if(type_id){
-     type = xbt_dict_get_or_null(all_types, type_id);
-     if(type->size == 0){
-       if(type->dw_type_id == NULL){
-         type_desc = get_type_description(all_types, type->name);
-         if(type_desc)
-           type = xbt_dict_get_or_null(all_types, type_desc);
-         else
-           type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
-       }else{
-         type = xbt_dict_get_or_null(all_types, type->dw_type_id);
-       }
-     }
-     if((type->type == e_dw_pointer_type) || ((type->type == e_dw_base_type) && (!strcmp(type->name, "char"))))
+   if(type){
+     if(type->full_type)
+       type = type->full_type;
+     // This assume that for "boring" types (volatile ...) byte_size is absent:
+     while(type->byte_size == 0 && type->subtype!=NULL)
+       type = type->subtype;
+     // Find type_size:
+     if((type->type == DW_TAG_pointer_type) || ((type->type == DW_TAG_base_type) && type->name!=NULL && (!strcmp(type->name, "char"))))
        type_size = -1;
      else
-       type_size = type->size;
+       type_size = type->byte_size;
    }
    
-   if((heapinfo1[block1].type == -1) && (heapinfo2[block2].type == -1)){  /* Free block */
+   if((state->heapinfo1[block1].type == -1) && (state->heapinfo2[block2].type == -1)){  /* Free block */
  
      if(match_pairs){
-       match_equals(previous);
+       match_equals(state, previous);
        xbt_dynar_free(&previous);
      }
      return 0;
  
-   }else if((heapinfo1[block1].type == 0) && (heapinfo2[block2].type == 0)){ /* Complete block */ 
+   }else if((state->heapinfo1[block1].type == 0) && (state->heapinfo2[block2].type == 0)){ /* Complete block */
      
-     if(equals_to1[block1][0] != NULL && equals_to2[block2][0] != NULL){
-       if(equal_blocks(block1, block2)){
+     // TODO, lookup variable type from block type as done for fragmented blocks
+     if(state->equals_to1[block1][0] != NULL && state->equals_to2[block2][0] != NULL){
+       if(equal_blocks(state, block1, block2)){
          if(match_pairs){
-           match_equals(previous);
+           match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return 0;
      }
  
      if(type_size != -1){
-       if(type_size != heapinfo1[block1].busy_block.busy_size && type_size != heapinfo2[block2].busy_block.busy_size && !strcmp(type->name, "s_smx_context")){
+       if(type_size != state->heapinfo1[block1].busy_block.busy_size
+         && type_size != state->heapinfo2[block2].busy_block.busy_size
+         && type->name!=NULL && !strcmp(type->name, "s_smx_context")){
          if(match_pairs){
-           match_equals(previous);
+           match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return -1;
        }
      }
  
-     if(heapinfo1[block1].busy_block.size != heapinfo2[block2].busy_block.size){
+     if(state->heapinfo1[block1].busy_block.size != state->heapinfo2[block2].busy_block.size){
        if(match_pairs){
          xbt_dynar_free(&previous);
        }
        return 1;
      }
  
-     if(heapinfo1[block1].busy_block.busy_size != heapinfo2[block2].busy_block.busy_size){
+     if(state->heapinfo1[block1].busy_block.busy_size != state->heapinfo2[block2].busy_block.busy_size){
        if(match_pairs){
          xbt_dynar_free(&previous);
        }
  
      if(!add_heap_area_pair(previous, block1, -1, block2, -1)){
        if(match_pairs){
-         match_equals(previous);
+         match_equals(state, previous);
          xbt_dynar_free(&previous);
        }
        return 0;
      }
   
-     size = heapinfo1[block1].busy_block.busy_size;
+     size = state->heapinfo1[block1].busy_block.busy_size;
      
-     if(type_id != NULL){
-       xbt_free(types1[block1][0]);
-       xbt_free(types2[block2][0]);
-       types1[block1][0] = strdup(type_id);
-       types2[block2][0] = strdup(type_id);
+     // Remember (basic) type inference.
+     // The current data structure only allows us to do this for the whole block.
+     if (type != NULL && area1==real_addr_block1) {
+       xbt_free(state->types1[block1][0]);
+       state->types1[block1][0] = type;
+     }
+     if (type != NULL && area2==real_addr_block2) {
+       xbt_free(state->types2[block2][0]);
+       state->types2[block2][0] = type;
      }
  
      if(size <= 0){
        if(match_pairs){
-         match_equals(previous);
+         match_equals(state, previous);
          xbt_dynar_free(&previous);
        }
        return 0;
      area1_to_compare = addr_block1;
      area2_to_compare = addr_block2;
  
-     if((heapinfo1[block1].busy_block.ignore > 0) && (heapinfo2[block2].busy_block.ignore == heapinfo1[block1].busy_block.ignore))
-       check_ignore = heapinfo1[block1].busy_block.ignore;
+     if((state->heapinfo1[block1].busy_block.ignore > 0) && (state->heapinfo2[block2].busy_block.ignore == state->heapinfo1[block1].busy_block.ignore))
+       check_ignore = state->heapinfo1[block1].busy_block.ignore;
        
-   }else if((heapinfo1[block1].type > 0) && (heapinfo2[block2].type > 0)){ /* Fragmented block */
+   }else if((state->heapinfo1[block1].type > 0) && (state->heapinfo2[block2].type > 0)){ /* Fragmented block */
  
-     frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> heapinfo1[block1].type;
-     frag2 = ((uintptr_t) (ADDR2UINT (area2) % (BLOCKSIZE))) >> heapinfo2[block2].type;
+     // Fragment number:
+     frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> state->heapinfo1[block1].type;
+     frag2 = ((uintptr_t) (ADDR2UINT (area2) % (BLOCKSIZE))) >> state->heapinfo2[block2].type;
  
-     addr_frag1 = (void*) ((char *)addr_block1 + (frag1 << heapinfo1[block1].type));
-     addr_frag2 = (void*) ((char *)addr_block2 + (frag2 << heapinfo2[block2].type));
+     // Snapshot address of the fragment:
+     addr_frag1 = (void*) ((char *)addr_block1 + (frag1 << state->heapinfo1[block1].type));
+     addr_frag2 = (void*) ((char *)addr_block2 + (frag2 << state->heapinfo2[block2].type));
  
-     real_addr_frag1 = (void*) ((char *)real_addr_block1 + (frag1 << ((xbt_mheap_t)s_heap)->heapinfo[block1].type));
-     real_addr_frag2 = (void*) ((char *)real_addr_block2 + (frag2 << ((xbt_mheap_t)s_heap)->heapinfo[block2].type));
+     // Process address of the fragment:
+     real_addr_frag1 = (void*) ((char *)real_addr_block1 + (frag1 << ((xbt_mheap_t)state->s_heap)->heapinfo[block1].type));
+     real_addr_frag2 = (void*) ((char *)real_addr_block2 + (frag2 << ((xbt_mheap_t)state->s_heap)->heapinfo[block2].type));
  
+     // Check the size of the fragments against the size of the type:
      if(type_size != -1){
-       if(heapinfo1[block1].busy_frag.frag_size[frag1] == -1 || heapinfo2[block2].busy_frag.frag_size[frag2] == -1){
+       if(state->heapinfo1[block1].busy_frag.frag_size[frag1] == -1 || state->heapinfo2[block2].busy_frag.frag_size[frag2] == -1){
          if(match_pairs){
-           match_equals(previous);
+           match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return -1;
        }
-       if(type_size != heapinfo1[block1].busy_frag.frag_size[frag1] || type_size !=  heapinfo2[block2].busy_frag.frag_size[frag2]){
+       if(type_size != state->heapinfo1[block1].busy_frag.frag_size[frag1]|| type_size !=  state->heapinfo2[block2].busy_frag.frag_size[frag2]){
          if(match_pairs){
-           match_equals(previous);
+           match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return -1;
        }
      }
  
-     if(equals_to1[block1][frag1] != NULL && equals_to2[block2][frag2] != NULL){
-       if(equal_fragments(block1, frag1, block2, frag2)){
+     // Check if the blocks are already matched together:
+     if(state->equals_to1[block1][frag1] != NULL && state->equals_to2[block2][frag2] != NULL){
+       if(equal_fragments(state, block1, frag1, block2, frag2)){
          if(match_pairs){
-           match_equals(previous);
+           match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return 0;
        }
      }
  
-     if(heapinfo1[block1].busy_frag.frag_size[frag1] != heapinfo2[block2].busy_frag.frag_size[frag2]){
+     // Compare the size of both fragments:
+     if(state->heapinfo1[block1].busy_frag.frag_size[frag1] != state->heapinfo2[block2].busy_frag.frag_size[frag2]){
        if(type_size == -1){
           if(match_pairs){
-           match_equals(previous);
+           match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return -1;
        }
      }
        
-     size = heapinfo1[block1].busy_frag.frag_size[frag1];
+     // Size of the fragment:
+     size = state->heapinfo1[block1].busy_frag.frag_size[frag1];
  
-     if(type_id != NULL){
-       xbt_free(types1[block1][frag1]);
-       xbt_free(types2[block2][frag2]);
-       types1[block1][frag1] = strdup(type_id);
-       types2[block2][frag2] = strdup(type_id);
+     // Remember (basic) type inference.
+     // The current data structure only allows us to do this for the whole block.
+     if(type != NULL && area1==real_addr_frag1){
+       state->types1[block1][frag1] = type;
      }
+     if(type != NULL && area2==real_addr_frag2) {
+       state->types2[block2][frag2] = type;
+     }
+     // The type of the variable is already known:
+     if(type) {
+       new_type1 = type;
+       new_type2 = type;
+     }
+     // Type inference from the block type.
+     else if(state->types1[block1][frag1] != NULL || state->types2[block2][frag2] != NULL) {
  
-     if(real_addr_frag1 != area1 || real_addr_frag2 != area2){
        offset1 = (char *)area1 - (char *)real_addr_frag1;
        offset2 = (char *)area2 - (char *)real_addr_frag2;
-       if(types1[block1][frag1] != NULL && types2[block2][frag2] != NULL){
-         new_type_id1 = get_offset_type(types1[block1][frag1], offset1, all_types, other_types, size, &switch_type);
-         new_type_id2 = get_offset_type(types2[block2][frag2], offset1, all_types, other_types, size, &switch_type);
-       }else if(types1[block1][frag1] != NULL){
-         new_type_id1 = get_offset_type(types1[block1][frag1], offset1, all_types, other_types, size, &switch_type);
-         new_type_id2 = get_offset_type(types1[block1][frag1], offset2, all_types, other_types, size, &switch_type);       
-       }else if(types2[block2][frag2] != NULL){
-         new_type_id1 = get_offset_type(types2[block2][frag2], offset1, all_types, other_types, size, &switch_type);
-         new_type_id2 = get_offset_type(types2[block2][frag2], offset2, all_types, other_types, size, &switch_type);
+       if(state->types1[block1][frag1] != NULL && state->types2[block2][frag2] != NULL){
+         new_type1 = get_offset_type(real_addr_frag1, state->types1[block1][frag1], offset1, size, snapshot1);
+         new_type2 = get_offset_type(real_addr_frag2, state->types2[block2][frag2], offset1, size, snapshot2);
+       }else if(state->types1[block1][frag1] != NULL){
+         new_type1 = get_offset_type(real_addr_frag1, state->types1[block1][frag1], offset1, size, snapshot1);
+         new_type2 = get_offset_type(real_addr_frag2, state->types1[block1][frag1], offset2, size, snapshot2);
+       }else if(state->types2[block2][frag2] != NULL){
+         new_type1 = get_offset_type(real_addr_frag1, state->types2[block2][frag2], offset1, size, snapshot1);
+         new_type2 = get_offset_type(real_addr_frag2, state->types2[block2][frag2], offset2, size, snapshot2);
        }else{
          if(match_pairs){
-           match_equals(previous);
+           match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return -1;
        }   
  
-       if(new_type_id1 !=  NULL && new_type_id2 !=  NULL && !strcmp(new_type_id1, new_type_id2)){
-         if(switch_type){
-           type = xbt_dict_get_or_null(other_types, new_type_id1);
-           while(type->size == 0 && type->dw_type_id != NULL)
-             type = xbt_dict_get_or_null(other_types, type->dw_type_id);
-           new_size1 = type->size;
-           type = xbt_dict_get_or_null(other_types, new_type_id2);
-           while(type->size == 0 && type->dw_type_id != NULL)
-             type = xbt_dict_get_or_null(other_types, type->dw_type_id);
-           new_size2 = type->size;
-         }else{
-           type = xbt_dict_get_or_null(all_types, new_type_id1);
-           while(type->size == 0 && type->dw_type_id != NULL)
-             type = xbt_dict_get_or_null(all_types, type->dw_type_id);
-           new_size1 = type->size;
-           type = xbt_dict_get_or_null(all_types, new_type_id2);
-           while(type->size == 0 && type->dw_type_id != NULL)
-             type = xbt_dict_get_or_null(all_types, type->dw_type_id);
-           new_size2 = type->size;
-         }
+       if(new_type1 !=  NULL && new_type2 !=  NULL && new_type1!=new_type2){
+           type = new_type1;
+           while(type->byte_size == 0 && type->subtype != NULL)
+             type = type->subtype;
+           new_size1 = type->byte_size;
+           type = new_type2;
+           while(type->byte_size == 0 && type->subtype != NULL)
+             type = type->subtype;
+           new_size2 = type->byte_size;
        }else{
          if(match_pairs){
-           match_equals(previous);
+           match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return -1;
      area2_to_compare = (char *)addr_frag2 + offset2;
      
      if(new_size1 > 0 && new_size1 == new_size2){
-       type_id = new_type_id1;
+       type = new_type1;
        size = new_size1;
      }
  
      if(offset1 == 0 && offset2 == 0){
        if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){
          if(match_pairs){
-           match_equals(previous);
+           match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return 0;
  
      if(size <= 0){
        if(match_pairs){
-         match_equals(previous);
+         match_equals(state, previous);
          xbt_dynar_free(&previous);
        }
        return 0;
      }
        
-     if((heapinfo1[block1].busy_frag.ignore[frag1] > 0) && ( heapinfo2[block2].busy_frag.ignore[frag2] == heapinfo1[block1].busy_frag.ignore[frag1]))
-       check_ignore = heapinfo1[block1].busy_frag.ignore[frag1];
+     if((state->heapinfo1[block1].busy_frag.ignore[frag1] > 0) && ( state->heapinfo2[block2].busy_frag.ignore[frag2] == state->heapinfo1[block1].busy_frag.ignore[frag1]))
+       check_ignore = state->heapinfo1[block1].busy_frag.ignore[frag1];
      
    }else{
  
    
  
    /* Start comparison*/
-   if(type_id != NULL){
-     if(switch_type)
-       res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, other_types, all_types, type_id, size, check_ignore, pointer_level);
-     else
-       res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, type_id, size, check_ignore, pointer_level);
-     if(res_compare == 1){
-       if(match_pairs)
-         xbt_dynar_free(&previous);
-       return res_compare;
-     }
+   if(type){
+     res_compare = compare_heap_area_with_type(state, area1, area2, area1_to_compare, area2_to_compare, snapshot1, snapshot2, previous, type, size, check_ignore, pointer_level);
    }else{
-     if(switch_type)
-       res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, other_types, all_types, size, check_ignore);
-     else
-       res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, size, check_ignore);
-     if(res_compare == 1){
-       if(match_pairs)
-         xbt_dynar_free(&previous);
-       return res_compare;
-     }
+     res_compare = compare_heap_area_without_type(state, area1, area2, area1_to_compare, area2_to_compare, snapshot1, snapshot2, previous, size, check_ignore);
+   }
+   if(res_compare == 1){
+     if(match_pairs)
+       xbt_dynar_free(&previous);
+     return res_compare;
    }
  
    if(match_pairs){
-     match_equals(previous);
+     match_equals(state, previous);
      xbt_dynar_free(&previous);
    }
  
  /*********************************************** Miscellaneous ***************************************************/
  /****************************************************************************************************************/
  
+ // Not used:
+ static int get_pointed_area_size(void *area, int heap){
  
- int get_pointed_area_size(void *area, int heap){
+   struct s_mm_diff *state = mm_diff_info;
  
    int block, frag;
    malloc_info *heapinfo;
  
    if(heap == 1)
-     heapinfo = heapinfo1;
+     heapinfo = state->heapinfo1;
    else
-     heapinfo = heapinfo2;
+     heapinfo = state->heapinfo2;
  
-   block = ((char*)area - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
+   block = ((char*)area - (char*)((xbt_mheap_t)state->s_heap)->heapbase) / BLOCKSIZE + 1;
  
-   if(((char *)area < (char*)((xbt_mheap_t)s_heap)->heapbase)  || (block > heapsize1) || (block < 1))
+   if(((char *)area < (char*)((xbt_mheap_t)state->s_heap)->heapbase)  || (block > state->heapsize1) || (block < 1))
      return -1;
  
    if(heapinfo[block].type == -1){ /* Free block */
  
  }
  
- char *get_type_description(xbt_dict_t types, char *type_name){
+ // Not used:
+ char *get_type_description(mc_object_info_t info, char *type_name){
  
    xbt_dict_cursor_t dict_cursor;
    char *type_origin;
    dw_type_t type;
  
-   xbt_dict_foreach(types, dict_cursor, type_origin, type){
-     if(type->name && (strcmp(type->name, type_name) == 0) && type->size > 0){
+   xbt_dict_foreach(info->types, dict_cursor, type_origin, type){
+     if(type->name && (strcmp(type->name, type_name) == 0) && type->byte_size > 0){
        xbt_dict_cursor_free(&dict_cursor);
        return type_origin;
      }
  #define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
  #endif
  
+ // Not used:
  int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
  
+   struct s_mm_diff *state = mm_diff_info;
    if(heap1 == NULL && heap1 == NULL){
      XBT_DEBUG("Malloc descriptors null");
      return 0;
    }
  
    /* Heap information */
-   heaplimit = ((struct mdesc *)heap1)->heaplimit;
+   state->heaplimit = ((struct mdesc *)heap1)->heaplimit;
  
-   s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
 -  state->s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
++  state->s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
  
-   heapbase1 = (char *)heap1 + BLOCKSIZE;
-   heapbase2 = (char *)heap2 + BLOCKSIZE;
+   state->heapbase1 = (char *)heap1 + BLOCKSIZE;
+   state->heapbase2 = (char *)heap2 + BLOCKSIZE;
  
-   heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)heap1->heapinfo - (char *)s_heap)));
-   heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)heap2->heapinfo - (char *)s_heap)));
+   state->heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)heap1->heapinfo - (char *)state->s_heap)));
+   state->heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)heap2->heapinfo - (char *)state->s_heap)));
  
-   heapsize1 = heap1->heapsize;
-   heapsize2 = heap2->heapsize;
+   state->heapsize1 = heap1->heapsize;
+   state->heapsize2 = heap2->heapsize;
  
    /* Start comparison */
    size_t i, j, k;
  
    i = 1;
  
-   while(i <= heaplimit){
+   while(i <= state->heaplimit){
  
-     addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
-     addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
+     addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
+     addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase2));
  
-     if(heapinfo1[i].type != heapinfo2[i].type){
+     if(state->heapinfo1[i].type != state->heapinfo2[i].type){
    
        distance += BLOCKSIZE;
-       XBT_DEBUG("Different type of blocks (%zu) : %d - %d -> distance = %d", i, heapinfo1[i].type, heapinfo2[i].type, distance);
+       XBT_DEBUG("Different type of blocks (%zu) : %d - %d -> distance = %d", i, state->heapinfo1[i].type, state->heapinfo2[i].type, distance);
        i++;
      
      }else{
  
-       if(heapinfo1[i].type == -1){ /* Free block */
+       if(state->heapinfo1[i].type == -1){ /* Free block */
          i++;
          continue;
        }
  
-       if(heapinfo1[i].type == 0){ /* Large block */
+       if(state->heapinfo1[i].type == 0){ /* Large block */
         
-         if(heapinfo1[i].busy_block.size != heapinfo2[i].busy_block.size){
-           distance += BLOCKSIZE * max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
-           i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
-           XBT_DEBUG("Different larger of cluster at block %zu : %zu - %zu -> distance = %d", i, heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size, distance);
+         if(state->heapinfo1[i].busy_block.size != state->heapinfo2[i].busy_block.size){
+           distance += BLOCKSIZE * max(state->heapinfo1[i].busy_block.size, state->heapinfo2[i].busy_block.size);
+           i += max(state->heapinfo1[i].busy_block.size, state->heapinfo2[i].busy_block.size);
+           XBT_DEBUG("Different larger of cluster at block %zu : %zu - %zu -> distance = %d", i, state->heapinfo1[i].busy_block.size, state->heapinfo2[i].busy_block.size, distance);
            continue;
          }
  
          k = 0;
  
          //while(k < (heapinfo1[i].busy_block.busy_size)){
-         while(k < heapinfo1[i].busy_block.size * BLOCKSIZE){
+         while(k < state->heapinfo1[i].busy_block.size * BLOCKSIZE){
            if(memcmp((char *)addr_block1 + k, (char *)addr_block2 + k, 1) != 0){
              distance ++;
            }
  
        }else { /* Fragmented block */
  
-         for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
+         for(j=0; j < (size_t) (BLOCKSIZE >> state->heapinfo1[i].type); j++){
  
-           addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
-           addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
+           addr_frag1 = (void*) ((char *)addr_block1 + (j << state->heapinfo1[i].type));
+           addr_frag2 = (void*) ((char *)addr_block2 + (j << state->heapinfo2[i].type));
  
-           if(heapinfo1[i].busy_frag.frag_size[j] == 0 && heapinfo2[i].busy_frag.frag_size[j] == 0){
+           if(state->heapinfo1[i].busy_frag.frag_size[j] == 0 && state->heapinfo2[i].busy_frag.frag_size[j] == 0){
              continue;
            }
            
            k=0;
  
            //while(k < max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j])){
-           while(k < (BLOCKSIZE / (BLOCKSIZE >> heapinfo1[i].type))){
+           while(k < (BLOCKSIZE / (BLOCKSIZE >> state->heapinfo1[i].type))){
              if(memcmp((char *)addr_frag1 + k, (char *)addr_frag2 + k, 1) != 0){
                distance ++;
              }