Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge 'master' into mc
authorGabriel Corona <gabriel.corona@loria.fr>
Mon, 24 Feb 2014 09:04:38 +0000 (10:04 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Mon, 24 Feb 2014 09:04:38 +0000 (10:04 +0100)
Conflicts:
src/mc/mc_checkpoint.c
src/mc/mc_global.c
src/mc/mc_private.h

21 files changed:
1  2 
CMakeLists.txt
buildtools/Cmake/CompleteInFiles.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/MakeLib.cmake
include/smpi/mpi.h
include/xbt/mmalloc.h
src/include/mc/datatypes.h
src/include/mc/mc.h
src/mc/mc_checkpoint.c
src/mc/mc_compare.c
src/mc/mc_dpor.c
src/mc/mc_global.c
src/mc/mc_liveness.c
src/mc/mc_memory.c
src/mc/mc_private.h
src/mc/mc_request.c
src/mc/mc_state.c
src/simgrid/sg_config.c
src/simix/smx_network.c
src/xbt/backtrace_linux.c
src/xbt/mmalloc/mm_diff.c

diff --combined CMakeLists.txt
@@@ -4,9 -4,12 +4,12 @@@ 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()
+ enable_language(CXX)
  if (NOT DEFINED enable_smpi OR enable_smpi) # smpi is enabled by default
    # Call enable_language(Fortran) in order to load the build rules for
    # this language, needed by teshsuite/smpi/mpich-test/.  Use
@@@ -47,11 -50,12 +50,12 @@@ set(CMAKE_Fortran_LINK_FLAGS "" CACHE T
  # 3.9.0 -> release 3.9
  # 3.9.90 -> release 3.10pre1
  # 3.10.0 -> release 3.10
+ # 3.11.0 -> release 3.11
  
  set(SIMGRID_VERSION_MAJOR "3")
- set(SIMGRID_VERSION_MINOR "10")
+ set(SIMGRID_VERSION_MINOR "11")
  set(SIMGRID_VERSION_PATCH "0")
- set(SIMGRID_VERSION_EXTRA "-rc2") # Extra words to add to version string (e.g. -rc1)
+ set(SIMGRID_VERSION_EXTRA "-devel") # Extra words to add to version string (e.g. -rc1)
  
  set(SIMGRID_VERSION_DATE  "2013") # Year for copyright information
  
@@@ -166,9 -170,9 +170,9 @@@ if(WIN32
      message(FATAL_ERROR "Please use MinGW to compile SimGrid!")
    endif()
  
-   if(ARCH_32_BITS)    ### Arch 32bits
+   if(ARCH_32_BITS)      ### Arch 32bits
      set(_WIN32 1)
-   else()      ### Arch 64bits
+   else()        ### Arch 64bits
      set(_WIN64 1)
    endif()
  
  
    set(_XBT_WIN32 1)
  
-   message(STATUS "C_COMPILER                  ${CMAKE_C_COMPILER} ${COMPILER_C_VERSION}")
-   message(STATUS "CXX_COMPILER                        ${CMAKE_CXX_COMPILER} ${COMPILER_CXX_VERSION}")
-   message(STATUS "CMAKE_RC_COMPILER           ${CMAKE_RC_COMPILER}")
-   message(STATUS "INCLUDE                     ${CMAKE_INCLUDE_WIN}")
-   message(STATUS "LIB                         ${CMAKE_LIB_WIN}")
-   message(STATUS "MAKE_PROGRAM                        ${CMAKE_MAKE_PROGRAM}")
-   message(STATUS "CMAKE_BUILD_TOOL            ${CMAKE_BUILD_TOOL}")
-   message(STATUS "LINKER                      ${CMAKE_LINKER}")
-   message(STATUS "CMAKE_GENERATOR             ${CMAKE_GENERATOR}")
-   message(STATUS "BORLAND                     ${BORLAND}")
-   message(STATUS "VISUALC                     ${MSVC}")
-   message(STATUS "GNUC                                ${CMAKE_COMPILER_IS_GNUCC}")
+   message(STATUS "C_COMPILER                    ${CMAKE_C_COMPILER} ${COMPILER_C_VERSION}")
+   message(STATUS "CXX_COMPILER                  ${CMAKE_CXX_COMPILER} ${COMPILER_CXX_VERSION}")
+   message(STATUS "CMAKE_RC_COMPILER             ${CMAKE_RC_COMPILER}")
+   message(STATUS "INCLUDE                       ${CMAKE_INCLUDE_WIN}")
+   message(STATUS "LIB                           ${CMAKE_LIB_WIN}")
+   message(STATUS "MAKE_PROGRAM                  ${CMAKE_MAKE_PROGRAM}")
+   message(STATUS "CMAKE_BUILD_TOOL              ${CMAKE_BUILD_TOOL}")
+   message(STATUS "LINKER                        ${CMAKE_LINKER}")
+   message(STATUS "CMAKE_GENERATOR               ${CMAKE_GENERATOR}")
+   message(STATUS "BORLAND                       ${BORLAND}")
+   message(STATUS "VISUALC                       ${MSVC}")
+   message(STATUS "GNUC                          ${CMAKE_COMPILER_IS_GNUCC}")
  
  endif()
  
@@@ -9,7 -9,7 +9,7 @@@ set(CMAKE_MODULE_PAT
  
  ### Determine the assembly flavor that we need today
  include(CMakeDetermineSystem)
- IF(CMAKE_SYSTEM_PROCESSOR MATCHES ".86|AMD64")
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES ".86|AMD64|amd64")
    IF(${ARCH_32_BITS})
      message(STATUS "System processor: i686 (${CMAKE_SYSTEM_PROCESSOR}, 32 bits)")
      set(PROCESSOR_i686 1)
@@@ -73,6 -73,7 +73,7 @@@ include(TestBigEndian
  TEST_BIG_ENDIAN(BIGENDIAN)
  
  include(FindGraphviz)
+ include(FindLibSigc++)
  
  set(HAVE_GTNETS 0)
  if(enable_gtnets)
@@@ -98,6 -99,13 +99,13 @@@ if(enable_ns3
    include(FindNS3)
  endif()
  
+ find_package(Boost REQUIRED)
+ if(Boost_FOUND)
+   include_directories(${Boost_INCLUDE_DIRS})
+ else()
+   message(FATAL_ERROR, "Failed to find Boost libraries")
+ endif()
  # Checks for header libraries functions.
  CHECK_LIBRARY_EXISTS(pthread pthread_create          "" pthread)
  CHECK_LIBRARY_EXISTS(pthread sem_init                "" HAVE_SEM_INIT_LIB)
@@@ -148,7 -156,6 +156,6 @@@ CHECK_FUNCTION_EXISTS(asprintf HAVE_ASP
  CHECK_FUNCTION_EXISTS(vasprintf HAVE_VASPRINTF)
  CHECK_FUNCTION_EXISTS(makecontext HAVE_MAKECONTEXT)
  CHECK_FUNCTION_EXISTS(mmap HAVE_MMAP)
- CHECK_FUNCTION_EXISTS(mergesort HAVE_MERGESORT)
  
  #Check if __thread is defined
  execute_process(
    )
  
  if(HAVE_thread_storage_run)
-   set(HAVE_THREAD_LOCAL_STORAGE 0)
- else()
    set(HAVE_THREAD_LOCAL_STORAGE 1)
+ else()
+   set(HAVE_THREAD_LOCAL_STORAGE 0)
  endif()
  
  # Our usage of mmap is Linux-specific (flag MAP_ANONYMOUS), but kFreeBSD uses a GNU libc
  IF(NOT "${CMAKE_SYSTEM}" MATCHES "Linux" AND NOT "${CMAKE_SYSTEM}" MATCHES "kFreeBSD" AND NOT "${CMAKE_SYSTEM}" MATCHES "GNU" AND NOT  "${CMAKE_SYSTEM}" MATCHES "Darwin")
    SET(HAVE_MMAP 0)
    message(STATUS "Warning: MMAP is thought as non functional on this architecture (${CMAKE_SYSTEM})")
- ENDIF(NOT "${CMAKE_SYSTEM}" MATCHES "Linux" AND NOT "${CMAKE_SYSTEM}" MATCHES "kFreeBSD" AND NOT "${CMAKE_SYSTEM}" MATCHES "GNU" AND NOT  "${CMAKE_SYSTEM}" MATCHES "Darwin")
+ ENDIF()
+ if(HAVE_MMAP AND HAVE_THREAD_LOCAL_STORAGE)
+   SET(HAVE_MMALLOC 1)
+ else()
+   SET(HAVE_MMALLOC 0)
+ endif()
  
  if(WIN32) #THOSE FILES ARE FUNCTIONS ARE NOT DETECTED BUT THEY SHOULD...
    set(HAVE_UCONTEXT_H 1)
@@@ -208,12 -221,14 +221,15 @@@ else(
    SET(MALLOCATOR_IS_WANTED 0)
  endif()
  
- if(enable_model-checking AND HAVE_MMAP)
+ if(enable_model-checking AND HAVE_MMALLOC)
    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")
+   endif()
    SET(HAVE_MC 0)
    SET(MMALLOC_WANT_OVERRIDE_LEGACY 0)
  endif()
@@@ -483,7 -498,7 +499,7 @@@ endif(
  ###############
  ## GIT version check
  ##
- if(EXISTS ${CMAKE_HOME_DIRECTORY}/.git/ AND NOT WIN32)
+ if(EXISTS ${CMAKE_HOME_DIRECTORY}/.git/)
    execute_process(COMMAND git remote
    COMMAND head -n 1
    WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/.git/
      message(STATUS "Git date: ${GIT_DATE}")
      string(REGEX REPLACE " .*" "" GIT_VERSION "${GIT_VERSION}")
    endif()
+ elseif(EXISTS ${CMAKE_HOME_DIRECTORY}/.gitversion)
+   FILE(STRINGS ${CMAKE_HOME_DIRECTORY}/.gitversion GIT_VERSION)
  endif()
  
  if(release)
@@@ -810,6 -827,7 +828,7 @@@ if(HAVE_NS3_LIB
  endif()
  set(CMAKE_SMPI_COMMAND "${CMAKE_SMPI_COMMAND}:\${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}\"")
  
+ file(READ ${CMAKE_HOME_DIRECTORY}/src/smpi/smpitools.sh SMPITOOLS_SH)
  configure_file(${CMAKE_HOME_DIRECTORY}/include/smpi/mpif.h.in ${CMAKE_BINARY_DIR}/include/smpi/mpif.h @ONLY)
  configure_file(${CMAKE_HOME_DIRECTORY}/include/smpi/smpif.h.in ${CMAKE_BINARY_DIR}/include/smpi/smpif.h @ONLY)
  configure_file(${CMAKE_HOME_DIRECTORY}/src/smpi/smpicc.in ${CMAKE_BINARY_DIR}/bin/smpicc @ONLY)
@@@ -876,8 -894,6 +895,6 @@@ set(generated_files_to_clea
    ${CMAKE_BINARY_DIR}/bin/colorize
    ${CMAKE_BINARY_DIR}/bin/simgrid_update_xml
    ${CMAKE_BINARY_DIR}/examples/smpi/tracing/smpi_traced.trace
-   ${CMAKE_BINARY_DIR}/src/supernovae_sg.c
-   ${CMAKE_BINARY_DIR}/src/supernovae_smpi.c
    )
  
  if("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_HOME_DIRECTORY}")
@@@ -2,7 -2,7 +2,7 @@@
  
  set(EXTRA_DIST
    include/xbt/win32_ucontext.h
-   src/bindings/java/MANIFEST.MF
+   src/bindings/java/MANIFEST.MF.in
    src/include/instr/instr_interface.h
    src/include/mc/datatypes.h
    src/include/mc/mc.h
@@@ -19,7 -19,6 +19,6 @@@
    src/include/surf/trace_mgr.h
    src/include/xbt/wine_dbghelp.h
    src/include/xbt/xbt_os_time.h
-   src/mk_supernovae.pl
    src/msg/msg_mailbox.h
    src/msg/msg_private.h
    src/portable.h
    src/simdag/dax_dtd.c
    src/simdag/dax_dtd.h
    src/simdag/private.h
+   src/simix/simcalls.in
+   src/simix/simcalls.py
+   src/simix/simcalls_generated_enum.h
+   src/simix/simcalls_generated_string.c
+   src/simix/simcalls_generated_res_getter_setter.h
+   src/simix/simcalls_generated_args_getter_setter.h
+   src/simix/simcalls_generated_case.c
+   src/simix/simcalls_generated_body.c
    src/simix/smx_host_private.h
    src/simix/smx_io_private.h
    src/simix/smx_network_private.h
    src/smpi/colls/coll_tuned_topo.h
    src/smpi/private.h
    src/smpi/smpi_mpi_dt_private.h
-   src/surf/cpu_cas01_private.h
-   src/surf/cpu_ti_private.h
+   src/surf/plugins/energy.hpp
+   src/surf/cpu_interface.hpp
+   src/surf/cpu_ti.hpp
+   src/surf/cpu_cas01.hpp
    src/surf/gtnets/gtnets_interface.h
    src/surf/gtnets/gtnets_simulator.h
    src/surf/gtnets/gtnets_topology.h
-   src/surf/maxmin_private.h
-   src/surf/network_gtnets_private.h
-   src/surf/network_ns3_private.h
-   src/surf/network_private.h
+   src/surf/maxmin_private.hpp
+   src/surf/network_interface.hpp
+   src/surf/network_gtnets.hpp
+   src/surf/network_ns3.hpp
+   src/surf/network_cm02.hpp
+   src/surf/network_smpi.hpp
+   src/surf/network_constant.hpp
    src/surf/ns3/my-point-to-point-helper.h
    src/surf/ns3/ns3_interface.h
    src/surf/ns3/ns3_simulator.h
    src/surf/platf_generator_private.h
    src/surf/simgrid.dtd
    src/surf/simgrid_dtd.c
-   src/surf/storage_private.h
+   src/surf/storage_interface.hpp
+   src/surf/storage_n11.hpp
+   src/surf/surf_interface.hpp
    src/surf/surf_private.h
-   src/surf/surf_routing_private.h
+   src/surf/surf_routing_private.hpp
+   src/surf/surf_routing.hpp
+   src/surf/surf_routing_cluster.hpp
+   src/surf/surf_routing_cluster_torus.hpp
+   src/surf/surf_routing_dijkstra.hpp
+   src/surf/surf_routing_floyd.hpp
+   src/surf/surf_routing_full.hpp
+   src/surf/surf_routing_generic.hpp
+   src/surf/surf_routing_none.hpp
+   src/surf/surf_routing_vivaldi.hpp
    src/surf/surfxml_parse.c
    src/surf/trace_mgr_private.h
+   src/surf/vm_workstation_interface.hpp
+   src/surf/vm_workstation_hl13.hpp
+   src/surf/workstation_interface.hpp
+   src/surf/workstation_clm03.hpp
+   src/surf/workstation_ptask_L07.hpp
    src/win32/config.h
    src/xbt/automaton/automaton_lexer.yy.c
    src/xbt/automaton/parserPromela.lex
@@@ -257,7 -285,7 +285,7 @@@ set(XBT_SR
    src/xbt_modinter.h
    )
  
- if(HAVE_MMAP)
+ if(HAVE_MMALLOC)
    set(XBT_SRC
      ${XBT_SRC}
      src/xbt/mmalloc/mm.c
@@@ -268,11 -296,11 +296,11 @@@ set(GTNETS_SR
    src/surf/gtnets/gtnets_interface.cc
    src/surf/gtnets/gtnets_simulator.cc
    src/surf/gtnets/gtnets_topology.cc
-   src/surf/network_gtnets.c
+   src/surf/network_gtnets.cpp
    )
  
  set(NS3_SRC
-   src/surf/network_ns3.c
+   src/surf/network_ns3.cpp
    src/surf/ns3/my-point-to-point-helper.cc
    src/surf/ns3/ns3_interface.cc
    src/surf/ns3/ns3_simulator.cc
    )
  
  set(SURF_SRC
-   src/surf/cpu_cas01.c
-   src/surf/cpu_ti.c
-   src/surf/fair_bottleneck.c
+   src/surf/plugins/energy.cpp
+   src/surf/cpu_interface.cpp
+   src/surf/cpu_ti.cpp
+   src/surf/cpu_cas01.cpp
+   src/surf/fair_bottleneck.cpp
    src/surf/instr_routing.c
    src/surf/instr_surf.c
-   src/surf/lagrange.c
-   src/surf/maxmin.c
-   src/surf/network.c
-   src/surf/network_constant.c
+   src/surf/lagrange.cpp
+   src/surf/maxmin.cpp
+   src/surf/network_interface.cpp
+   src/surf/network_cm02.cpp
+   src/surf/network_smpi.cpp  
+   src/surf/network_constant.cpp
    src/surf/platf_generator.c
    src/surf/random_mgr.c
    src/surf/sg_platf.c
-   src/surf/storage.c
-   src/surf/surf.c
-   src/surf/surf_action.c
-   src/surf/surf_model.c
-   src/surf/surf_routing.c
-   src/surf/surf_routing_cluster.c
-   src/surf/surf_routing_dijkstra.c
-   src/surf/surf_routing_floyd.c
-   src/surf/surf_routing_full.c
-   src/surf/surf_routing_generic.c
-   src/surf/surf_routing_none.c
-   src/surf/surf_routing_vivaldi.c
+   src/surf/storage_interface.cpp
+   src/surf/storage_n11.cpp
+   src/surf/surf_interface.cpp
+   src/surf/surf_c_bindings.cpp
+   src/surf/surf_routing.cpp  
+   src/surf/surf_routing_cluster.cpp
+   src/surf/surf_routing_cluster_torus.cpp
+   src/surf/surf_routing_dijkstra.cpp
+   src/surf/surf_routing_floyd.cpp
+   src/surf/surf_routing_full.cpp
+   src/surf/surf_routing_generic.cpp
+   src/surf/surf_routing_none.cpp
+   src/surf/surf_routing_vivaldi.cpp
    src/surf/surfxml_parse.c
    src/surf/surfxml_parseplatf.c
    src/surf/trace_mgr.c
-   src/surf/workstation.c
-   src/surf/workstation_ptask_L07.c
+   src/surf/workstation_interface.cpp
+   src/surf/workstation_clm03.cpp
+   src/surf/workstation_ptask_L07.cpp
+   src/surf/vm_workstation_interface.cpp
+   src/surf/vm_workstation_hl13.cpp
    src/xbt/xbt_sg_stubs.c
    )
  
@@@ -326,6 -362,7 +362,7 @@@ set(SIMIX_SR
    src/simix/smx_smurf.c
    src/simix/smx_synchro.c
    src/simix/smx_user.c
+   src/simix/smx_vm.c
    )
  
  set(SIMGRID_SRC
@@@ -367,19 -404,6 +404,6 @@@ set(SIMIX_SR
  )
  #* ****************************************************************************************** *#
  
- #* ****************************************************************************************** *#
- #* TUTORIAL: New Model                                                                        *#
- set(SURF_SRC
-   ${SURF_SRC}
-   src/surf/new_model.c
-   )
- set(EXTRA_DIST
-   ${EXTRA_DIST}
-   src/surf/new_model_private.h
-   )
- #* ****************************************************************************************** *#
  set(SIMDAG_SRC
    src/simdag/instr_sd_task.c
    src/simdag/sd_daxloader.c
@@@ -446,12 -470,13 +470,13 @@@ set(JMSG_JAVA_SR
    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/Semaphore.java
    src/bindings/java/org/simgrid/msg/NativeException.java
+   src/bindings/java/org/simgrid/msg/NativeLib.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/RngStream.java
+   src/bindings/java/org/simgrid/msg/Semaphore.java
    src/bindings/java/org/simgrid/msg/Task.java
    src/bindings/java/org/simgrid/msg/TaskCancelledException.java
    src/bindings/java/org/simgrid/msg/TimeoutException.java
@@@ -517,7 -542,6 +542,7 @@@ set(MC_SR
    src/mc/mc_compare.c
    src/mc/mc_dpor.c
    src/mc/mc_global.c
 +  src/mc/mc_dwarf.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
+   include/simgrid.h
    include/instr/instr.h
    include/msg/datatypes.h
    include/msg/msg.h
    include/simdag/datatypes.h
    include/simdag/simdag.h
+   include/simgrid/datatypes.h
    include/simgrid/modelchecker.h
    include/simgrid/platf.h
    include/simgrid/platf_generator.h
+   include/simgrid/plugins.h
    include/simgrid/simix.h
    include/smpi/mpi.h
    include/smpi/smpi.h
@@@ -824,6 -849,7 +852,7 @@@ set(bin_file
    src/smpi/smpiff.in
    src/smpi/smpif90.in
    src/smpi/smpirun.in
+   src/smpi/smpitools.sh
    )
  
  set(txt_files
@@@ -847,6 -873,7 +876,7 @@@ set(EXAMPLES_CMAKEFILES_TX
    examples/java/bittorrent/CMakeLists.txt
    examples/java/chord/CMakeLists.txt
    examples/java/cloud/CMakeLists.txt
+   examples/java/cloud/migration/CMakeLists.txt
    examples/java/commTime/CMakeLists.txt
    examples/java/io/CMakeLists.txt
    examples/java/kademlia/CMakeLists.txt
@@@ -931,6 -958,7 +961,7 @@@ set(TESHSUITE_CMAKEFILES_TX
    teshsuite/smpi/mpich3-test/group/CMakeLists.txt
    teshsuite/smpi/mpich3-test/init/CMakeLists.txt
    teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f77/util/CMakeLists.txt
  #  teshsuite/smpi/mpich3-test/f77/attr/CMakeLists.txt
    teshsuite/smpi/mpich3-test/f77/coll/CMakeLists.txt
    teshsuite/smpi/mpich3-test/f77/comm/CMakeLists.txt
    teshsuite/smpi/mpich3-test/f77/ext/CMakeLists.txt
    teshsuite/smpi/mpich3-test/f77/init/CMakeLists.txt
    teshsuite/smpi/mpich3-test/f77/pt2pt/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f90/util/CMakeLists.txt
    teshsuite/smpi/mpich3-test/f90/coll/CMakeLists.txt
    teshsuite/smpi/mpich3-test/f90/datatype/CMakeLists.txt
    teshsuite/smpi/mpich3-test/f90/init/CMakeLists.txt
@@@ -976,8 -1005,8 +1008,9 @@@ set(CMAKE_SOURCE_FILE
    buildtools/Cmake/Modules/FindGFortran.cmake
    buildtools/Cmake/Modules/FindGTnets.cmake
    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
    buildtools/Cmake/Scripts/SimGrid.packproj
    buildtools/Cmake/Scripts/generate_memcheck_tests.pl
    buildtools/Cmake/Scripts/generate_new_tests.pl
+   buildtools/Cmake/Scripts/java_bundle.sh
    buildtools/Cmake/Scripts/my_valgrind.pl
    buildtools/Cmake/Scripts/postinstall.sh
    buildtools/Cmake/Scripts/preinstall.sh
    buildtools/Cmake/Scripts/tesh.pl
    buildtools/Cmake/Scripts/update_tesh.pl
-   buildtools/Cmake/Supernovae.cmake
    buildtools/Cmake/UnitTesting.cmake
    buildtools/Cmake/src/internal_config.h.in
    buildtools/Cmake/src/simgrid.nsi.in
@@@ -1031,6 -1060,7 +1064,7 @@@ set(PLATFORMS_EXAMPLE
    examples/platforms/conf/lcg_sept2004_grid.xml
    examples/platforms/conf/transform_optorsim_platform.pl
    examples/platforms/config.xml
+   examples/platforms/content/small_content.txt
    examples/platforms/content/storage_content.txt
    examples/platforms/content/win_storage_content.txt
    examples/platforms/data_center.xml
    examples/platforms/generation_scripts/generate_g5k_platform.pl
    examples/platforms/generation_scripts/generate_g5k_platform_cabinets.pl
    examples/platforms/griffon.xml
+   examples/platforms/torus_cluster.xml
    examples/platforms/meta_cluster.xml
    examples/platforms/multicore_machine.xml
    examples/platforms/prop.xml
@@@ -3,11 -3,8 +3,8 @@@
  ###############################
  # Declare the library content #
  ###############################
- # If we want supernovae, rewrite the libs' content to use it
- include(${CMAKE_HOME_DIRECTORY}/buildtools/Cmake/Supernovae.cmake)
  
  # Actually declare our libraries
  add_library(simgrid SHARED ${simgrid_sources})
  set_target_properties(simgrid PROPERTIES VERSION ${libsimgrid_version})
  
@@@ -21,24 -18,9 +18,9 @@@ endif(
  
  add_dependencies(simgrid maintainer_files)
  
- # if supernovaeing, we need some depends to make sure that the source gets generated
- if (enable_supernovae)
-   add_dependencies(simgrid ${CMAKE_CURRENT_BINARY_DIR}/src/supernovae_sg.c)
-   if(enable_lib_static)
-     add_dependencies(simgrid_static ${CMAKE_CURRENT_BINARY_DIR}/src/supernovae_sg.c)
-   endif()
-   if(enable_smpi)
-     add_dependencies(simgrid ${CMAKE_CURRENT_BINARY_DIR}/src/supernovae_smpi.c)
-     if(enable_lib_static)
-       add_dependencies(simgrid_static ${CMAKE_CURRENT_BINARY_DIR}/src/supernovae_smpi.c)
-     endif()
-   endif()
- endif()
  # Compute the dependencies of SimGrid
  #####################################
- set(SIMGRID_DEP "-lm")
+ set(SIMGRID_DEP "-lm -lstdc++")
  
  if(pthread)
    if(${CONTEXT_THREADS})
@@@ -82,6 -64,10 +64,10 @@@ if(HAVE_GRAPHVIZ
    endif()
  endif()
  
+ if(HAVE_LIBSIGC++)
+   SET(SIMGRID_DEP "${SIMGRID_DEP} -lsigc-2.0")          
+ endif()
  if(HAVE_GTNETS)
    SET(SIMGRID_DEP "${SIMGRID_DEP} -lgtnets")
  endif()
@@@ -91,9 -77,6 +77,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)
@@@ -108,12 -91,12 +94,12 @@@ if(MMALLOC_WANT_OVERRIDE_LEGACY AND HAV
  endif()
  
  if(HAVE_NS3)
-   if(${NS3_VERSION} EQUAL 310)
+   if(${NS3_VERSION_MINOR} EQUAL 10)
      SET(SIMGRID_DEP "${SIMGRID_DEP} -lns3")
      set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_NS3_3_10")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_NS3_3_10")
    else()
-     SET(SIMGRID_DEP "${SIMGRID_DEP} -lns3-core -lns3-csma -lns3-point-to-point -lns3-internet -lns3-applications")
+     SET(SIMGRID_DEP "${SIMGRID_DEP} -lns3.${NS3_VERSION_MINOR}-core -lns3.${NS3_VERSION_MINOR}-csma -lns3.${NS3_VERSION_MINOR}-point-to-point -lns3.${NS3_VERSION_MINOR}-internet -lns3.${NS3_VERSION_MINOR}-applications")
    endif()
  endif()
  
@@@ -139,6 -122,9 +125,9 @@@ endif(
  
  # Dependencies from maintainer mode
  ###################################
+ if(enable_maintainer_mode AND PYTHON_EXE)
+   add_dependencies(simgrid simcalls_generated_src)
+ endif()
  if(enable_maintainer_mode AND BISON_EXE AND LEX_EXE)
    add_dependencies(simgrid automaton_generated_src)
  endif()
diff --combined include/smpi/mpi.h
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2010-2012. The SimGrid Team.
+ /* Copyright (c) 2010-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
  #include <xbt/sysdep.h>
  #include <xbt/log.h>
  #include <xbt/asserts.h>
 +#include <simgrid/modelchecker.h>
 +
 +#ifdef HAVE_MC
 +#undef assert
 +#define assert(x) MC_assert(x)
 +#endif
  
  #endif
diff --combined include/xbt/mmalloc.h
@@@ -1,13 -1,12 +1,12 @@@
  /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
     This file was then part of the GNU C Library. */
  
- /* Copyright (c) 2010-2013. The SimGrid Team.
+ /* Copyright (c) 2010-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
  
  #ifndef MMALLOC_H
  #define MMALLOC_H 1
  
@@@ -20,7 -19,6 +19,7 @@@
  
  #include "xbt/dynar.h"
  #include "xbt/dict.h"
 +#include "mc/datatypes.h"
  
  /* Datatype representing a separate heap. The whole point of the mmalloc module
   * is to allow several such heaps in the process. It thus works by redefining
@@@ -39,7 -37,6 +38,7 @@@ void *mmalloc_no_memset(xbt_mheap_t mdp
  
  /* Re-allocate the previously allocated block in void*, making the new block
     SIZE bytes long.  */
 +
  XBT_PUBLIC( void ) *mrealloc(xbt_mheap_t md, void *ptr, size_t size);
  
  /* Free a block allocated by `mmalloc', `mrealloc' or `mcalloc'.  */
@@@ -58,11 -55,12 +57,11 @@@ XBT_PUBLIC( xbt_mheap_t ) mmalloc_get_d
  void mmalloc_set_current_heap(xbt_mheap_t new_heap);
  xbt_mheap_t mmalloc_get_current_heap(void);
  
 -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(xbt_mheap_t heap1, xbt_mheap_t heap2, mc_object_info_t info, mc_object_info_t other_info);
  int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2);
  int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t to_ignore1, xbt_dynar_t to_ignore2);
 -int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type, int pointer_level);
 +int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, mc_object_info_t info, mc_object_info_t other_info, char *type, int pointer_level);
  void reset_heap_information(void);
 -int get_pointed_area_size(void *area, int heap);
  
  size_t mmalloc_get_bytes_used(xbt_mheap_t);
  ssize_t mmalloc_get_busy_size(xbt_mheap_t, void *ptr);
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -6,16 -6,10 +6,16 @@@
  
  #ifndef MC_DATATYPE_H
  #define MC_DATATYPE_H
 +
 +#define UNW_LOCAL_ONLY
 +
  #include "xbt/misc.h"
  #include "xbt/swag.h"
  #include "xbt/fifo.h"
  
 +#include <libunwind.h>
 +#include <dwarf.h>
 +
  SG_BEGIN_DECL()
  
  /******************************* Transitions **********************************/
@@@ -43,31 -37,34 +43,31 @@@ typedef struct s_stack_region
  void heap_ignore_region_free(mc_heap_ignore_region_t r);
  void heap_ignore_region_free_voidp(void *r);
  
 +/************ Object info *************/
 +
 +typedef struct s_mc_object_info s_mc_object_info_t, *mc_object_info_t;
 +
  /************ DWARF structures *************/
  
 -typedef enum{
 -  e_dw_base_type = 0,
 -  e_dw_enumeration_type,
 -  e_dw_enumerator,
 -  e_dw_typedef,
 -  e_dw_const_type,
 -  e_dw_array_type,
 -  e_dw_pointer_type,
 -  e_dw_structure_type,
 -  e_dw_union_type,
 -  e_dw_subroutine_type,
 -  e_dw_volatile_type
 -}e_dw_type_type;
 -
 -typedef struct s_dw_type{
 +typedef int e_dw_type_type;
 +
 +typedef struct s_dw_type s_dw_type_t, *dw_type_t;
 +
 +struct s_dw_type{
    e_dw_type_type type;
 -  void *id;
 -  char *name;
 -  int size;
 -  char *dw_type_id;
 -  xbt_dynar_t members; /* if DW_TAG_structure_type */
 +  void *id; /* Offset in the section (in hexadecimal form) */
 +  char *name; /* Name of the type */
 +  int byte_size; /* Size in bytes */
 +  int element_count; /* Number of elements for array type */
 +  char *dw_type_id; /* DW_AT_type */
 +  xbt_dynar_t members; /* if DW_TAG_structure_type, DW_TAG_union_type*/
    int is_pointer_type;
    int offset;
 -}s_dw_type_t, *dw_type_t;
 +  dw_type_t subtype;
 +  dw_type_t other_object_same_type; // The same (but more complete) type in the other object.
 +};
  
 -char* get_type_description(xbt_dict_t types, char *type_name);
 +char* get_type_description(mc_object_info_t info, char *type_name);
  
  SG_END_DECL()
  #endif                          /* _MC_MC_H */
diff --combined src/include/mc/mc.h
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -26,11 -26,9 +26,11 @@@ 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 xbt_dynar_t mc_heap_comparison_ignore;
  extern xbt_dynar_t stacks_areas;
@@@ -42,11 -40,9 +42,11 @@@ 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);
  
  XBT_PUBLIC(void) MC_do_the_modelcheck_for_real(void);
  
diff --combined src/mc/mc_checkpoint.c
@@@ -1,31 -1,29 +1,31 @@@
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
  
 -#include <libgen.h>
 +#define _GNU_SOURCE
 +#define UNW_LOCAL_ONLY
 +
 +#include <string.h>
 +#include <link.h>
  #include "mc_private.h"
  #include "xbt/module.h"
 +#include <xbt/mmalloc.h>
 +
 +#include "xbt/mmalloc/mmprivate.h"
  
  #include "../simix/smx_private.h"
  
  #include <libunwind.h>
 +#include <libelf.h>
 +
 +#include "mc_private.h"
  
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc,
                                  "Logging specific to mc_checkpoint");
  
 -void *start_text_libsimgrid;
 -void *start_plt_libsimgrid, *end_plt_libsimgrid;
 -void *start_got_plt_libsimgrid, *end_got_plt_libsimgrid;
 -void *start_plt_binary, *end_plt_binary;
 -void *start_got_plt_binary, *end_got_plt_binary;
  char *libsimgrid_path;
 -void *start_data_libsimgrid, *start_bss_libsimgrid;
 -void *start_data_binary, *start_bss_binary;
 -void *start_text_binary;
  
  /************************************  Free functions **************************************/
  /*****************************************************************************************/
@@@ -33,7 -31,6 +33,7 @@@
  static void MC_snapshot_stack_free(mc_snapshot_stack_t s){
    if(s){
      xbt_dynar_free(&(s->local_variables));
 +    xbt_dynar_free(&(s->stack_frames));
      xbt_free(s);
    }
  }
@@@ -45,6 -42,7 +45,6 @@@ static void MC_snapshot_stack_free_void
  static void local_variable_free(local_variable_t v){
    xbt_free(v->frame);
    xbt_free(v->name);
 -  xbt_free(v->type);
    xbt_free(v);
  }
  
@@@ -75,10 -73,10 +75,10 @@@ void MC_free_snapshot(mc_snapshot_t sna
  
  static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size)
  {
 -  mc_mem_region_t new_reg = xbt_new0(s_mc_mem_region_t, 1);
 +  mc_mem_region_t new_reg = xbt_new(s_mc_mem_region_t, 1);
    new_reg->start_addr = start_addr;
    new_reg->size = size;
 -  new_reg->data = xbt_malloc0(size);
 +  new_reg->data = xbt_malloc(size);
    memcpy(new_reg->data, start_addr, size);
  
    XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu", type, new_reg->data, start_addr, size);
@@@ -104,235 -102,561 +104,235 @@@ static void MC_snapshot_add_region(mc_s
  
  static void MC_get_memory_regions(mc_snapshot_t snapshot){
  
 -  FILE *fp;
 -  char *line = NULL;
 -  ssize_t read;
 -  size_t n = 0;
 -  
 -  char *lfields[6] = {0}, *tok;
 -  void *start_addr, *start_addr1, *end_addr;
 -  size_t size;
 -  int i;
 -
 -  fp = fopen("/proc/self/maps", "r");
 -  
 -  xbt_assert(fp, 
 -             "Cannot open /proc/self/maps to investigate the memory map of the process. Please report this bug.");
 -
 -  setbuf(fp, NULL);
 -
 -  while((read = xbt_getline(&line, &n, fp)) != -1){
 -
 -    /* Wipeout the new line character */
 -    line[read - 1] = '\0';
 -
 -    /* Tokenize the line using spaces as delimiters and store each token */
 -    lfields[0] = strtok(line, " ");
 -
 -    for (i = 1; i < 6 && lfields[i - 1] != NULL; i++) {
 -      lfields[i] = strtok(NULL, " ");
 -    }
 -
 -    /* First get the permissions flags, need write permission */
 -    if(lfields[1][1] == 'w'){
 -
 -      /* Get the start address of the map */
 -      tok = strtok(lfields[0], "-");
 -      start_addr = (void *)strtoul(tok, NULL, 16);
 -    
 -      if(start_addr == std_heap){     /* Std_heap ? */
 -        tok = strtok(NULL, "-");
 -        end_addr = (void *)strtoul(tok, NULL, 16);
 -        MC_snapshot_add_region(snapshot, 0, start_addr, (char*)end_addr - (char*)start_addr);
 -        snapshot->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
 -      }else{ /* map name == libsimgrid || binary_name ? */
 -        if(lfields[5] != NULL){
 -          if(!memcmp(basename(lfields[5]), "libsimgrid", 10)){
 -            tok = strtok(NULL, "-");
 -            end_addr = (void *)strtoul(tok, NULL, 16);
 -            size = (char*)end_addr - (char*)start_addr;
 -            /* BSS and data segments may be separated according to the OS */
 -            if((read = xbt_getline(&line, &n, fp)) != -1){
 -              line[read - 1] = '\0';
 -              lfields[0] = strtok(line, " ");
 -              for (i = 1; i < 6 && lfields[i - 1] != NULL; i++) {
 -                lfields[i] = strtok(NULL, " ");
 -              }
 -              if(lfields[1][1] == 'w' && lfields[5] == NULL){
 -                tok = strtok(lfields[0], "-");
 -                start_addr1 = (void *)strtoul(tok, NULL, 16);
 -                tok = strtok(NULL, "-");
 -                size += (char *)(void *)strtoul(tok, NULL, 16) - (char*)start_addr1;
 -              }
 -            }
 -            MC_snapshot_add_region(snapshot, 1, start_addr, size);
 -          }else if(!memcmp(basename(lfields[5]), basename(xbt_binary_name), strlen(basename(xbt_binary_name)))){
 -            tok = strtok(NULL, "-");
 -            end_addr = (void *)strtoul(tok, NULL, 16);
 -            size = (char*)end_addr - (char*)start_addr;
 -             /* BSS and data segments may be separated according to the OS */
 -            if((read = xbt_getline(&line, &n, fp)) != -1){
 -              line[read - 1] = '\0';
 -              lfields[0] = strtok(line, " ");
 -              for (i = 1; i < 6 && lfields[i - 1] != NULL; i++) {
 -                lfields[i] = strtok(NULL, " ");
 -              }
 -              tok = strtok(lfields[0], "-");
 -              start_addr1 = (void *)strtoul(tok, NULL, 16);
 -              if(lfields[1][1] == 'w' && lfields[5] == NULL){
 -                if(start_addr1 == std_heap){     /* Std_heap ? */
 -                  tok = strtok(NULL, "-");
 -                  end_addr = (void *)strtoul(tok, NULL, 16);
 -                  MC_snapshot_add_region(snapshot, 0, start_addr1, (char*)end_addr - (char*)start_addr1);
 -                  snapshot->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
 -                }else if(start_addr1 != raw_heap){
 -                  tok = strtok(NULL, "-");
 -                  size += (char *)(void *)strtoul(tok, NULL, 16) - (char *)start_addr1;
 -                }
 -              }
 -            }
 -            MC_snapshot_add_region(snapshot, 2, start_addr, size);
 -          }else if (!memcmp(lfields[5], "[stack]", 7)){
 -            maestro_stack_start = start_addr;
 -            tok = strtok(NULL, "-");
 -            maestro_stack_end = (void *)strtoul(tok, NULL, 16);
 -          }
 -        }
 -      }
 -    }
 -    
 -  }
 -
 -  free(line);
 -  fclose(fp);
 +  void* start_heap = ((xbt_mheap_t)std_heap)->base;
 +  void* end_heap   = ((xbt_mheap_t)std_heap)->breakval;
 +  MC_snapshot_add_region(snapshot, 0, start_heap, (char*) end_heap - (char*) start_heap);
 +  snapshot->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
  
 +  MC_snapshot_add_region(snapshot, 1,  mc_libsimgrid_info->start_rw, mc_libsimgrid_info->end_rw - mc_libsimgrid_info->start_rw);
 +  MC_snapshot_add_region(snapshot, 2,  mc_binary_info->start_rw, mc_binary_info->end_rw - mc_binary_info->start_rw);
  }
  
 +/** @brief Finds the range of the different memory segments and binary paths */
  void MC_init_memory_map_info(){
   
    unsigned int i = 0;
    s_map_region_t reg;
    memory_map_t maps = MC_get_memory_map();
  
 +  maestro_stack_start = NULL;
 +  maestro_stack_end = NULL;
 +  libsimgrid_path = NULL;
 +
    while (i < maps->mapsize) {
      reg = maps->regions[i];
 -    if ((reg.prot & PROT_WRITE)){
 -      if (maps->regions[i].pathname != NULL){
 -        if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
 -          start_data_libsimgrid = reg.start_addr;
 -          i++;
 -          reg = maps->regions[i];
 -          if(reg.pathname == NULL && (reg.prot & PROT_WRITE) && i < maps->mapsize)
 -            start_bss_libsimgrid = reg.start_addr;
 -        }else if (!memcmp(basename(maps->regions[i].pathname), basename(xbt_binary_name), strlen(basename(xbt_binary_name)))){
 -          start_data_binary = reg.start_addr;
 -          i++;
 -          reg = maps->regions[i];
 -          if(reg.pathname == NULL && (reg.prot & PROT_WRITE) && reg.start_addr != std_heap && reg.start_addr != raw_heap && i < maps->mapsize){
 -            start_bss_binary = reg.start_addr;
 -            i++;
 -          }
 -        }else if(!memcmp(maps->regions[i].pathname, "[stack]", 7)){
 +    if (maps->regions[i].pathname == NULL) {
 +      // Nothing to do
 +    }
 +    else if ((reg.prot & PROT_WRITE) && !memcmp(maps->regions[i].pathname, "[stack]", 7)){
            maestro_stack_start = reg.start_addr;
            maestro_stack_end = reg.end_addr;
 -          i++;
 -        }
 -      }
 -    }else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)){
 -      if (maps->regions[i].pathname != NULL){
 -        if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
 -          start_text_libsimgrid = reg.start_addr;
 +    } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC) && !memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
 +      if(libsimgrid_path == NULL)
            libsimgrid_path = strdup(maps->regions[i].pathname);
 -        }else if (!memcmp(basename(maps->regions[i].pathname), basename(xbt_binary_name), strlen(basename(xbt_binary_name)))){
 -          start_text_binary = reg.start_addr;
 -        }
 -      }
      }
      i++;
    }
 -   
 -  MC_free_memory_map(maps);
 -
 -}
 -
 -void MC_get_libsimgrid_plt_section(){
  
 -  FILE *fp;
 -  char *line = NULL;            /* Temporal storage for each line that is readed */
 -  ssize_t read;                 /* Number of bytes readed */
 -  size_t n = 0;                 /* Amount of bytes to read by xbt_getline */
 +  xbt_assert(maestro_stack_start, "maestro_stack_start");
 +  xbt_assert(maestro_stack_end, "maestro_stack_end");
 +  xbt_assert(libsimgrid_path, "libsimgrid_path&");
  
 -  char *lfields[7];
 -  int i, plt_found = 0;
 -  unsigned long int size, offset;
 -
 -  char *command = bprintf("objdump --section-headers %s", libsimgrid_path);
 +  MC_free_memory_map(maps);
  
 -  fp = popen(command, "r");
 +}
  
 -  if(fp == NULL){
 -    perror("popen failed");
 -    xbt_abort();
 +/** \brief Fill/llokup the "subtype" field.
 + */
 +static void MC_resolve_subtype(mc_object_info_t info, dw_type_t type) {
 +
 +  if(type->dw_type_id==NULL)
 +    return;
 +  type->subtype = xbt_dict_get_or_null(info->types, type->dw_type_id);
 +  if(type->subtype==NULL)
 +    return;
 +  if(type->subtype->byte_size != 0)
 +    return;
 +  if(type->subtype->name==NULL)
 +    return;
 +  // Try to find a more complete description of the type:
 +  // We need to fix in order to support C++.
 +
 +  dw_type_t subtype = xbt_dict_get_or_null(info->types_by_name, type->subtype->name);
 +  if(subtype!=NULL) {
 +    type->subtype = subtype;
    }
  
 -  while ((read = xbt_getline(&line, &n, fp)) != -1 && plt_found != 2) {
 -
 -    if(n == 0)
 -      continue;
 -
 -    /* Wipeout the new line character */
 -    line[read - 1] = '\0';
 -
 -    lfields[0] = strtok(line, " ");
 -
 -    if(lfields[0] == NULL)
 -      continue;
 -
 -    if(strcmp(lfields[0], "Sections:") == 0 || strcmp(lfields[0], "Idx") == 0 || strncmp(lfields[0], libsimgrid_path, strlen(libsimgrid_path)) == 0)
 -      continue;
 +  // TODO, support "switch type" (looking up the type in another lib) when possible
 +}
  
 -    for (i = 1; i < 7 && lfields[i - 1] != NULL; i++) {
 -      lfields[i] = strtok(NULL, " ");
 -    }
 +void MC_post_process_types(mc_object_info_t info) {
 +  xbt_dict_cursor_t cursor = NULL;
 +  char *origin;
 +  dw_type_t type;
  
 -    if(i>=6){
 -      if(strcmp(lfields[1], ".plt") == 0){
 -        size = strtoul(lfields[2], NULL, 16);
 -        offset = strtoul(lfields[5], NULL, 16);
 -        start_plt_libsimgrid = (char *)start_text_libsimgrid + offset;
 -        end_plt_libsimgrid = (char *)start_plt_libsimgrid + size;
 -        plt_found++;
 -      }else if(strcmp(lfields[1], ".got.plt") == 0){
 -        size = strtoul(lfields[2], NULL, 16);
 -        offset = strtoul(lfields[5], NULL, 16);
 -        start_got_plt_libsimgrid = (char *)start_text_libsimgrid + offset;
 -        end_got_plt_libsimgrid = (char *)start_got_plt_libsimgrid + size;
 -        plt_found++;
 -       }
 +  // Lookup "subtype" field:
 +  xbt_dict_foreach(info->types, cursor, origin, type){
 +    MC_resolve_subtype(info, type);
  
 +    dw_type_t member;
 +    unsigned int i = 0;
 +    if(type->members!=NULL) xbt_dynar_foreach(type->members, i, member) {
 +      MC_resolve_subtype(info, member);
      }
 -    
    }
 -
 -  xbt_free(command);
 -  xbt_free(line);
 -  pclose(fp);
 -
  }
  
 -void MC_get_binary_plt_section(){
 -
 -  FILE *fp;
 -  char *line = NULL;            /* Temporal storage for each line that is readed */
 -  ssize_t read;                 /* Number of bytes readed */
 -  size_t n = 0;                 /* Amount of bytes to read by xbt_getline */
 -
 -  char *lfields[7];
 -  int i, plt_found = 0;
 -  unsigned long int size;
 +/** \brief Fills the position of the .bss and .data sections. */
 +void MC_find_object_address(memory_map_t maps, mc_object_info_t result) {
  
 -  char *command = bprintf( "objdump --section-headers %s", xbt_binary_name);
 -
 -  fp = popen(command, "r");
 -
 -  if(fp == NULL){
 -    perror("popen failed");
 -    xbt_abort();
 -  }
 -
 -  while ((read = xbt_getline(&line, &n, fp)) != -1 && plt_found != 2) {
 -
 -    if(n == 0)
 -      continue;
 -
 -    /* Wipeout the new line character */
 -    line[read - 1] = '\0';
 -
 -    lfields[0] = strtok(line, " ");
 -
 -    if(lfields[0] == NULL)
 -      continue;
 -
 -    if(strcmp(lfields[0], "Sections:") == 0 || strcmp(lfields[0], "Idx") == 0 || strncmp(lfields[0], basename(xbt_binary_name), strlen(xbt_binary_name)) == 0)
 -      continue;
 -
 -    for (i = 1; i < 7 && lfields[i - 1] != NULL; i++) {
 -      lfields[i] = strtok(NULL, " ");
 +  unsigned int i = 0;
 +  s_map_region_t reg;
 +  const char* name = basename(result->file_name);
 +  while (i < maps->mapsize) {
 +    reg = maps->regions[i];
 +    if (maps->regions[i].pathname == NULL || strcmp(basename(maps->regions[i].pathname),  name)) {
 +      // Nothing to do
      }
 -
 -    if(i>=6){
 -      if(strcmp(lfields[1], ".plt") == 0){
 -        size = strtoul(lfields[2], NULL, 16);
 -        start_plt_binary = (void *)strtoul(lfields[3], NULL, 16);
 -        end_plt_binary = (char *)start_plt_binary + size;
 -        plt_found++;
 -      }else if(strcmp(lfields[1], ".got.plt") == 0){
 -        size = strtoul(lfields[2], NULL, 16);
 -        start_got_plt_binary = (char *)strtoul(lfields[3], NULL, 16);
 -        end_got_plt_binary = (char *)start_got_plt_binary + size;
 -        plt_found++;
 -       }
 +    else if ((reg.prot & PROT_WRITE)){
 +          xbt_assert(!result->start_rw,
 +            "Multiple read-write segments for %s, not supported",
 +            maps->regions[i].pathname);
 +          result->start_rw = reg.start_addr;
 +          result->end_rw   = reg.end_addr;
 +          // .bss is usually after the .data:
 +          // TODO, use dl_iterate_phdr to be more robust
 +          s_map_region_t* next = &(maps->regions[i+1]);
 +          if(next->pathname == NULL && (next->prot & PROT_WRITE) && next->start_addr == reg.end_addr) {
 +            result->end_rw = maps->regions[i+1].end_addr;
 +          }
 +    } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)){
 +          xbt_assert(!result->start_exec,
 +            "Multiple executable segments for %s, not supported",
 +            maps->regions[i].pathname);
 +          result->start_exec = reg.start_addr;
 +          result->end_exec   = reg.end_addr;
 +    }
 +    else if((reg.prot & PROT_READ) && !(reg.prot & PROT_EXEC)) {
 +        xbt_assert(!result->start_ro,
 +          "Multiple read only segments for %s, not supported",
 +          maps->regions[i].pathname);
 +        result->start_ro = reg.start_addr;
 +        result->end_ro   = reg.end_addr;
      }
 -    
 -    
 +    i++;
    }
  
 -  xbt_free(command);
 -  xbt_free(line);
 -  pclose(fp);
 -
 +  xbt_assert(result->file_name);
 +  xbt_assert(result->start_rw);
 +  xbt_assert(result->start_exec);
  }
  
  /************************************* Take Snapshot ************************************/
  /****************************************************************************************/
  
 -static void MC_get_hash_global(char *snapshot_hash, void *data1, void *data2){
 -  
 -  /* unsigned int cursor = 0; */
 -  /* size_t offset;  */
 -  /* global_variable_t current_var;  */
 -  /* void *addr_pointed = NULL; */
 -  /* void *res = NULL; */
 -
 -  /* xbt_strbuff_t clear = xbt_strbuff_new(); */
 -  
 -  /* xbt_dynar_foreach(mc_global_variables, cursor, current_var){ */
 -  /*   if(current_var->address < start_data_libsimgrid){ /\* binary *\/ */
 -  /*     offset = (char *)current_var->address - (char *)start_data_binary; */
 -  /*     addr_pointed = *((void **)((char *)data2 + offset)); */
 -  /*     if(((addr_pointed >= start_plt_binary && addr_pointed <= end_plt_binary)) || ((addr_pointed >= std_heap && (char *)addr_pointed <= (char *)std_heap + STD_HEAP_SIZE ))) */
 -  /*       continue; */
 -  /*     res = xbt_malloc0(current_var->size + 1); */
 -  /*     memset(res, 0, current_var->size + 1); */
 -  /*     memcpy(res, (char*)data2 + offset, current_var->size); */
 -  /*   }else{ /\* libsimgrid *\/ */
 -  /*     offset = (char *)current_var->address - (char *)start_data_libsimgrid; */
 -  /*     addr_pointed = *((void **)((char *)data1 + offset)); */
 -  /*     if((addr_pointed >= start_plt_libsimgrid && addr_pointed <= end_plt_libsimgrid) || (addr_pointed >= std_heap && (char *)addr_pointed <= (char *)std_heap + STD_HEAP_SIZE )) */
 -  /*       continue; */
 -  /*     res = xbt_malloc0(current_var->size + 1); */
 -  /*     memset(res, 0, current_var->size + 1); */
 -  /*     memcpy(res, (char*)data1 + offset, current_var->size); */
 -  /*   } */
 -  /*   if(res != NULL){ */
 -  /*     xbt_strbuff_append(clear, (const char*)res); */
 -  /*     xbt_free(res); */
 -  /*     res = NULL; */
 -  /*   } */
 -  /* } */
 -
 -  /* xbt_sha(clear->data, snapshot_hash); */
 -
 -  /* xbt_strbuff_free(clear); */
 -
 -}
 -
 -static void MC_get_hash_local(char *snapshot_hash, xbt_dynar_t stacks){
 -
 -  /* xbt_dynar_t tokens = NULL, s_tokens = NULL; */
 -  /* unsigned int cursor1 = 0, cursor2 = 0; */
 -  /* mc_snapshot_stack_t current_stack; */
 -  /* char *frame_name = NULL; */
 -  /* void *addr; */
 -
 -  /* xbt_strbuff_t clear = xbt_strbuff_new(); */
 -
 -  /* while(cursor1 < xbt_dynar_length(stacks)){ */
 -  /*   current_stack = xbt_dynar_get_as(stacks, cursor1, mc_snapshot_stack_t); */
 -  /*   tokens = xbt_str_split(current_stack->local_variables->data, NULL); */
 -  /*   cursor2 = 0; */
 -  /*   while(cursor2 < xbt_dynar_length(tokens)){ */
 -  /*     s_tokens = xbt_str_split(xbt_dynar_get_as(tokens, cursor2, char *), "="); */
 -  /*     if(xbt_dynar_length(s_tokens) > 1){ */
 -  /*       if(strcmp(xbt_dynar_get_as(s_tokens, 0, char *), "frame_name") == 0){ */
 -  /*         xbt_free(frame_name); */
 -  /*         frame_name = xbt_strdup(xbt_dynar_get_as(s_tokens, 1, char *)); */
 -  /*         xbt_strbuff_append(clear, (const char*)xbt_dynar_get_as(tokens, cursor2, char *)); */
 -  /*         cursor2++; */
 -  /*         xbt_dynar_free(&s_tokens); */
 -  /*         continue; */
 -  /*       } */
 -  /*       addr = (void *) strtoul(xbt_dynar_get_as(s_tokens, 1, char *), NULL, 16); */
 -  /*       if(addr > std_heap && (char *)addr <= (char *)std_heap + STD_HEAP_SIZE){ */
 -  /*         cursor2++; */
 -  /*         xbt_dynar_free(&s_tokens); */
 -  /*         continue; */
 -  /*       } */
 -  /*       if(is_stack_ignore_variable(frame_name, xbt_dynar_get_as(s_tokens, 0, char *))){ */
 -  /*         cursor2++; */
 -  /*         xbt_dynar_free(&s_tokens); */
 -  /*         continue; */
 -  /*       } */
 -  /*       xbt_strbuff_append(clear, (const char *)xbt_dynar_get_as(tokens, cursor2, char *)); */
 -  /*     } */
 -  /*     xbt_dynar_free(&s_tokens); */
 -  /*     cursor2++; */
 -  /*   } */
 -  /*   xbt_dynar_free(&tokens); */
 -  /*   cursor1++; */
 -  /* } */
 -
 -  /* xbt_free(frame_name); */
 -
 -  /* xbt_sha(clear->data, snapshot_hash); */
 -
 -  /* xbt_strbuff_free(clear); */
 -
 -}
 -
 -static xbt_dynar_t MC_get_local_variables_values(void *stack_context){
 -  
 -  unw_cursor_t c;
 -  int ret;
 -
 -  char frame_name[256];
 -  
 -  ret = unw_init_local(&c, (unw_context_t *)stack_context);
 -  if(ret < 0){
 -    XBT_INFO("unw_init_local failed");
 -    xbt_abort();
 -  }
 -
 -  unw_word_t ip, sp, off;
 -  dw_frame_t frame;
 -
 -  unsigned int cursor = 0;
 -  dw_variable_t current_variable;
 -  dw_location_entry_t entry = NULL;
 -  dw_location_t location_entry = NULL;
 -  unw_word_t res;
 -  int frame_found = 0, region_type;
 -  void *frame_pointer_address = NULL;
 -  unsigned long true_ip, value;
 -  int stop = 0;
 +static xbt_dynar_t MC_get_local_variables_values(xbt_dynar_t stack_frames){
  
 +  unsigned cursor1 = 0;
 +  mc_stack_frame_t stack_frame;
    xbt_dynar_t variables = xbt_dynar_new(sizeof(local_variable_t), local_variable_free_voidp);
  
 -  while(ret >= 0 && !stop){
 -
 -    unw_get_reg(&c, UNW_REG_IP, &ip);
 -    unw_get_reg(&c, UNW_REG_SP, &sp);
 +  xbt_dynar_foreach(stack_frames,cursor1,stack_frame) {
  
 -    unw_get_proc_name(&c, frame_name, sizeof (frame_name), &off);
 -
 -    if(!strcmp(frame_name, "smx_ctx_sysv_wrapper")) /* Stop before context switch with maestro */
 -      stop = 1;
 -
 -    if((uintptr_t)ip > (uintptr_t)start_text_libsimgrid)
 -      frame = xbt_dict_get_or_null(mc_local_variables_libsimgrid, frame_name);
 -    else
 -      frame = xbt_dict_get_or_null(mc_local_variables_binary, frame_name);
 -
 -    if(frame == NULL){
 -      ret = unw_step(&c);
 -      continue;
 -    }
 -    
 -    true_ip = (unsigned long)frame->low_pc + (unsigned long)off;
 -    frame_pointer_address = NULL;
 -
 -    /* Get frame pointer */
 -    switch(frame->frame_base->type){
 -    case e_dw_loclist:
 -      cursor = 0;
 -      while(cursor < xbt_dynar_length(frame->frame_base->location.loclist) && !frame_found){
 -        entry = xbt_dynar_get_as(frame->frame_base->location.loclist, cursor, dw_location_entry_t);
 -        if((true_ip >= entry->lowpc) && (true_ip < entry->highpc)){
 -          frame_found = 1;
 -          switch(entry->location->type){
 -          case e_dw_compose:
 -            if(xbt_dynar_length(entry->location->location.compose) > 1){
 -              frame_pointer_address = NULL; /* TODO : location list with optimizations enabled */
 -            }else{
 -              location_entry = xbt_dynar_get_as(entry->location->location.compose, 0, dw_location_t);
 -              switch(location_entry->type){
 -              case e_dw_register:
 -                unw_get_reg(&c, location_entry->location.reg, &res);
 -                frame_pointer_address = (void*)(uintptr_t)res;
 -                break;
 -              case e_dw_bregister_op:
 -                unw_get_reg(&c, location_entry->location.breg_op.reg, &res);
 -                frame_pointer_address = (void*)((uintptr_t)res + location_entry->location.breg_op.offset);
 -                break;
 -              default:
 -                frame_pointer_address = NULL; /* FIXME : implement other cases (with optimizations enabled) */
 -                break;
 -              }
 -            }
 -            break;
 -          default:
 -            frame_pointer_address = NULL; /* FIXME : implement other cases (with optimizations enabled) */
 -            break;
 -          }
 -        }
 -        cursor++;
 -      }
 -      break;
 -    default :
 -      frame_pointer_address = NULL; /* FIXME : implement other cases (with optimizations enabled)*/
 -      break;
 -    }
 -
 -    frame_found = 0;
 -    cursor = 0;
 -
 -    xbt_dynar_foreach(frame->variables, cursor, current_variable){
 +    unsigned cursor2 = 0;
 +    dw_variable_t current_variable;
 +    xbt_dynar_foreach(stack_frame->frame->variables, cursor2, current_variable){
        
 -      if((uintptr_t)ip > (uintptr_t)start_text_libsimgrid)
 +      int region_type;
 +      if((long)stack_frame->ip > (long)mc_libsimgrid_info->start_exec)
          region_type = 1;
        else
          region_type = 2;
  
        local_variable_t new_var = xbt_new0(s_local_variable_t, 1);
 -      new_var->frame = xbt_strdup(frame_name);
 -      new_var->ip = (unsigned long)ip;
 +      new_var->frame = xbt_strdup(stack_frame->frame_name);
 +      new_var->ip = stack_frame->ip;
        new_var->name = xbt_strdup(current_variable->name);
 -      new_var->type = strdup(current_variable->type_origin);
 +      new_var->type = current_variable->type;
        new_var->region= region_type;
        
 -      if(current_variable->address.location != NULL){
 -        switch(current_variable->address.location->type){
 -        case e_dw_compose:
 -          if(xbt_dynar_length(current_variable->address.location->location.compose) > 1){
 -            /* TODO : location list with optimizations enabled */
 -          }else{
 -            location_entry = xbt_dynar_get_as(current_variable->address.location->location.compose, 0, dw_location_t);
 -            
 -            switch(location_entry->type){
 -            case e_dw_register:
 -              unw_get_reg(&c, location_entry->location.reg, &res);
 -              value = (unsigned long)res;
 -              break;
 -            case e_dw_bregister_op:
 -              unw_get_reg(&c, location_entry->location.breg_op.reg, &res);
 -              value = (unsigned long)res + location_entry->location.breg_op.offset;
 -              break;
 -            case e_dw_fbregister_op:
 -              if(frame_pointer_address != NULL)
 -                value = (unsigned long)((char *)frame_pointer_address + location_entry->location.fbreg_op);
 -              else
 -                value = 0;
 -              break;
 -            default:
 -              value = 0; /* FIXME : implement other cases (with optimizations enabled)*/
 -              break;
 -            }
 -
 -            if(value)
 -              new_var->address = (void *)value;
 -            else
 -              new_var->address = NULL;
 -          }
 -          break;
 -        default :
 -          break;
 -        }
 +      /* if(current_variable->address!=NULL) {
 +        new_var->address = current_variable->address;
 +      } else */
 +      if(current_variable->location != NULL){
 +        new_var->address = (void*) MC_dwarf_resolve_location(
 +          &(stack_frame->unw_cursor), current_variable->location, (void*)stack_frame->frame_base);
        }
  
        xbt_dynar_push(variables, &new_var);
  
      }
 -
 -    ret = unw_step(&c);
 -     
    }
  
    return variables;
  
  }
  
 +static void MC_stack_frame_free_voipd(void *s){
 +  mc_stack_frame_t stack_frame = *(mc_stack_frame_t*)s;
 +  if(stack_frame) {
 +    xbt_free(stack_frame->frame_name);
 +    xbt_free(stack_frame);
 +  }
 +}
  
 -static void *MC_get_stack_pointer(void *stack_context, void *heap){
 +static xbt_dynar_t MC_unwind_stack_frames(void *stack_context) {
 +  xbt_dynar_t result = xbt_dynar_new(sizeof(mc_stack_frame_t), MC_stack_frame_free_voipd);
  
    unw_cursor_t c;
 +
 +  dw_frame_t test = MC_find_function_by_ip(&MC_unwind_stack_frames);
 +  xbt_assert(test);
 +
    int ret;
 -  unw_word_t sp;
 +  for(ret = unw_init_local(&c, (unw_context_t *)stack_context); ret >= 0; ret = unw_step(&c)){
 +    mc_stack_frame_t stack_frame = xbt_new(s_mc_stack_frame_t, 1);
 +    xbt_dynar_push(result, &stack_frame);
 +
 +    stack_frame->unw_cursor = c;
 +
 +    unw_word_t ip, sp;
 +
 +    unw_get_reg(&c, UNW_REG_IP, &ip);
 +    unw_get_reg(&c, UNW_REG_SP, &sp);
  
 -  ret = unw_init_local(&c, (unw_context_t *)stack_context);
 -  if(ret < 0){
 +    stack_frame->ip = ip;
 +    stack_frame->sp = sp;
 +
 +    // TODO, use real addresses in frame_t instead of fixing it here
 +
 +    dw_frame_t frame = MC_find_function_by_ip((void*) ip);
 +    stack_frame->frame = frame;
 +
 +    if(frame) {
 +      stack_frame->frame_name = xbt_strdup(frame->name);
 +      stack_frame->frame_base = (unw_word_t)mc_find_frame_base((void*)ip, frame, &c);
 +    } else {
 +      stack_frame->frame_base = 0;
 +    }
 +
 +    /* Stop before context switch with maestro */
 +    if(frame!=NULL && frame->name!=NULL && !strcmp(frame->name, "smx_ctx_sysv_wrapper"))
 +      break;
 +  }
 +
 +  if(xbt_dynar_length(result) == 0){
      XBT_INFO("unw_init_local failed");
      xbt_abort();
    }
  
 -  unw_get_reg(&c, UNW_REG_SP, &sp);
 -
 -  return (char *)heap + ((char *)sp - (char*)std_heap);
 -
 -}
 +  return result;
 +};
  
  static xbt_dynar_t MC_take_snapshot_stacks(mc_snapshot_t *snapshot, void *heap){
  
    
    xbt_dynar_foreach(stacks_areas, cursor, current_stack){
      mc_snapshot_stack_t st = xbt_new(s_mc_snapshot_stack_t, 1);
 -    st->local_variables = MC_get_local_variables_values(current_stack->context);
 -    st->stack_pointer = MC_get_stack_pointer(current_stack->context, heap);
 +    st->stack_frames = MC_unwind_stack_frames(current_stack->context);
 +    st->local_variables = MC_get_local_variables_values(st->stack_frames);
 +
 +    unw_word_t sp = xbt_dynar_get_as(st->stack_frames, 0, mc_stack_frame_t)->sp;
 +    st->stack_pointer = ((char *)heap + (size_t)(((char *)((long)sp) - (char*)std_heap)));
 +
      st->real_address = current_stack->address;
      xbt_dynar_push(res, &st);
      (*snapshot)->stack_sizes = xbt_realloc((*snapshot)->stack_sizes, (cursor + 1) * sizeof(size_t));
@@@ -417,14 -737,8 +417,14 @@@ mc_snapshot_t MC_take_snapshot(int num_
  
    if(_sg_mc_visited > 0 || strcmp(_sg_mc_property_file,"")){
      snapshot->stacks = MC_take_snapshot_stacks(&snapshot, snapshot->regions[0]->data);
 -    //MC_get_hash_global(snapshot->hash_global, snapshot->regions[1]->data, snapshot->regions[2]->data);
 -    //MC_get_hash_local(snapshot->hash_local, snapshot->stacks);
 +    if(_sg_mc_hash && snapshot->stacks!=NULL) {
 +      snapshot->hash = mc_hash_processes_state(num_state, snapshot->stacks);
 +    } else {
 +      snapshot->hash = 0;
 +    }
 +  }
 +  else {
 +    snapshot->hash = 0;
    }
  
    if(num_state > 0)
diff --combined src/mc/mc_compare.c
@@@ -1,11 -1,9 +1,11 @@@
- /* Copyright (c) 2012-2013. The SimGrid Team.
+ /* Copyright (c) 2012-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
  
 +#include <inttypes.h>
 +
  #include "mc_private.h"
  
  #include "xbt/mmalloc.h"
@@@ -45,12 -43,38 +45,12 @@@ static void pointers_pair_free_voidp(vo
  /************************** Snapshot comparison *******************************/
  /******************************************************************************/
  
 -static int already_compared_pointers(void *p1, void *p2){
 -
 -  if(xbt_dynar_is_empty(compared_pointers))
 -    return -1;
 -
 -  unsigned int cursor = 0;
 -  int start = 0;
 -  int end = xbt_dynar_length(compared_pointers) - 1;
 -  pointers_pair_t pair;
 -
 -  while(start <= end){
 -    cursor = (start + end) / 2;
 -    pair = (pointers_pair_t)xbt_dynar_get_as(compared_pointers, cursor, pointers_pair_t);
 -    if(pair->p1 == p1){
 -      if(pair->p2 == p2)
 -        return 0;
 -      else if(pair->p2 < p2)
 -        start = cursor + 1;
 -      else
 -        end = cursor - 1;
 -    }else if(pair->p1 < p1){
 -      start = cursor + 1;
 -    }else{
 -      end = cursor - 1 ;
 -    }
 -  }
 -
 -  return -1;
 -
 -}
 -
 -static void add_compared_pointers(void *p1, void *p2){
 +/** \brief Try to add a pair a compared pointers to the set of compared pointers
 + *
 + *  \result !=0 if the pointers were added (they were not in the set),
 + *      0 otherwise (they were already in the set)
 + */
 +static int add_compared_pointers(void *p1, void *p2){
  
    pointers_pair_t new_pair = xbt_new0(s_pointers_pair_t, 1);
    new_pair->p1 = p1;
@@@ -58,7 -82,7 +58,7 @@@
    
    if(xbt_dynar_is_empty(compared_pointers)){
      xbt_dynar_push(compared_pointers, &new_pair);
 -    return;
 +    return 1;
    }
  
    unsigned int cursor = 0;
    int end = xbt_dynar_length(compared_pointers) - 1;
    pointers_pair_t pair = NULL;
  
 +  pointers_pair_t* p = (pointers_pair_t*) xbt_dynar_get_ptr(compared_pointers, 0);
 +
    while(start <= end){
      cursor = (start + end) / 2;
 -    pair = (pointers_pair_t)xbt_dynar_get_as(compared_pointers, cursor, pointers_pair_t);
 -    if(pair->p1 == p1){
 -      if(pair->p2 == p2){
 -        pointers_pair_free(new_pair);
 -        return;
 -      }else if(pair->p2 < p2)
 -        start = cursor + 1;
 -      else
 -        end = cursor - 1;
 -    }else if(pair->p1 < p1){
 +    pair = p[cursor];
 +    if(pair->p1 < p1){
        start = cursor + 1;
 -    }else{
 +    } else if(pair->p1 > p1) {
 +      end = cursor - 1 ;
 +    } else if(pair->p2 < p2){
 +      start = cursor + 1;
 +    } else if(pair->p2 > p2) {
        end = cursor - 1 ;
 +    } else {
 +      pointers_pair_free(new_pair);
 +      return 0;
      }
    }
  
 -  if(pair->p1 == p1){
 -    if(pair->p2 < p2)
 -      xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
 -    else
 -      xbt_dynar_insert_at(compared_pointers, cursor, &new_pair); 
 -  }else{
 -    if(pair->p1 < p1)
 -      xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
 -    else
 -      xbt_dynar_insert_at(compared_pointers, cursor, &new_pair);   
 -  }
 -
 +  if(pair->p1 < p1)
 +    xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
 +  else if(pair->p1 > p1)
 +    xbt_dynar_insert_at(compared_pointers, cursor, &new_pair);
 +  else if(pair->p2 < p2)
 +    xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
 +  else if(pair->p2 > p2)
 +    xbt_dynar_insert_at(compared_pointers, cursor, &new_pair);
 +  else
 +    xbt_die("Unrecheable");
 +
 +  return 1;
  }
  
 -static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, xbt_dict_t other_types, char *type_id, int region_size, int region_type, void *start_data, int pointer_level){
 +static int compare_areas_with_type(void *area1, void *area2, mc_object_info_t info, mc_object_info_t other_info, dw_type_t type, int region_size, int region_type, void *start_data, int pointer_level){
  
 -  dw_type_t type = xbt_dict_get_or_null(types, type_id);;
    unsigned int cursor = 0;
    dw_type_t member, subtype, subsubtype;
    int elm_size, i, res, switch_types = 0;
    void *addr_pointed1, *addr_pointed2;
  
    switch(type->type){
 -  case e_dw_base_type:
 -  case e_dw_enumeration_type:
 -  case e_dw_union_type:
 -    return (memcmp(area1, area2, type->size) != 0);
 +  case DW_TAG_base_type:
 +  case DW_TAG_enumeration_type:
 +  case DW_TAG_union_type:
 +    return (memcmp(area1, area2, type->byte_size) != 0);
      break;
 -  case e_dw_typedef:
 -  case e_dw_volatile_type:
 -    return compare_areas_with_type(area1, area2, types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level);
 +  case DW_TAG_typedef:
 +  case DW_TAG_volatile_type:
 +  case DW_TAG_const_type:
 +    return compare_areas_with_type(area1, area2, info, other_info, type->subtype, region_size, region_type, start_data, pointer_level);
      break;
 -  case e_dw_const_type: /* Const variable cannot be modified */
 -    return -1;
 -    break;
 -  case e_dw_array_type:
 -    subtype = xbt_dict_get_or_null(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 */
 -        subtype = xbt_dict_get_or_null(types, get_type_description(types, subtype->name));
 -        if(subtype == NULL){
 -          subtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name));
 +    case DW_TAG_base_type:
 +    case DW_TAG_enumeration_type:
 +    case DW_TAG_pointer_type:
 +    case DW_TAG_structure_type:
 +    case DW_TAG_union_type:
 +      if(subtype->byte_size == 0){ /*declaration of the type, need the complete description */
 +          subtype = subtype->other_object_same_type;
            switch_types = 1;
 -        }
        }
 -      elm_size = subtype->size;
 +      elm_size = subtype->byte_size;
        break;
 -    case e_dw_typedef:
 -    case e_dw_volatile_type:
 -      subsubtype = xbt_dict_get_or_null(types, subtype->dw_type_id);
 -      if(subsubtype->size == 0){ /*declaration of the type, need the complete description */
 -        subsubtype = xbt_dict_get_or_null(types, get_type_description(types, subsubtype->name));
 -        if(subsubtype == NULL){
 -          subsubtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subsubtype->name));
 +    case DW_TAG_const_type:
 +    case DW_TAG_typedef:
 +    case DW_TAG_volatile_type:
 +      subsubtype = subtype->subtype;
 +      if(subsubtype->byte_size == 0){ /*declaration of the type, need the complete description */
 +          subsubtype = subsubtype->other_object_same_type;
            switch_types = 1;
 -        }
        }
 -      elm_size = subsubtype->size;
 +      elm_size = subsubtype->byte_size;
        break;
      default : 
        return 0;
        break;
      }
 -    for(i=0; i<type->size; i++){
 +    for(i=0; i<type->element_count; i++){
        if(switch_types)
 -        res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), other_types, types, type->dw_type_id, region_size, region_type, start_data, pointer_level);
 +        res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), other_info, info, type->subtype, region_size, region_type, start_data, pointer_level);
        else
 -        res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level);
 +        res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), info, other_info, type->subtype, region_size, region_type, start_data, 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(types, type->dw_type_id))->type == e_dw_subroutine_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);
        
        if(addr_pointed1 == NULL && addr_pointed2 == NULL)
          return 0;
 -      if(already_compared_pointers(addr_pointed1, addr_pointed2) != -1)
 +      if(!add_compared_pointers(addr_pointed1, addr_pointed2))
          return 0;
 -      add_compared_pointers(addr_pointed1, addr_pointed2);
  
        pointer_level++;
        
 -      if(addr_pointed1 > std_heap && (char *)addr_pointed1 < (char*) std_heap + STD_HEAP_SIZE && addr_pointed2 > std_heap && (char *)addr_pointed2 < (char*) std_heap + STD_HEAP_SIZE){
 -        return compare_heap_area(addr_pointed1, addr_pointed2, NULL, types, other_types, type->dw_type_id, pointer_level); 
 -      }else if(addr_pointed1 > start_data && (char*)addr_pointed1 <= (char *)start_data + region_size && addr_pointed2 > start_data && (char*)addr_pointed2 <= (char *)start_data + region_size){
 +      // Some cases are not handled here:
 +      // * the pointers lead to different areas (one to the heap, the other to the RW segment ...);
 +      // * a pointer leads to the read-only segment of the current object;
 +      // * a pointer lead to a different ELF object.
 +
 +      // The pointers are both in the heap:
 +      if(addr_pointed1 > std_heap && (char *)addr_pointed1 < (char*) std_heap + STD_HEAP_SIZE){
 +        if(!(addr_pointed2 > std_heap && (char *)addr_pointed2 < (char*) std_heap + STD_HEAP_SIZE))
 +          return 1;
 +        return compare_heap_area(addr_pointed1, addr_pointed2, NULL, info, other_info, type->dw_type_id, pointer_level);
 +      }
 +
 +      // The pointers are both in the current object R/W segment:
 +      else if(addr_pointed1 > start_data && (char*)addr_pointed1 <= (char *)start_data + region_size){
 +        if(!(addr_pointed2 > start_data && (char*)addr_pointed2 <= (char *)start_data + region_size))
 +          return 1;
          if(type->dw_type_id == NULL)
            return  (addr_pointed1 != addr_pointed2);
          else
 -          return  compare_areas_with_type(addr_pointed1, addr_pointed2, types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level); 
 -      }else{
 +          return  compare_areas_with_type(addr_pointed1, addr_pointed2, info, other_info, type->subtype, region_size, region_type, start_data, pointer_level);
 +      }
 +
 +      else{
          return (addr_pointed1 != addr_pointed2);
        }
      }
      break;
 -  case e_dw_structure_type:
 +  case DW_TAG_structure_type:
      xbt_dynar_foreach(type->members, cursor, member){
 -      res = compare_areas_with_type((char *)area1 + member->offset, (char *)area2 + member->offset, types, other_types, member->dw_type_id, region_size, region_type, start_data, pointer_level);
 +      XBT_DEBUG("Compare member %s", member->name);
 +      res = compare_areas_with_type((char *)area1 + member->offset, (char *)area2 + member->offset, info, other_info, member->subtype, region_size, region_type, start_data, pointer_level);
        if(res == 1)
          return res;
      }
      break;
 -  case e_dw_subroutine_type:
 +  case DW_TAG_subroutine_type:
      return -1;
      break;
    default:
@@@ -226,40 -242,33 +226,40 @@@ static int compare_global_variables(in
    }
  
    xbt_dynar_t variables;
 -  xbt_dict_t types, other_types;
    int res;
    unsigned int cursor = 0;
    dw_variable_t current_var;
    size_t offset;
    void *start_data;
 +  void* start_data_binary = mc_binary_info->start_rw;
 +  void* start_data_libsimgrid = mc_libsimgrid_info->start_rw;
  
 +  mc_object_info_t object_info = NULL;
 +  mc_object_info_t other_object_info = NULL;
    if(region_type == 2){
 -    variables = mc_global_variables_binary;
 -    types = mc_variables_type_binary;
 -    other_types = mc_variables_type_libsimgrid;
 +    object_info = mc_binary_info;
 +    other_object_info = mc_libsimgrid_info;
      start_data = start_data_binary;
    }else{
 -    variables = mc_global_variables_libsimgrid;
 -    types = mc_variables_type_libsimgrid;
 -    other_types = mc_variables_type_binary;
 +    object_info = mc_libsimgrid_info;
 +    other_object_info = mc_binary_info;
      start_data = start_data_libsimgrid;
    }
 +  variables = object_info->global_variables;
  
    xbt_dynar_foreach(variables, cursor, current_var){
  
 -    if(region_type == 2)
 -      offset = (char *)current_var->address.address - (char *)start_data_binary;
 -    else
 -      offset = (char *)current_var->address.address - (char *)start_data_libsimgrid;
 +    // If the variable is not in this object, skip it:
 +    // We do not expect to find a pointer to something which is not reachable
 +    // by the global variables.
 +    if((char*) current_var->address < (char*) object_info->start_rw
 +      || (char*) current_var->address > (char*) object_info->end_rw)
 +       continue;
 +
 +    offset = (char *)current_var->address - (char *)object_info->start_rw;
  
 -    res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, types, other_types, current_var->type_origin, r1->size, region_type, start_data, 0);
 +    dw_type_t bvariable_type = current_var->type;
 +    res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, object_info, other_object_info, bvariable_type, r1->size, region_type, start_data, 0);
      if(res == 1){
        XBT_VERB("Global variable %s (%p - %p) is different between snapshots", current_var->name, (char *)r1->data + offset, (char *)r2->data + offset);
        xbt_dynar_free(&compared_pointers);
  }
  
  static int compare_local_variables(mc_snapshot_stack_t stack1, mc_snapshot_stack_t stack2, void *heap1, void *heap2){
 +  void* start_data_binary = mc_binary_info->start_rw;
 +  void* start_data_libsimgrid = mc_libsimgrid_info->start_rw;
  
    if(!compared_pointers){
      compared_pointers = xbt_dynar_new(sizeof(pointers_pair_t), pointers_pair_free_voidp);
        }
        offset1 = (char *)current_var1->address - (char *)std_heap;
        offset2 = (char *)current_var2->address - (char *)std_heap;
 -      if(current_var1->region == 1)
 -        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_variables_type_libsimgrid, mc_variables_type_binary, current_var1->type, 0, 1, start_data_libsimgrid, 0);
 -      else
 -        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_variables_type_binary, mc_variables_type_libsimgrid, current_var1->type, 0, 2, start_data_binary, 0);
 +      XBT_DEBUG("Compare local variable %s of frame %s", current_var1->name, current_var1->frame);
 +
 +
 +      if(current_var1->region == 1) {
 +        dw_type_t subtype = current_var1->type;
 +        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_libsimgrid_info, mc_binary_info, subtype, 0, 1, start_data_libsimgrid, 0);
 +      } else {
 +        dw_type_t subtype = current_var2->type;
 +        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_binary_info, mc_libsimgrid_info, subtype, 0, 2, start_data_binary, 0);
 +      }
        if(res == 1){
          XBT_VERB("Local variable %s (%p - %p) in frame %s  is different between snapshots", current_var1->name,(char *)heap1 + offset1, (char *)heap2 + offset2, current_var1->frame);
          xbt_dynar_free(&compared_pointers);
@@@ -364,25 -365,10 +364,25 @@@ int snapshot_compare(void *state1, voi
      xbt_os_walltimer_start(timer);
    #endif
  
 -  /* Compare size of stacks */
 +  int hash_result = 0;
 +  if(_sg_mc_hash) {
 +    hash_result = (s1->hash != s2->hash);
 +    if(hash_result) {
 +      XBT_VERB("(%d - %d) Different hash : 0x%" PRIx64 "--0x%" PRIx64, num1, num2, s1->hash, s2->hash);
 +#ifndef MC_DEBUG
 +      return 1;
 +#endif
 +    } else {
 +      XBT_VERB("(%d - %d) Same hash : 0x%" PRIx64, num1, num2, s1->hash);
 +    }
 +  }
 +
    int i = 0;
    size_t size_used1, size_used2;
    int is_diff = 0;
 +
 +
 +  /* Compare size of stacks */
    while(i < xbt_dynar_length(s1->stacks)){
      size_used1 = s1->stack_sizes[i];
      size_used2 = s2->stack_sizes[i];
      xbt_os_walltimer_start(timer);
    #endif
  
 -  /* Compare hash of global variables */
 -  if(s1->hash_global != NULL && s2->hash_global != NULL){
 -    if(strcmp(s1->hash_global, s2->hash_global) != 0){
 -      #ifdef MC_DEBUG
 -        xbt_os_walltimer_stop(timer);
 -        mc_comp_times->hash_global_variables_comparison_time = xbt_os_timer_elapsed(timer);
 -        XBT_DEBUG("Different hash of global variables : %s - %s", s1->hash_global, s2->hash_global); 
 -        errors++; 
 -      #else
 -        #ifdef MC_VERBOSE
 -          XBT_VERB("Different hash of global variables : %s - %s", s1->hash_global, s2->hash_global); 
 -        #endif
 -
 -        xbt_os_walltimer_stop(timer);
 -        xbt_os_timer_free(timer);
 -        xbt_os_walltimer_stop(global_timer);
 -        mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
 -        xbt_os_timer_free(global_timer);
 -
 -        return 1;
 -      #endif
 -    }
 -  }
 -
 -  #ifdef MC_DEBUG
 -    xbt_os_walltimer_start(timer);
 -  #endif
 -
 -  /* Compare hash of local variables */
 -  if(s1->hash_local != NULL && s2->hash_local != NULL){
 -    if(strcmp(s1->hash_local, s2->hash_local) != 0){
 -      #ifdef MC_DEBUG
 -        xbt_os_walltimer_stop(timer);
 -        mc_comp_times->hash_local_variables_comparison_time = xbt_os_timer_elapsed(timer);
 -        XBT_DEBUG("Different hash of local variables : %s - %s", s1->hash_local, s2->hash_local); 
 -        errors++; 
 -      #else
 -        #ifdef MC_VERBOSE
 -          XBT_VERB("Different hash of local variables : %s - %s", s1->hash_local, s2->hash_local); 
 -        #endif
 -
 -        xbt_os_walltimer_stop(timer);
 -        xbt_os_timer_free(timer);
 -        xbt_os_walltimer_stop(global_timer);
 -        mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
 -        xbt_os_timer_free(global_timer);
 -
 -        return 1;
 -      #endif
 -    }
 -  }
 -
 -  #ifdef MC_DEBUG
 -    xbt_os_walltimer_start(timer);
 -  #endif
 -
    /* Init heap information used in heap comparison algorithm */
    res_init = init_heap_information((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data, s1->to_ignore, s2->to_ignore);
    if(res_init == -1){
      cursor++;
    }
  
 -  #ifdef MC_DEBUG
 -    if(is_diff == 0)
 -      xbt_os_walltimer_stop(timer);
 -    xbt_os_walltimer_start(timer);
 -  #endif
  
 -  /* Compare binary global variables */
 -  is_diff = compare_global_variables(2, s1->regions[2], s2->regions[2]);
 -  if(is_diff != 0){
 -    #ifdef MC_DEBUG
 -      xbt_os_walltimer_stop(timer);
 -      mc_comp_times->binary_global_variables_comparison_time = xbt_os_timer_elapsed(timer);
 -      XBT_DEBUG("(%d - %d) Different global variables in binary", num1, num2);
 -      errors++;
 -    #else
 -      #ifdef MC_VERBOSE
 -      XBT_VERB("(%d - %d) Different global variables in binary", num1, num2);
 -      #endif
  
 -      reset_heap_information();
 -      xbt_os_walltimer_stop(timer);
 -      xbt_os_timer_free(timer);
 -      xbt_os_walltimer_stop(global_timer);
 -      mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
 -      xbt_os_timer_free(global_timer);
 + const char* names[3] = { "?", "libsimgrid", "binary" };
 +#ifdef MC_DEBUG
 + double *times[3] = {
 +   NULL,
 +   &mc_comp_times->libsimgrid_global_variables_comparison_time,
 +   &mc_comp_times->binary_global_variables_comparison_time
 + };
 +#endif
  
 -      return 1;
 + int k=0;
 + for(k=2; k!=0; --k) {
 +    #ifdef MC_DEBUG
 +      if(is_diff == 0)
 +        xbt_os_walltimer_stop(timer);
 +      xbt_os_walltimer_start(timer);
      #endif
 -  }
  
 -  #ifdef MC_DEBUG
 -    if(is_diff == 0)
 -      xbt_os_walltimer_stop(timer);
 -    xbt_os_walltimer_start(timer);
 -  #endif
 -
 -  /* Compare libsimgrid global variables */
 -  is_diff = compare_global_variables(1, s1->regions[1], s2->regions[1]);
 +  /* Compare global variables */
 +  is_diff = compare_global_variables(k, s1->regions[k], s2->regions[k]);
    if(is_diff != 0){
      #ifdef MC_DEBUG
        xbt_os_walltimer_stop(timer);
 -      mc_comp_times->libsimgrid_global_variables_comparison_time = xbt_os_timer_elapsed(timer);
 -      XBT_DEBUG("(%d - %d) Different global variables in libsimgrid", num1, num2);
 +      *times[k] = xbt_os_timer_elapsed(timer);
 +      XBT_DEBUG("(%d - %d) Different global variables in %s", num1, num2, names[k]);
        errors++;
      #else
        #ifdef MC_VERBOSE
 -      XBT_VERB("(%d - %d) Different global variables in libsimgrid", num1, num2);
 +      XBT_VERB("(%d - %d) Different global variables in %s", num1, num2, names[k]);
        #endif
 -        
 +
        reset_heap_information();
        xbt_os_walltimer_stop(timer);
        xbt_os_timer_free(timer);
        return 1;
      #endif
    }
 + }
  
    #ifdef MC_DEBUG
      xbt_os_walltimer_start(timer);
    #endif
  
    /* Compare heap */
 -    if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data, mc_variables_type_libsimgrid, mc_variables_type_binary) > 0){
 +    if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[0]->data,
 +                            (xbt_mheap_t)s2->regions[0]->data,
 +                            mc_libsimgrid_info,
 +                            mc_binary_info) > 0){
  
      #ifdef MC_DEBUG
        xbt_os_walltimer_stop(timer);
      print_comparison_times();
    #endif
  
 -  return errors > 0;
 +#ifdef MC_VERBOSE
 +   if(errors || hash_result)
 +     XBT_VERB("(%d - %d) Difference found", num1, num2);
 +   else
 +     XBT_VERB("(%d - %d) No difference found", num1, num2);
 +#endif
 +
 +#if defined(MC_DEBUG) && defined(MC_VERBOSE)
 +   if(_sg_mc_hash) {
 +     // * false positive SHOULD be avoided.
 +     // * There MUST not be any false negative.
 +
 +     XBT_VERB("(%d - %d) State equality hash test is %s %s", num1, num2,
 +       (hash_result!=0) == (errors!=0) ? "true" : "false",
 +       !hash_result ? "positive" : "negative");
 +   }
 +#endif
 +
 +   return errors > 0 || hash_result;
    
  }
  
diff --combined src/mc/mc_dpor.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -13,154 -13,9 +13,154 @@@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dpor
  
  xbt_dynar_t visited_states;
  xbt_dict_t first_enabled_state;
 +xbt_dynar_t initial_communications_pattern;
 +xbt_dynar_t communications_pattern;
 +int nb_comm_pattern;
  
  /********** Static functions ***********/
  
 +static void comm_pattern_free(mc_comm_pattern_t p){
 +  xbt_free(p->rdv);
 +  xbt_free(p->data);
 +  xbt_free(p);
 +  p = NULL;
 +}
 +
 +static void comm_pattern_free_voidp( void *p){
 +  comm_pattern_free((mc_comm_pattern_t) * (void **)p);
 +}
 +
 +static mc_comm_pattern_t get_comm_pattern_from_idx(xbt_dynar_t pattern, unsigned int *idx, e_smx_comm_type_t type, unsigned long proc){
 +  mc_comm_pattern_t current_comm;
 +  while(*idx < xbt_dynar_length(pattern)){
 +    current_comm = (mc_comm_pattern_t)xbt_dynar_get_as(pattern, *idx, mc_comm_pattern_t);
 +    if(current_comm->type == type && type == SIMIX_COMM_SEND){
 +      if(current_comm->src_proc == proc)
 +        return current_comm;
 +    }else if(current_comm->type == type && type == SIMIX_COMM_RECEIVE){
 +      if(current_comm->dst_proc == proc)
 +        return current_comm;
 +    }
 +    (*idx)++;
 +  }
 +  return NULL;
 +}
 +
 +static int compare_comm_pattern(mc_comm_pattern_t comm1, mc_comm_pattern_t comm2){
 +  if(strcmp(comm1->rdv, comm2->rdv) != 0)
 +    return 1;
 +  if(comm1->src_proc != comm2->src_proc)
 +    return 1;
 +  if(comm1->dst_proc != comm2->dst_proc)
 +    return 1;
 +  if(comm1->data_size != comm2->data_size)
 +    return 1;
 +  if(memcmp(comm1->data, comm2->data, comm1->data_size) != 0)
 +    return 1;
 +  return 0;
 +}
 +
 +static void deterministic_pattern(xbt_dynar_t initial_pattern, xbt_dynar_t pattern){
 +  unsigned int cursor = 0, send_index = 0, recv_index = 0;
 +  mc_comm_pattern_t comm1, comm2;
 +  int comm_comparison = 0;
 +  int current_process = 0;
 +  while(current_process < simix_process_maxpid){
 +    while(cursor < xbt_dynar_length(initial_pattern)){
 +      comm1 = (mc_comm_pattern_t)xbt_dynar_get_as(initial_pattern, cursor, mc_comm_pattern_t);
 +      if(comm1->type == SIMIX_COMM_SEND && comm1->src_proc == current_process){
 +        comm2 = get_comm_pattern_from_idx(pattern, &send_index, comm1->type, current_process);
 +        comm_comparison = compare_comm_pattern(comm1, comm2);
 +        if(comm_comparison == 1){
 +          initial_state_safety->send_deterministic = 0;
 +          initial_state_safety->comm_deterministic = 0;
 +          return;
 +        }
 +        send_index++;
 +      }else if(comm1->type == SIMIX_COMM_RECEIVE && comm1->dst_proc == current_process){
 +        comm2 = get_comm_pattern_from_idx(pattern, &recv_index, comm1->type, current_process);
 +        comm_comparison = compare_comm_pattern(comm1, comm2);
 +        if(comm_comparison == 1){
 +          initial_state_safety->comm_deterministic = 0;
 +        }
 +        recv_index++;
 +      }
 +      cursor++;
 +    }
 +    cursor = 0;
 +    send_index = 0;
 +    recv_index = 0;
 +    current_process++;
 +  }
 +  // XBT_DEBUG("Communication-deterministic : %d, Send-deterministic : %d", initial_state_safety->comm_deterministic, initial_state_safety->send_deterministic);
 +}
 +
 +static int complete_comm_pattern(xbt_dynar_t list, mc_comm_pattern_t pattern){
 +  mc_comm_pattern_t current_pattern;
 +  unsigned int cursor = 0;
 +  xbt_dynar_foreach(list, cursor, current_pattern){
 +    if(current_pattern->comm == pattern->comm){
 +      if(!current_pattern->completed){
 +        current_pattern->src_proc = pattern->comm->comm.src_proc->pid;
 +        current_pattern->dst_proc = pattern->comm->comm.dst_proc->pid;
 +        current_pattern->data_size = pattern->comm->comm.src_buff_size;
 +        current_pattern->data = xbt_malloc0(current_pattern->data_size);
 +        current_pattern->matched_comm = pattern->num;
 +        memcpy(current_pattern->data, current_pattern->comm->comm.src_buff, current_pattern->data_size);
 +        current_pattern->completed = 1;
 +        return current_pattern->num;
 +      }
 +    }
 +  }
 +  return -1;
 +}
 +
 +void get_comm_pattern(xbt_dynar_t list, smx_simcall_t request, int call){
 +  mc_comm_pattern_t pattern = NULL;
 +  pattern = xbt_new0(s_mc_comm_pattern_t, 1);
 +  pattern->num = ++nb_comm_pattern;
 +  pattern->completed = 0;
 +  if(call == 1){ // ISEND
 +    pattern->comm = simcall_comm_isend__get__result(request);
 +    pattern->type = SIMIX_COMM_SEND;
 +    if(pattern->comm->comm.dst_proc != NULL){
 + 
 +      pattern->matched_comm = complete_comm_pattern(list, pattern);
 +      pattern->dst_proc = pattern->comm->comm.dst_proc->pid;
 +      pattern->completed = 1;
 +    }
 +    pattern->src_proc = pattern->comm->comm.src_proc->pid;
 +    pattern->data_size = pattern->comm->comm.src_buff_size;
 +    pattern->data=xbt_malloc0(pattern->data_size);
 +    memcpy(pattern->data, pattern->comm->comm.src_buff, pattern->data_size);
 +  }else{ // IRECV
 +    pattern->comm = simcall_comm_irecv__get__result(request);
 +    pattern->type = SIMIX_COMM_RECEIVE;
 +    if(pattern->comm->comm.src_proc != NULL){
 +      pattern->matched_comm = complete_comm_pattern(list, pattern);
 +      pattern->src_proc = pattern->comm->comm.src_proc->pid;
 +      pattern->completed = 1;
 +      pattern->data_size = pattern->comm->comm.src_buff_size;
 +      pattern->data=xbt_malloc0(pattern->data_size);
 +      memcpy(pattern->data, pattern->comm->comm.src_buff, pattern->data_size);
 +    }
 +    pattern->dst_proc = pattern->comm->comm.dst_proc->pid;
 +  }
 +  if(pattern->comm->comm.rdv != NULL)
 +    pattern->rdv = strdup(pattern->comm->comm.rdv->name);
 +  else
 +    pattern->rdv = strdup(pattern->comm->comm.rdv_cpy->name);
 +  xbt_dynar_push(list, &pattern);
 +}
 +
 +static void print_communications_pattern(xbt_dynar_t comms_pattern){
 +  unsigned int cursor = 0;
 +  mc_comm_pattern_t current_comm;
 +  xbt_dynar_foreach(comms_pattern, cursor, current_comm){
 +    // fprintf(stderr, "%s (%d - comm %p, src : %lu, dst %lu, rdv name %s, data %p, matched with %d)\n", current_comm->type == SIMIX_COMM_SEND ? "iSend" : "iRecv", current_comm->num, current_comm->comm, current_comm->src_proc, current_comm->dst_proc, current_comm->rdv, current_comm->data, current_comm->matched_comm);
 +  }
 +}
 +
  static void visited_state_free(mc_visited_state_t state){
    if(state){
      MC_free_snapshot(state->system_state);
@@@ -172,10 -27,6 +172,10 @@@ static void visited_state_free_voidp(vo
    visited_state_free((mc_visited_state_t) * (void **) s);
  }
  
 +/** \brief Save the current state
 + *
 + *  \return Snapshot of the current state.
 + */
  static mc_visited_state_t visited_state_new(){
  
    mc_visited_state_t new_state = NULL;
    
  }
  
 +/** \brief Find a suitable subrange of candidate duplicates for a given state
 + *
 + *  \param all_ pairs dynamic array of states with candidate duplicates of the current state;
 + *  \param pair current state;
 + *  \param min (output) index of the beginning of the the subrange
 + *  \param max (output) index of the enf of the subrange
 + *
 + *  Given a suitably ordered array of state, this function extracts a subrange
 + *  (with index *min <= i <= *max) with candidate duplicates of the given state.
 + *  This function uses only fast discriminating criterions and does not use the
 + *  full state comparison algorithms.
 + *
 + *  The states in all_pairs MUST be ordered using a (given) weak order
 + *  (based on nb_processes and heap_bytes_used).
 + *  The subrange is the subrange of "equivalence" of the given state.
 + */
  static int get_search_interval(xbt_dynar_t all_states, mc_visited_state_t state, int *min, int *max){
  
    int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
    return cursor;
  }
  
 +/** \brief Take a snapshot the current state and process it.
 + *
 + *  \return number of the duplicate state or -1 (not visited)
 + */
  static int is_visited_state(){
  
    if(_sg_mc_visited == 0)
      index = get_search_interval(visited_states, new_state, &min, &max);
  
      if(min != -1 && max != -1){
 +
 +      // Parallell implementation
        /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_states, min), (max-min)+1, new_state);
        if(res != -1){
          state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, (min+res)-1, mc_visited_state_t);
            MC_UNSET_RAW_MEM;
          return new_state->other_num;
          }*/
 +
        cursor = min;
        while(cursor <= max){
          state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, cursor, mc_visited_state_t);
          if(snapshot_compare(state_test, new_state) == 0){
 +          // The state has been visited:
 +
            if(state_test->other_num == -1)
              new_state->other_num = state_test->num;
            else
              XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num);
            else
              XBT_DEBUG("State %d already visited ! (equal to state %d (state %d in dot_output))", new_state->num, state_test->num, new_state->other_num);
 +
 +          // Replace the old state with the new one (why?):
            xbt_dynar_remove_at(visited_states, cursor, NULL);
            xbt_dynar_insert_at(visited_states, cursor, &new_state);
 +
            if(!raw_mem_set)
              MC_UNSET_RAW_MEM;
            return new_state->other_num;
          }
          cursor++;
        }
 +
 +      // The state has not been visited, add it to the list:
        xbt_dynar_insert_at(visited_states, min, &new_state);
 +
      }else{
 +
 +      // The state has not been visited: insert the state in the dynamic array.
        state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, index, mc_visited_state_t);
        if(state_test->nb_processes < new_state->nb_processes){
          xbt_dynar_insert_at(visited_states, index+1, &new_state);
          else
            xbt_dynar_insert_at(visited_states, index, &new_state);
        }
 +
      }
  
 +    // We have reached the maximum number of stored states;
      if(xbt_dynar_length(visited_states) > _sg_mc_visited){
 +
 +      // Find the (index of the) older state:
        int min2 = mc_stats->expanded_states;
        unsigned int cursor2 = 0;
        unsigned int index2 = 0;
            min2 = state_test->num;
          }
        }
 +
 +      // and drop it:
        xbt_dynar_remove_at(visited_states, index2, NULL);
      }
  
@@@ -398,17 -210,12 +398,17 @@@ void MC_dpor_init(
    /* Create the initial state and push it into the exploration stack */
    MC_SET_RAW_MEM;
  
 -  initial_state = MC_state_new();
    if(_sg_mc_visited > 0)
      visited_states = xbt_dynar_new(sizeof(mc_visited_state_t), visited_state_free_voidp);
  
    first_enabled_state = xbt_dict_new_homogeneous(&xbt_free_f);
  
 +  initial_communications_pattern = xbt_dynar_new(sizeof(mc_comm_pattern_t), comm_pattern_free_voidp);
 +  communications_pattern = xbt_dynar_new(sizeof(mc_comm_pattern_t), comm_pattern_free_voidp);
 +  nb_comm_pattern = 0;
 +
 +  initial_state = MC_state_new();
 +
    MC_UNSET_RAW_MEM;
  
    XBT_DEBUG("**************************************************");
  }
  
  
 -/**
 - *   \brief Perform the model-checking operation using a depth-first search exploration
 - *         with Dynamic Partial Order Reductions
 +/** \brief Model-check the application using a DFS exploration
 + *         with DPOR (Dynamic Partial Order Reductions)
   */
  void MC_dpor(void)
  {
    char *req_str = NULL;
    int value;
    smx_simcall_t req = NULL, prev_req = NULL;
 -  mc_state_t state = NULL, prev_state = NULL, next_state = NULL, restore_state=NULL;
 +  mc_state_t state = NULL, prev_state = NULL, next_state = NULL, restored_state=NULL;
    smx_process_t process = NULL;
    xbt_fifo_item_t item = NULL;
    mc_state_t state_test = NULL;
    int pos;
    int visited_state = -1;
    int enabled = 0;
 +  int interleave_size = 0;
 +  int comm_pattern = 0;
  
    while (xbt_fifo_size(mc_stack_safety) > 0) {
  
                xbt_fifo_size(mc_stack_safety), state, state->num,
                MC_state_interleave_size(state), user_max_depth_reached, xbt_dict_size(first_enabled_state));
        
 +    interleave_size = MC_state_interleave_size(state);
 +
      /* Update statistics */
      mc_stats->visited_states++;
  
        xbt_dict_remove(first_enabled_state, key); 
        xbt_free(key);
        MC_UNSET_RAW_MEM;
 +      
 +      if(_sg_mc_comms_determinism){
 +        if(req->call == SIMCALL_COMM_ISEND)
 +          comm_pattern = 1;
 +        else if(req->call == SIMCALL_COMM_IRECV)
 +          comm_pattern = 2;
 +      }
  
        /* Answer the request */
        SIMIX_simcall_pre(req, value); /* After this call req is no longer usefull */
  
 +      if(_sg_mc_comms_determinism){
 +        MC_SET_RAW_MEM;
 +        if(comm_pattern != 0){
 +          if(!initial_state_safety->initial_communications_pattern_done)
 +            get_comm_pattern(initial_communications_pattern, req, comm_pattern);
 +          else
 +            get_comm_pattern(communications_pattern, req, comm_pattern);
 +        }
 +        MC_UNSET_RAW_MEM; 
 +        comm_pattern = 0;
 +      }
 +
        /* Wait for requests (schedules processes) */
        MC_wait_for_requests();
  
  
        }
  
 -      /* Trash the current state, no longer needed */
        MC_SET_RAW_MEM;
 +
 +      if(_sg_mc_comms_determinism){
 +        if(!initial_state_safety->initial_communications_pattern_done){
 +          //print_communications_pattern(initial_communications_pattern);
 +        }else{
 +          if(interleave_size == 0){ /* if (interleave_size > 0), process interleaved but not enabled => "incorrect" path, determinism not evaluated */
 +            //print_communications_pattern(communications_pattern);
 +            deterministic_pattern(initial_communications_pattern, communications_pattern);
 +          }
 +        }
 +        initial_state_safety->initial_communications_pattern_done = 1;
 +      }
 +
 +      /* Trash the current state, no longer needed */
        xbt_fifo_shift(mc_stack_safety);
        MC_state_delete(state);
        XBT_DEBUG("Delete state %d at depth %d", state->num, xbt_fifo_size(mc_stack_safety) + 1);
 +
        MC_UNSET_RAW_MEM;        
        
        /* Check for deadlocks */
                pos = xbt_fifo_size(mc_stack_safety);
                item = xbt_fifo_get_first_item(mc_stack_safety);
                while(pos>0){
 -                restore_state = (mc_state_t) xbt_fifo_get_item_content(item);
 -                if(restore_state->system_state != NULL){
 +                restored_state = (mc_state_t) xbt_fifo_get_item_content(item);
 +                if(restored_state->system_state != NULL){
                    break;
                  }else{
                    item = xbt_fifo_get_next_item(item);
                    pos--;
                  }
                }
 -              MC_restore_snapshot(restore_state->system_state);
 +              MC_restore_snapshot(restored_state->system_state);
                xbt_fifo_unshift(mc_stack_safety, state);
                MC_UNSET_RAW_MEM;
                MC_replay(mc_stack_safety, pos);
            XBT_DEBUG("Back-tracking to state %d at depth %d done", state->num, xbt_fifo_size(mc_stack_safety));
            break;
          } else {
 +          req = MC_state_get_internal_request(state);
 +          if(_sg_mc_comms_determinism){
 +            if(req->call == SIMCALL_COMM_ISEND || req->call == SIMCALL_COMM_IRECV){
 +              if(!xbt_dynar_is_empty(communications_pattern))
 +                xbt_dynar_remove_at(communications_pattern, xbt_dynar_length(communications_pattern) - 1, NULL);
 +            }
 +          }
            XBT_DEBUG("Delete state %d at depth %d", state->num, xbt_fifo_size(mc_stack_safety) + 1); 
            MC_state_delete(state);
          }
diff --combined src/mc/mc_global.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -8,7 -8,6 +8,7 @@@
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <sys/time.h>
 +#include <libgen.h>
  
  #include "simgrid/sg_config.h"
  #include "../surf/surf_private.h"
@@@ -30,11 -29,9 +30,11 @@@ int _sg_do_model_check = 0
  int _sg_mc_checkpoint=0;
  char* _sg_mc_property_file=NULL;
  int _sg_mc_timeout=0;
 +int _sg_mc_hash=0;
  int _sg_mc_max_depth=1000;
  int _sg_mc_visited=0;
  char *_sg_mc_dot_output_file = NULL;
 +int _sg_mc_comms_determinism=0;
  
  int user_max_depth_reached = 0;
  
@@@ -72,13 -69,6 +72,13 @@@ void _mc_cfg_cb_timeout(const char *nam
    _sg_mc_timeout= xbt_cfg_get_boolean(_sg_cfg_set, name);
  }
  
 +void _mc_cfg_cb_hash(const char *name, int pos) {
 +  if (_sg_cfg_init_status && !_sg_do_model_check) {
 +    xbt_die("You are specifying a value to enable/disable the use of global hash to speedup state comparaison, but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
 +  }
 +  _sg_mc_hash= xbt_cfg_get_boolean(_sg_cfg_set, name);
 +}
 +
  void _mc_cfg_cb_max_depth(const char *name, int pos) {
    if (_sg_cfg_init_status && !_sg_do_model_check) {
      xbt_die("You are specifying a max depth value after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
@@@ -100,13 -90,6 +100,13 @@@ void _mc_cfg_cb_dot_output(const char *
    _sg_mc_dot_output_file= xbt_cfg_get_string(_sg_cfg_set, name);
  }
  
 +void _mc_cfg_cb_comms_determinism(const char *name, int pos) {
 +  if (_sg_cfg_init_status && !_sg_do_model_check) {
 +    xbt_die("You are specifying a value to enable/disable the detection of determinism in the communications schemes after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
 +  }
 +  _sg_mc_comms_determinism= xbt_cfg_get_boolean(_sg_cfg_set, name);
 +}
 +
  /* MC global data structures */
  mc_state_t mc_current_state = NULL;
  char mc_replay_mode = FALSE;
@@@ -127,10 -110,16 +127,10 @@@ int compare
  xbt_automaton_t _mc_property_automaton = NULL;
  
  /* Variables */
 -xbt_dict_t mc_local_variables_libsimgrid = NULL;
 -xbt_dict_t mc_local_variables_binary = NULL;
 -xbt_dynar_t mc_global_variables_libsimgrid = NULL;
 -xbt_dynar_t mc_global_variables_binary = NULL;
 -xbt_dict_t mc_variables_type_libsimgrid = NULL;
 -xbt_dict_t mc_variables_type_binary = NULL;
 +mc_object_info_t mc_libsimgrid_info = NULL;
 +mc_object_info_t mc_binary_info = NULL;
  
  /* Ignore mechanism */
 -xbt_dynar_t mc_stack_comparison_ignore;
 -xbt_dynar_t mc_data_bss_comparison_ignore;
  extern xbt_dynar_t mc_heap_comparison_ignore;
  extern xbt_dynar_t stacks_areas;
  
@@@ -162,7 -151,7 +162,7 @@@ static void dw_location_entry_free(dw_l
    xbt_free(e);
  }
  
 -static void dw_type_free(dw_type_t t){
 +void dw_type_free(dw_type_t t){
    xbt_free(t->name);
    xbt_free(t->dw_type_id);
    xbt_dynar_free(&(t->members));
@@@ -173,169 -162,20 +173,169 @@@ static void dw_type_free_voidp(void *t)
    dw_type_free((dw_type_t) * (void **) t);
  }
  
 -static void dw_variable_free(dw_variable_t v){
 +void dw_variable_free(dw_variable_t v){
    if(v){
      xbt_free(v->name);
      xbt_free(v->type_origin);
      if(!v->global)
 -      dw_location_free(v->address.location);
 +      dw_location_free(v->location);
      xbt_free(v);
    }
  }
  
 -static void dw_variable_free_voidp(void *t){
 +void dw_variable_free_voidp(void *t){
    dw_variable_free((dw_variable_t) * (void **) t);
  }
  
 +// ***** object_info
 +
 +mc_object_info_t MC_new_object_info(void) {
 +  mc_object_info_t res = xbt_new0(s_mc_object_info_t, 1);
 +  res->local_variables = xbt_dict_new_homogeneous(NULL);
 +  res->global_variables = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp);
 +  res->types = xbt_dict_new_homogeneous(NULL);
 +  res->types_by_name = xbt_dict_new_homogeneous(NULL);
 +  return res;
 +}
 +
 +
 +void MC_free_object_info(mc_object_info_t* info) {
 +  xbt_free(&(*info)->file_name);
 +  xbt_dict_free(&(*info)->local_variables);
 +  xbt_dynar_free(&(*info)->global_variables);
 +  xbt_dict_free(&(*info)->types);
 +  xbt_dict_free(&(*info)->types_by_name);
 +  xbt_free(info);
 +  xbt_dynar_free(&(*info)->functions_index);
 +  *info = NULL;
 +}
 +
 +// ***** Helpers
 +
 +void* MC_object_base_address(mc_object_info_t info) {
 +  void* result = info->start_exec;
 +  if(info->start_rw!=NULL && result > (void*) info->start_rw) result = info->start_rw;
 +  if(info->start_ro!=NULL && result > (void*) info->start_ro) result = info->start_ro;
 +  return result;
 +}
 +
 +// ***** Functions index
 +
 +static int MC_compare_frame_index_items(mc_function_index_item_t a, mc_function_index_item_t b) {
 +  if(a->low_pc < b->low_pc)
 +    return -1;
 +  else if(a->low_pc == b->low_pc)
 +    return 0;
 +  else
 +    return 1;
 +}
 +
 +static void MC_make_functions_index(mc_object_info_t info) {
 +  xbt_dynar_t index = xbt_dynar_new(sizeof(s_mc_function_index_item_t), NULL);
 +
 +  // Populate the array:
 +  dw_frame_t frame = NULL;
 +  xbt_dict_cursor_t cursor = NULL;
 +  const char* name = NULL;
 +  xbt_dict_foreach(info->local_variables, cursor, name, frame) {
 +    if(frame->low_pc==NULL)
 +      continue;
 +    s_mc_function_index_item_t entry;
 +    entry.low_pc = frame->low_pc;
 +    entry.high_pc = frame->high_pc;
 +    entry.function = frame;
 +    xbt_dynar_push(index, &entry);
 +  }
 +
 +  mc_function_index_item_t base = (mc_function_index_item_t) xbt_dynar_get_ptr(index, 0);
 +
 +  // Sort the array by low_pc:
 +  qsort(base,
 +    xbt_dynar_length(index),
 +    sizeof(s_mc_function_index_item_t),
 +    (int (*)(const void *, const void *))MC_compare_frame_index_items);
 +
 +  info->functions_index = index;
 +}
 +
 +mc_object_info_t MC_ip_find_object_info(void* ip) {
 +  mc_object_info_t infos[2] = { mc_binary_info, mc_libsimgrid_info };
 +  size_t n = 2;
 +  size_t i;
 +  for(i=0; i!=n; ++i) {
 +    if(ip >= (void*)infos[i]->start_exec && ip <= (void*)infos[i]->end_exec) {
 +      return infos[i];
 +    }
 +  }
 +  return NULL;
 +}
 +
 +static dw_frame_t MC_find_function_by_ip_and_object(void* ip, mc_object_info_t info) {
 +  xbt_dynar_t dynar = info->functions_index;
 +  mc_function_index_item_t base = (mc_function_index_item_t) xbt_dynar_get_ptr(dynar, 0);
 +  int i = 0;
 +  int j = xbt_dynar_length(dynar) - 1;
 +  while(j>=i) {
 +    int k = i + ((j-i)/2);
 +    if(ip < base[k].low_pc) {
 +      j = k-1;
 +    } else if(ip > base[k].high_pc) {
 +      i = k+1;
 +    } else {
 +      return base[k].function;
 +    }
 +  }
 +  return NULL;
 +}
 +
 +dw_frame_t MC_find_function_by_ip(void* ip) {
 +  mc_object_info_t info = MC_ip_find_object_info(ip);
 +  if(info==NULL)
 +    return NULL;
 +  else
 +    return MC_find_function_by_ip_and_object(ip, info);
 +}
 +
 +static void MC_post_process_variables(mc_object_info_t info) {
 +  unsigned cursor = 0;
 +  dw_variable_t variable = NULL;
 +  xbt_dynar_foreach(info->global_variables, cursor, variable) {
 +    if(variable->type_origin) {
 +      variable->type = xbt_dict_get_or_null(info->types, variable->type_origin);
 +    }
 +  }
 +}
 +
 +static void MC_post_process_functions(mc_object_info_t info) {
 +  xbt_dict_cursor_t cursor = NULL;
 +  char* key = NULL;
 +  dw_frame_t function = NULL;
 +  xbt_dict_foreach(info->local_variables, cursor, key, function) {
 +    unsigned cursor2 = 0;
 +    dw_variable_t variable = NULL;
 +    xbt_dynar_foreach(function->variables, cursor2, variable) {
 +      if(variable->type_origin) {
 +        variable->type = xbt_dict_get_or_null(info->types, variable->type_origin);
 +      }
 +    }
 +  }
 +}
 +
 +/** \brief Finds informations about a given shared object/executable */
 +mc_object_info_t MC_find_object_info(memory_map_t maps, char* name, int executable) {
 +  mc_object_info_t result = MC_new_object_info();
 +  if(executable)
 +    result->flags |= MC_OBJECT_INFO_EXECUTABLE;
 +  result->file_name = xbt_strdup(name);
 +  MC_find_object_address(maps, result);
 +  MC_dwarf_get_variables(result);
 +  MC_post_process_types(result);
 +  MC_post_process_variables(result);
 +  MC_post_process_functions(result);
 +  MC_make_functions_index(result);
 +  return result;
 +}
 +
  /*************************************************************************/
  
  static dw_location_t MC_dwarf_get_location(xbt_dict_t location_list, char *expr){
  
    if(location_list != NULL){
      
-     char *key = bprintf("%d", (int)strtoul(expr, NULL, 16));
+     char *key = bprintf("%lu", strtoul(expr, NULL, 16));
      loc->type = e_dw_loclist;
      loc->location.loclist =  (xbt_dynar_t)xbt_dict_get_or_null(location_list, key);
      if(loc->location.loclist == NULL)
  
  }
  
 -static xbt_dict_t MC_dwarf_get_location_list(const char *elf_file){
 -
 -  char *command = bprintf("objdump -Wo %s", elf_file);
 -
 -  FILE *fp = popen(command, "r");
 -
 -  if(fp == NULL){
 -    perror("popen for objdump failed");
 -    xbt_abort();
 -  }
 -
 -  int debug = 0; /*Detect if the program has been compiled with -g */
 -
 -  xbt_dict_t location_list = xbt_dict_new_homogeneous(NULL);
 -  char *line = NULL, *loc_expr = NULL;
 -  ssize_t read;
 -  size_t n = 0;
 -  int cursor_remove;
 -  xbt_dynar_t split = NULL;
 -
 -  while ((read = xbt_getline(&line, &n, fp)) != -1) {
 -
 -    /* Wipeout the new line character */
 -    line[read - 1] = '\0';
 -
 -    xbt_str_trim(line, NULL);
 -    
 -    if(n == 0)
 -      continue;
 -
 -    if(strlen(line) == 0)
 -      continue;
 -
 -    if(debug == 0){
 -
 -      if(strncmp(line, elf_file, strlen(elf_file)) == 0)
 -        continue;
 -      
 -      if(strncmp(line, "Contents", 8) == 0)
 -        continue;
 -
 -      if(strncmp(line, "Offset", 6) == 0){
 -        debug = 1;
 -        continue;
 -      }
 -    }
 -
 -    if(debug == 0){
 -      XBT_INFO("Your program must be compiled with -g");
 -      xbt_abort();
 -    }
 -
 -    xbt_dynar_t loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL);
 -
 -    xbt_str_strip_spaces(line);
 -    split = xbt_str_split(line, " ");
 -
 -    while(read != -1 && strcmp("<End", (char *)xbt_dynar_get_as(split, 1, char *)) != 0){
 -      
 -      dw_location_entry_t new_entry = xbt_new0(s_dw_location_entry_t, 1);
 -      new_entry->lowpc = strtoul((char *)xbt_dynar_get_as(split, 1, char *), NULL, 16);
 -      new_entry->highpc = strtoul((char *)xbt_dynar_get_as(split, 2, char *), NULL, 16);
 -      
 -      cursor_remove =0;
 -      while(cursor_remove < 3){
 -        xbt_dynar_remove_at(split, 0, NULL);
 -        cursor_remove++;
 -      }
 -
 -      loc_expr = xbt_str_join(split, " ");
 -      xbt_str_ltrim(loc_expr, "(");
 -      xbt_str_rtrim(loc_expr, ")");
 -      new_entry->location = MC_dwarf_get_location(NULL, loc_expr);
 -
 -      xbt_dynar_push(loclist, &new_entry);
 -
 -      xbt_dynar_free(&split);
 -      free(loc_expr);
 -
 -      read = xbt_getline(&line, &n, fp);
 -      if(read != -1){
 -        line[read - 1] = '\0';
 -        xbt_str_strip_spaces(line);
 -        split = xbt_str_split(line, " ");
 -      }
 -
 -    }
 -
 -
 -    char *key = bprintf("%lu", strtoul((char *)xbt_dynar_get_as(split, 0, char *), NULL, 16));
 -    xbt_dict_set(location_list, key, loclist, NULL);
 -    xbt_free(key);
 -    
 -    xbt_dynar_free(&split);
 -
 -  }
 -
 -  xbt_free(line);
 -  xbt_free(command);
 -  pclose(fp);
 -
 -  return location_list;
 -}
--
 +/** \brief Finds a frame (DW_TAG_subprogram) from an DWARF offset in the rangd of this subprogram
 + *
 + * The offset can be an offset of a child DW_TAG_variable.
 + */
  static dw_frame_t MC_dwarf_get_frame_by_offset(xbt_dict_t all_variables, unsigned long int offset){
  
    xbt_dict_cursor_t cursor = NULL;
@@@ -529,9 -468,9 +528,9 @@@ static int MC_dwarf_get_variable_index(
        end = cursor - 1;
      }else{
        if(address){ /* global variable */
 -        if(var_test->address.address == address)
 +        if(var_test->address == address)
            return -1;
 -        if(var_test->address.address > address)
 +        if(var_test->address > address)
            end = cursor - 1;
          else
            start = cursor + 1;
    }
  
    if(strcmp(var_test->name, var) == 0){
 -    if(address && var_test->address.address < address)
 +    if(address && var_test->address < address)
        return cursor+1;
      else
        return cursor;
  
  }
  
 +void MC_dwarf_register_global_variable(mc_object_info_t info, dw_variable_t variable) {
 +  int index = MC_dwarf_get_variable_index(info->global_variables, variable->name, variable->address);
 +  if (index != -1)
 +    xbt_dynar_insert_at(info->global_variables, index, &variable);
 +  // TODO, else ?
 +}
  
 -static void MC_dwarf_get_variables(const char *elf_file, xbt_dict_t location_list, xbt_dict_t *local_variables, xbt_dynar_t *global_variables, xbt_dict_t *types){
 -
 -  char *command = bprintf("objdump -Wi %s", elf_file);
 -  
 -  FILE *fp = popen(command, "r");
 -
 -  if(fp == NULL)
 -    perror("popen for objdump failed");
 -
 -  char *line = NULL, *origin, *abstract_origin, *current_frame = NULL, 
 -    *subprogram_name = NULL, *subprogram_start = NULL, *subprogram_end = NULL,
 -    *node_type = NULL, *location_type = NULL, *variable_name = NULL, 
 -    *loc_expr = NULL, *name = NULL, *end =NULL, *type_origin = NULL, *global_address = NULL, 
 -    *parent_value = NULL;
 -
 -  ssize_t read =0;
 -  size_t n = 0;
 -  int global_variable = 0, parent = 0, new_frame = 0, new_variable = 1, size = 0, 
 -    is_pointer = 0, struct_decl = 0, member_end = 0,
 -    enumeration_size = 0, subrange = 0, union_decl = 0, offset = 0, index = 0;
 -  
 -  xbt_dynar_t split = NULL, split2 = NULL;
 -
 -  xbt_dict_t variables_origin = xbt_dict_new_homogeneous(xbt_free);
 -  xbt_dict_t subprograms_origin = xbt_dict_new_homogeneous(xbt_free);
 -
 -  dw_frame_t variable_frame, subroutine_frame = NULL;
 -
 -  e_dw_type_type type_type = -1;
 -
 -  read = xbt_getline(&line, &n, fp);
 -
 -  while (read != -1) {
 -
 -    /* Wipeout the new line character */
 -    line[read - 1] = '\0';
 -  
 -    if(n == 0 || strlen(line) == 0){
 -      read = xbt_getline(&line, &n, fp);
 -      continue;
 -    }
 -
 -    xbt_str_ltrim(line, NULL);
 -    xbt_str_strip_spaces(line);
 -    
 -    if(line[0] != '<'){
 -      read = xbt_getline(&line, &n, fp);
 -      continue;
 -    }
 -    
 -    xbt_dynar_free(&split);
 -    split = xbt_str_split(line, " ");
 -
 -    /* Get node type */
 -    node_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *);
 -
 -    if(strcmp(node_type, "(DW_TAG_subprogram)") == 0){ /* New frame */
 -
 -      dw_frame_t frame = NULL;
 -
 -      strtok(xbt_dynar_get_as(split, 0, char *), "<");
 -      subprogram_start = xbt_strdup(strtok(NULL, "<"));
 -      xbt_str_rtrim(subprogram_start, ">:");
 -
 -      read = xbt_getline(&line, &n, fp);
 -   
 -      while(read != -1){
 -
 -        /* Wipeout the new line character */
 -        line[read - 1] = '\0';
 -
 -        if(n == 0 || strlen(line) == 0){
 -          read = xbt_getline(&line, &n, fp);
 -          continue;
 -        }
 -        
 -        xbt_dynar_free(&split);
 -        xbt_str_rtrim(line, NULL);
 -        xbt_str_strip_spaces(line);
 -        split = xbt_str_split(line, " ");
 -          
 -        node_type = xbt_dynar_get_as(split, 1, char *);
 -
 -        if(strncmp(node_type, "DW_AT_", 6) != 0)
 -          break;
 -
 -        if(strcmp(node_type, "DW_AT_sibling") == 0){
 -
 -          subprogram_end = xbt_strdup(xbt_dynar_get_as(split, 3, char*));
 -          xbt_str_ltrim(subprogram_end, "<0x");
 -          xbt_str_rtrim(subprogram_end, ">");
 -          
 -        }else if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){ /* Frame already in dict */
 -          
 -          new_frame = 0;
 -          abstract_origin = xbt_strdup(xbt_dynar_get_as(split, 2, char*));
 -          xbt_str_ltrim(abstract_origin, "<0x");
 -          xbt_str_rtrim(abstract_origin, ">");
 -          subprogram_name = (char *)xbt_dict_get_or_null(subprograms_origin, abstract_origin);
 -          frame = xbt_dict_get_or_null(*local_variables, subprogram_name); 
 -          xbt_free(abstract_origin);
 -
 -        }else if(strcmp(node_type, "DW_AT_name") == 0){
 -
 -          new_frame = 1;
 -          xbt_free(current_frame);
 -          frame = xbt_new0(s_dw_frame_t, 1);
 -          frame->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *)); 
 -          frame->variables = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp);
 -          frame->frame_base = xbt_new0(s_dw_location_t, 1); 
 -          current_frame = strdup(frame->name);
 -
 -          xbt_dict_set(subprograms_origin, subprogram_start, xbt_strdup(frame->name), NULL);
 -        
 -        }else if(strcmp(node_type, "DW_AT_frame_base") == 0){
 -
 -          location_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *);
 -
 -          if(strcmp(location_type, "list)") == 0){ /* Search location in location list */
 -
 -            frame->frame_base = MC_dwarf_get_location(location_list, xbt_dynar_get_as(split, 3, char *));
 -             
 -          }else{
 -                
 -            xbt_str_strip_spaces(line);
 -            split2 = xbt_str_split(line, "(");
 -            xbt_dynar_remove_at(split2, 0, NULL);
 -            loc_expr = xbt_str_join(split2, " ");
 -            xbt_str_rtrim(loc_expr, ")");
 -            frame->frame_base = MC_dwarf_get_location(NULL, loc_expr);
 -            xbt_dynar_free(&split2);
 -            xbt_free(loc_expr);
 -
 -          }
 - 
 -        }else if(strcmp(node_type, "DW_AT_low_pc") == 0){
 -          
 -          if(frame != NULL)
 -            frame->low_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
 -
 -        }else if(strcmp(node_type, "DW_AT_high_pc") == 0){
 -
 -          if(frame != NULL)
 -            frame->high_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
 -
 -        }else if(strcmp(node_type, "DW_AT_MIPS_linkage_name:") == 0){
 -
 -          xbt_free(frame->name);
 -          xbt_free(current_frame);
 -          frame->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *));   
 -          current_frame = strdup(frame->name);
 -          xbt_dict_set(subprograms_origin, subprogram_start, xbt_strdup(frame->name), NULL);
 -
 -        }
 -
 -        read = xbt_getline(&line, &n, fp);
 -
 -      }
 - 
 -      if(new_frame == 1){
 -        frame->start = strtoul(subprogram_start, NULL, 16);
 -        if(subprogram_end != NULL)
 -          frame->end = strtoul(subprogram_end, NULL, 16);
 -        xbt_dict_set(*local_variables, frame->name, frame, NULL);
 -      }
 -
 -      xbt_free(subprogram_start);
 -      xbt_free(subprogram_end);
 -      subprogram_end = NULL;
 -        
 -
 -    }else if(strcmp(node_type, "(DW_TAG_variable)") == 0){ /* New variable */
 -
 -      dw_variable_t var = NULL;
 -      
 -      parent_value = strdup(xbt_dynar_get_as(split, 0, char *));
 -      parent_value = strtok(parent_value,"<");
 -      xbt_str_rtrim(parent_value, ">");
 -      parent = atoi(parent_value);
 -      xbt_free(parent_value);
 -
 -      if(parent == 1)
 -        global_variable = 1;
 -    
 -      strtok(xbt_dynar_get_as(split, 0, char *), "<");
 -      origin = xbt_strdup(strtok(NULL, "<"));
 -      xbt_str_rtrim(origin, ">:");
 -      
 -      read = xbt_getline(&line, &n, fp);
 -      
 -      while(read != -1){
 -
 -        /* Wipeout the new line character */
 -        line[read - 1] = '\0'; 
 -
 -        if(n == 0 || strlen(line) == 0){
 -          read = xbt_getline(&line, &n, fp);
 -          continue;
 -        }
 -    
 -        xbt_dynar_free(&split);
 -        xbt_str_rtrim(line, NULL);
 -        xbt_str_strip_spaces(line);
 -        split = xbt_str_split(line, " ");
 -  
 -        node_type = xbt_dynar_get_as(split, 1, char *);
 -
 -        if(strncmp(node_type, "DW_AT_", 6) != 0)
 -          break;
 -
 -        if(strcmp(node_type, "DW_AT_name") == 0){
 -
 -          var = xbt_new0(s_dw_variable_t, 1);
 -          var->name = xbt_strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *));
 -          xbt_dict_set(variables_origin, origin, xbt_strdup(var->name), NULL);
 -         
 -        }else if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){
 -
 -          new_variable = 0;
 -
 -          abstract_origin = xbt_dynar_get_as(split, 2, char *);
 -          xbt_str_ltrim(abstract_origin, "<0x");
 -          xbt_str_rtrim(abstract_origin, ">");
 -          
 -          variable_name = (char *)xbt_dict_get_or_null(variables_origin, abstract_origin);
 -          variable_frame = MC_dwarf_get_frame_by_offset(*local_variables, strtoul(abstract_origin, NULL, 16));
 -          var = MC_dwarf_get_variable_by_name(variable_frame, variable_name); 
 -
 -        }else if(strcmp(node_type, "DW_AT_location") == 0){
 -
 -          if(var != NULL){
 -
 -            if(!global_variable){
 -
 -              location_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *);
 -
 -              if(strcmp(location_type, "list)") == 0){ /* Search location in location list */
 -                var->address.location = MC_dwarf_get_location(location_list, xbt_dynar_get_as(split, 3, char *));
 -              }else{
 -                xbt_str_strip_spaces(line);
 -                split2 = xbt_str_split(line, "(");
 -                xbt_dynar_remove_at(split2, 0, NULL);
 -                loc_expr = xbt_str_join(split2, " ");
 -                xbt_str_rtrim(loc_expr, ")");
 -                if(strncmp("DW_OP_addr", loc_expr, 10) == 0){
 -                  global_variable = 1;
 -                  xbt_dynar_free(&split2);
 -                  split2 = xbt_str_split(loc_expr, " ");
 -                  if(strcmp(elf_file, xbt_binary_name) != 0)
 -                    var->address.address = (char *)start_text_libsimgrid + strtoul(xbt_dynar_get_as(split2, xbt_dynar_length(split2) - 1, char*), NULL, 16);
 -                  else
 -                    var->address.address = (void *)strtoul(xbt_dynar_get_as(split2, xbt_dynar_length(split2) - 1, char*), NULL, 16);
 -                }else{
 -                  var->address.location = MC_dwarf_get_location(NULL, loc_expr);
 -                }
 -                xbt_dynar_free(&split2);
 -                xbt_free(loc_expr);
 -              }
 -            }else{
 -              global_address = xbt_strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *));
 -              xbt_str_rtrim(global_address, ")");
 -              if(strcmp(elf_file, xbt_binary_name) != 0)
 -                var->address.address = (char *)start_text_libsimgrid + strtoul(global_address, NULL, 16);
 -              else
 -                var->address.address = (void *)strtoul(global_address, NULL, 16);
 -              xbt_free(global_address);
 -              global_address = NULL;
 -            }
 -
 -          }
 -                   
 -        }else if(strcmp(node_type, "DW_AT_type") == 0){
 -          
 -          type_origin = xbt_strdup(xbt_dynar_get_as(split, 3, char *));
 -          xbt_str_ltrim(type_origin, "<0x");
 -          xbt_str_rtrim(type_origin, ">");
 -        
 -        }else if(strcmp(node_type, "DW_AT_declaration") == 0){
 -
 -          new_variable = 0;
 -          if(new_variable){
 -            dw_variable_free(var);
 -            var = NULL;
 -          }
 -        
 -        }else if(strcmp(node_type, "DW_AT_artificial") == 0){
 -          
 -          new_variable = 0;
 -          if(new_variable){
 -            dw_variable_free(var);
 -            var = NULL;
 -          }
 -        
 -        }
 -
 -        read = xbt_getline(&line, &n, fp);
 - 
 -      }
 -
 -      if(new_variable == 1){
 -        
 -        if(!global_variable){
 -          variable_frame = xbt_dict_get_or_null(*local_variables, current_frame);
 -          var->type_origin = strdup(type_origin);
 -          var->global = 0;
 -          index = MC_dwarf_get_variable_index(variable_frame->variables, var->name, NULL);
 -          if(index != -1)
 -            xbt_dynar_insert_at(variable_frame->variables, index, &var);
 -        }else{
 -          var->type_origin = strdup(type_origin);
 -          var->global = 1;
 -          index = MC_dwarf_get_variable_index(*global_variables, var->name, var->address.address);
 -          if(index != -1)
 -            xbt_dynar_insert_at(*global_variables, index, &var); 
 -        }
 -
 -         xbt_free(type_origin);
 -         type_origin = NULL;
 -      }
 -
 -      global_variable = 0;
 -      new_variable = 1;
 -
 -    }else if(strcmp(node_type, "(DW_TAG_inlined_subroutine)") == 0){
 -
 -      read = xbt_getline(&line, &n, fp);
 -
 -      while(read != -1){
 -
 -        /* Wipeout the new line character */
 -        line[read - 1] = '\0'; 
 -
 -        if(n == 0 || strlen(line) == 0){
 -          read = xbt_getline(&line, &n, fp);
 -          continue;
 -        }
 -
 -        xbt_dynar_free(&split);
 -        xbt_str_rtrim(line, NULL);
 -        xbt_str_strip_spaces(line);
 -        split = xbt_str_split(line, " ");
 -        
 -        if(strncmp(xbt_dynar_get_as(split, 1, char *), "DW_AT_", 6) != 0)
 -          break;
 -          
 -        node_type = xbt_dynar_get_as(split, 1, char *);
 -
 -        if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){
 -
 -          origin = xbt_dynar_get_as(split, 2, char *);
 -          xbt_str_ltrim(origin, "<0x");
 -          xbt_str_rtrim(origin, ">");
 -          
 -          subprogram_name = (char *)xbt_dict_get_or_null(subprograms_origin, origin);
 -          subroutine_frame = xbt_dict_get_or_null(*local_variables, subprogram_name);
 -        
 -        }else if(strcmp(node_type, "DW_AT_low_pc") == 0){
 -
 -          subroutine_frame->low_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
 -
 -        }else if(strcmp(node_type, "DW_AT_high_pc") == 0){
 -
 -          subroutine_frame->high_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
 -        }
 -
 -        read = xbt_getline(&line, &n, fp);
 -      
 -      }
 -
 -    }else if(strcmp(node_type, "(DW_TAG_base_type)") == 0 
 -             || strcmp(node_type, "(DW_TAG_enumeration_type)") == 0
 -             || strcmp(node_type, "(DW_TAG_enumerator)") == 0
 -             || strcmp(node_type, "(DW_TAG_typedef)") == 0
 -             || strcmp(node_type, "(DW_TAG_const_type)") == 0
 -             || strcmp(node_type, "(DW_TAG_subroutine_type)") == 0
 -             || strcmp(node_type, "(DW_TAG_volatile_type)") == 0
 -             || (is_pointer = !strcmp(node_type, "(DW_TAG_pointer_type)"))){
 -
 -      if(strcmp(node_type, "(DW_TAG_base_type)") == 0)
 -        type_type = e_dw_base_type;
 -      else if(strcmp(node_type, "(DW_TAG_enumeration_type)") == 0)
 -        type_type = e_dw_enumeration_type;
 -      else if(strcmp(node_type, "(DW_TAG_enumerator)") == 0)
 -        type_type = e_dw_enumerator;
 -      else if(strcmp(node_type, "(DW_TAG_typedef)") == 0)
 -        type_type = e_dw_typedef;
 -      else if(strcmp(node_type, "(DW_TAG_const_type)") == 0)
 -        type_type = e_dw_const_type;
 -      else if(strcmp(node_type, "(DW_TAG_pointer_type)") == 0)
 -        type_type = e_dw_pointer_type;
 -      else if(strcmp(node_type, "(DW_TAG_subroutine_type)") == 0)
 -        type_type = e_dw_subroutine_type;
 -      else if(strcmp(node_type, "(DW_TAG_volatile_type)") == 0)
 -        type_type = e_dw_volatile_type;
 -
 -      strtok(xbt_dynar_get_as(split, 0, char *), "<");
 -      origin = strdup(strtok(NULL, "<"));
 -      xbt_str_rtrim(origin, ">:");
 -      
 -      read = xbt_getline(&line, &n, fp);
 -      
 -      while(read != -1){
 -        
 -         /* Wipeout the new line character */
 -        line[read - 1] = '\0'; 
 -
 -        if(n == 0 || strlen(line) == 0){
 -          read = xbt_getline(&line, &n, fp);
 -          continue;
 -        }
 -
 -        xbt_dynar_free(&split);
 -        xbt_str_rtrim(line, NULL);
 -        xbt_str_strip_spaces(line);
 -        split = xbt_str_split(line, " ");
 -        
 -        if(strncmp(xbt_dynar_get_as(split, 1, char *), "DW_AT_", 6) != 0)
 -          break;
 -
 -        node_type = xbt_dynar_get_as(split, 1, char *);
 -
 -        if(strcmp(node_type, "DW_AT_byte_size") == 0){
 -          size = strtol(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL, 10);
 -          if(type_type == e_dw_enumeration_type)
 -            enumeration_size = size;
 -        }else if(strcmp(node_type, "DW_AT_name") == 0){
 -          end = xbt_str_join(split, " ");
 -          xbt_dynar_free(&split);
 -          split = xbt_str_split(end, "):");
 -          xbt_str_ltrim(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL);
 -          name = xbt_strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*));
 -        }else if(strcmp(node_type, "DW_AT_type") == 0){
 -          type_origin = xbt_strdup(xbt_dynar_get_as(split, 3, char *));
 -          xbt_str_ltrim(type_origin, "<0x");
 -          xbt_str_rtrim(type_origin, ">");
 -        }
 -        
 -        read = xbt_getline(&line, &n, fp);
 -      }
 -
 -      dw_type_t type = xbt_new0(s_dw_type_t, 1);
 -      type->type = type_type;
 -      if(name)
 -        type->name = xbt_strdup(name);
 -      else
 -        type->name = xbt_strdup("undefined");
 -      type->is_pointer_type = is_pointer;
 -      type->id = (void *)strtoul(origin, NULL, 16);
 -      if(type_origin)
 -        type->dw_type_id = xbt_strdup(type_origin);
 -      if(type_type == e_dw_enumerator)
 -        type->size = enumeration_size;
 -      else
 -        type->size = size;
 -      type->members = NULL;
 -
 -      xbt_dict_set(*types, origin, type, NULL); 
 -
 -      xbt_free(name);
 -      name = NULL;
 -      xbt_free(type_origin);
 -      type_origin = NULL;
 -      xbt_free(end);
 -      end = NULL;
 -
 -      is_pointer = 0;
 -      size = 0;
 -      xbt_free(origin);
 -
 -    }else if(strcmp(node_type, "(DW_TAG_structure_type)") == 0 || strcmp(node_type, "(DW_TAG_union_type)") == 0){
 -      
 -      if(strcmp(node_type, "(DW_TAG_structure_type)") == 0)
 -        struct_decl = 1;
 -      else
 -        union_decl = 1;
 -
 -      strtok(xbt_dynar_get_as(split, 0, char *), "<");
 -      origin = strdup(strtok(NULL, "<"));
 -      xbt_str_rtrim(origin, ">:");
 -      
 -      read = xbt_getline(&line, &n, fp);
 -
 -      dw_type_t type = NULL;
 -
 -      while(read != -1){
 -      
 -        while(read != -1){
 -        
 -          /* Wipeout the new line character */
 -          line[read - 1] = '\0'; 
 -
 -          if(n == 0 || strlen(line) == 0){
 -            read = xbt_getline(&line, &n, fp);
 -            continue;
 -          }
 -
 -          xbt_dynar_free(&split);
 -          xbt_str_rtrim(line, NULL);
 -          xbt_str_strip_spaces(line);
 -          split = xbt_str_split(line, " ");
 -        
 -          node_type = xbt_dynar_get_as(split, 1, char *);
 -
 -          if(strncmp(node_type, "DW_AT_", 6) != 0){
 -            member_end = 1;
 -            break;
 -          }
 -
 -          if(strcmp(node_type, "DW_AT_byte_size") == 0){
 -            size = strtol(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL, 10);
 -          }else if(strcmp(node_type, "DW_AT_name") == 0){
 -            xbt_free(end);
 -            end = xbt_str_join(split, " ");
 -            xbt_dynar_free(&split);
 -            split = xbt_str_split(end, "):");
 -            xbt_str_ltrim(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL);
 -            name = xbt_strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*));
 -          }else if(strcmp(node_type, "DW_AT_type") == 0){
 -            type_origin = xbt_strdup(xbt_dynar_get_as(split, 3, char *));
 -            xbt_str_ltrim(type_origin, "<0x");
 -            xbt_str_rtrim(type_origin, ">");
 -          }else if(strcmp(node_type, "DW_AT_data_member_location:") == 0){
 -            xbt_free(end);
 -            end = xbt_str_join(split, " ");
 -            xbt_dynar_free(&split);
 -            split = xbt_str_split(end, "DW_OP_plus_uconst:");
 -            xbt_str_ltrim(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), NULL);
 -            xbt_str_rtrim(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), ")");
 -            offset = strtol(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL, 10);
 -          }
 -
 -          read = xbt_getline(&line, &n, fp);
 -          
 -        }
 -
 -        if(member_end && type){         
 -          member_end = 0;
 -          
 -          dw_type_t member_type = xbt_new0(s_dw_type_t, 1);
 -          member_type->name = xbt_strdup(name);
 -          member_type->size = size;
 -          member_type->is_pointer_type = is_pointer;
 -          member_type->id = (void *)strtoul(origin, NULL, 16);
 -          member_type->offset = offset;
 -          if(type_origin)
 -            member_type->dw_type_id = xbt_strdup(type_origin);
 -
 -          xbt_dynar_push(type->members, &member_type);
 -
 -          xbt_free(name);
 -          name = NULL;
 -          xbt_free(end);
 -          end = NULL;
 -          xbt_free(type_origin);
 -          type_origin = NULL;
 -          size = 0;
 -          offset = 0;
 -
 -          xbt_free(origin);
 -          origin = NULL;
 -          strtok(xbt_dynar_get_as(split, 0, char *), "<");
 -          origin = strdup(strtok(NULL, "<"));
 -          xbt_str_rtrim(origin, ">:");
 -
 -        }
 -
 -        if(struct_decl || union_decl){
 -          type = xbt_new0(s_dw_type_t, 1);
 -          if(struct_decl)
 -            type->type = e_dw_structure_type;
 -          else
 -            type->type = e_dw_union_type;
 -          type->name = xbt_strdup(name);
 -          type->size = size;
 -          type->is_pointer_type = is_pointer;
 -          type->id = (void *)strtoul(origin, NULL, 16);
 -          if(type_origin)
 -            type->dw_type_id = xbt_strdup(type_origin);
 -          type->members = xbt_dynar_new(sizeof(dw_type_t), dw_type_free_voidp);
 -          
 -          xbt_dict_set(*types, origin, type, NULL); 
 -          
 -          xbt_free(name);
 -          name = NULL;
 -          xbt_free(end);
 -          end = NULL;
 -          xbt_free(type_origin);
 -          type_origin = NULL;
 -          size = 0;
 -          struct_decl = 0;
 -          union_decl = 0;
 -
 -        }
 -
 -        if(strcmp(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), "(DW_TAG_member)") != 0)
 -          break;  
 -
 -        read = xbt_getline(&line, &n, fp);
 -    
 -      }
 -
 -      xbt_free(origin);
 -      origin = NULL;
 -
 -    }else if(strcmp(node_type, "(DW_TAG_array_type)") == 0){
 -      
 -      strtok(xbt_dynar_get_as(split, 0, char *), "<");
 -      origin = strdup(strtok(NULL, "<"));
 -      xbt_str_rtrim(origin, ">:");
 -      
 -      read = xbt_getline(&line, &n, fp);
 -
 -      dw_type_t type = NULL;
 -
 -      while(read != -1){
 -      
 -        while(read != -1){
 -        
 -          /* Wipeout the new line character */
 -          line[read - 1] = '\0'; 
 -
 -          if(n == 0 || strlen(line) == 0){
 -            read = xbt_getline(&line, &n, fp);
 -            continue;
 -          }
 -
 -          xbt_dynar_free(&split);
 -          xbt_str_rtrim(line, NULL);
 -          xbt_str_strip_spaces(line);
 -          split = xbt_str_split(line, " ");
 -        
 -          node_type = xbt_dynar_get_as(split, 1, char *);
 -
 -          if(strncmp(node_type, "DW_AT_", 6) != 0)
 -            break;
 -
 -          if(strcmp(node_type, "DW_AT_upper_bound") == 0){
 -            size = strtol(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL, 10);
 -          }else if(strcmp(node_type, "DW_AT_name") == 0){
 -            end = xbt_str_join(split, " ");
 -            xbt_dynar_free(&split);
 -            split = xbt_str_split(end, "):");
 -            xbt_str_ltrim(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL);
 -            name = xbt_strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*));
 -          }else if(strcmp(node_type, "DW_AT_type") == 0){
 -            type_origin = xbt_strdup(xbt_dynar_get_as(split, 3, char *));
 -            xbt_str_ltrim(type_origin, "<0x");
 -            xbt_str_rtrim(type_origin, ">");
 -          }
 -
 -          read = xbt_getline(&line, &n, fp);
 -          
 -        }
 -
 -        if(strcmp(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), "(DW_TAG_subrange_type)") == 0){
 -          subrange = 1;         
 -        }
 -
 -        if(subrange && type){         
 -          type->size = size;
 -      
 -          xbt_free(name);
 -          name = NULL;
 -          xbt_free(end);
 -          end = NULL;
 -          xbt_free(type_origin);
 -          type_origin = NULL;
 -          size = 0;
 -
 -          xbt_free(origin);
 -          origin = NULL;
 -          strtok(xbt_dynar_get_as(split, 0, char *), "<");
 -          origin = strdup(strtok(NULL, "<"));
 -          xbt_str_rtrim(origin, ">:");
 -
 -        }else {
 -          
 -          type = xbt_new0(s_dw_type_t, 1);
 -          type->type = e_dw_array_type;
 -          type->name = xbt_strdup(name);
 -          type->is_pointer_type = is_pointer;
 -          type->id = (void *)strtoul(origin, NULL, 16);
 -          if(type_origin)
 -            type->dw_type_id = xbt_strdup(type_origin);
 -          type->members = NULL;
 -          
 -          xbt_dict_set(*types, origin, type, NULL); 
 -          
 -          xbt_free(name);
 -          name = NULL;
 -          xbt_free(end);
 -          end = NULL;
 -          xbt_free(type_origin);
 -          type_origin = NULL;
 -          size = 0;
 -        }
 -
 -        if(strcmp(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), "(DW_TAG_subrange_type)") != 0)
 -          break;  
 -
 -        read = xbt_getline(&line, &n, fp);
 -    
 -      }
 -
 -      xbt_free(origin);
 -      origin = NULL;
 -
 -    }else{
 -
 -      read = xbt_getline(&line, &n, fp);
 -
 -    }
 +void MC_dwarf_register_non_global_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable) {
 +  xbt_assert(frame, "Frame is NULL");
 +  int index = MC_dwarf_get_variable_index(frame->variables, variable->name, NULL);
 +  if (index != -1)
 +    xbt_dynar_insert_at(frame->variables, index, &variable);
 +  // TODO, else ?
 +}
  
 -  }
 -  
 -  xbt_dynar_free(&split);
 -  xbt_dict_free(&variables_origin);
 -  xbt_dict_free(&subprograms_origin);
 -  xbt_free(line);
 -  xbt_free(command);
 -  pclose(fp);
 -  
 +void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable) {
 +  if(variable->global)
 +    MC_dwarf_register_global_variable(info, variable);
 +  else if(frame==NULL)
 +    xbt_die("No frame for this local variable");
 +  else
 +    MC_dwarf_register_non_global_variable(info, frame, variable);
  }
  
  
@@@ -588,6 -1228,10 +587,6 @@@ typedef struct s_mc_stack_ignore_variab
    char *frame;
  }s_mc_stack_ignore_variable_t, *mc_stack_ignore_variable_t;
  
 -typedef struct s_mc_data_bss_ignore_variable{
 -  char *name;
 -}s_mc_data_bss_ignore_variable_t, *mc_data_bss_ignore_variable_t;
 -
  /**************************** Free functions ******************************/
  
  static void stack_ignore_variable_free(mc_stack_ignore_variable_t v){
@@@ -608,6 -1252,15 +607,6 @@@ void heap_ignore_region_free_voidp(voi
    heap_ignore_region_free((mc_heap_ignore_region_t) * (void **) r);
  }
  
 -static void data_bss_ignore_variable_free(mc_data_bss_ignore_variable_t v){
 -  xbt_free(v->name);
 -  xbt_free(v);
 -}
 -
 -static void data_bss_ignore_variable_free_voidp(void *v){
 -  data_bss_ignore_variable_free((mc_data_bss_ignore_variable_t) * (void **) v);
 -}
 -
  static void checkpoint_ignore_region_free(mc_checkpoint_ignore_region_t r){
    xbt_free(r);
  }
@@@ -722,26 -1375,69 +721,26 @@@ void MC_ignore_global_variable(const ch
  
    MC_SET_RAW_MEM;
  
 -  if(mc_global_variables_libsimgrid){
 +  xbt_assert(mc_libsimgrid_info, "MC subsystem not initialized");
  
      unsigned int cursor = 0;
      dw_variable_t current_var;
      int start = 0;
 -    int end = xbt_dynar_length(mc_global_variables_libsimgrid) - 1;
 +    int end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
  
      while(start <= end){
        cursor = (start + end) /2;
 -      current_var = (dw_variable_t)xbt_dynar_get_as(mc_global_variables_libsimgrid, cursor, dw_variable_t);
 +      current_var = (dw_variable_t)xbt_dynar_get_as(mc_libsimgrid_info->global_variables, cursor, dw_variable_t);
        if(strcmp(current_var->name, name) == 0){
 -        xbt_dynar_remove_at(mc_global_variables_libsimgrid, cursor, NULL);
 +        xbt_dynar_remove_at(mc_libsimgrid_info->global_variables, cursor, NULL);
          start = 0;
 -        end = xbt_dynar_length(mc_global_variables_libsimgrid) - 1;
 +        end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
        }else if(strcmp(current_var->name, name) < 0){
          start = cursor + 1;
        }else{
          end = cursor - 1;
        } 
      }
 -   
 -  }else{
 -
 -    if(mc_data_bss_comparison_ignore == NULL)
 -      mc_data_bss_comparison_ignore = xbt_dynar_new(sizeof(mc_data_bss_ignore_variable_t), data_bss_ignore_variable_free_voidp);
 -
 -    mc_data_bss_ignore_variable_t var = NULL;
 -    var = xbt_new0(s_mc_data_bss_ignore_variable_t, 1);
 -    var->name = strdup(name);
 -
 -    if(xbt_dynar_is_empty(mc_data_bss_comparison_ignore)){
 -
 -      xbt_dynar_insert_at(mc_data_bss_comparison_ignore, 0, &var);
 -
 -    }else{
 -    
 -      unsigned int cursor = 0;
 -      int start = 0;
 -      int end = xbt_dynar_length(mc_data_bss_comparison_ignore) - 1;
 -      mc_data_bss_ignore_variable_t current_var = NULL;
 -
 -      while(start <= end){
 -        cursor = (start + end) / 2;
 -        current_var = (mc_data_bss_ignore_variable_t)xbt_dynar_get_as(mc_data_bss_comparison_ignore, cursor, mc_data_bss_ignore_variable_t);
 -        if(strcmp(current_var->name, name) == 0){
 -          data_bss_ignore_variable_free(var);
 -          if(!raw_mem_set)
 -            MC_UNSET_RAW_MEM;
 -          return;
 -        }else if(strcmp(current_var->name, name) < 0){
 -          start = cursor + 1;
 -        }else{
 -          end = cursor - 1;
 -        }
 -      }
 -
 -      if(strcmp(current_var->name, name) < 0)
 -        xbt_dynar_insert_at(mc_data_bss_comparison_ignore, cursor + 1, &var);
 -      else
 -        xbt_dynar_insert_at(mc_data_bss_comparison_ignore, cursor, &var);
 -
 -    }
 -  }
  
    if(!raw_mem_set)
      MC_UNSET_RAW_MEM;
@@@ -753,6 -1449,7 +752,6 @@@ void MC_ignore_local_variable(const cha
  
    MC_SET_RAW_MEM;
  
 -  if(mc_local_variables_libsimgrid){
      unsigned int cursor = 0;
      dw_variable_t current_var;
      int start, end;
        xbt_dict_cursor_t dict_cursor;
        char *current_frame_name;
        dw_frame_t frame;
 -      xbt_dict_foreach(mc_local_variables_libsimgrid, dict_cursor, current_frame_name, frame){
 +      xbt_dict_foreach(mc_libsimgrid_info->local_variables, dict_cursor, current_frame_name, frame){
          start = 0;
          end = xbt_dynar_length(frame->variables) - 1;
          while(start <= end){
            } 
          }
        }
 -       xbt_dict_foreach(mc_local_variables_binary, dict_cursor, current_frame_name, frame){
 +       xbt_dict_foreach(mc_binary_info->local_variables, dict_cursor, current_frame_name, frame){
          start = 0;
          end = xbt_dynar_length(frame->variables) - 1;
          while(start <= end){
          }
        }
      }else{
 -      xbt_dynar_t variables_list = ((dw_frame_t)xbt_dict_get_or_null(mc_local_variables_libsimgrid, frame_name))->variables;
 +      xbt_dynar_t variables_list = ((dw_frame_t)xbt_dict_get_or_null(
 +                                      mc_libsimgrid_info->local_variables, frame_name))->variables;
        start = 0;
        end = xbt_dynar_length(variables_list) - 1;
        while(start <= end){
          } 
        }
      } 
 -  }else{
 -
 -    if(mc_stack_comparison_ignore == NULL)
 -      mc_stack_comparison_ignore = xbt_dynar_new(sizeof(mc_stack_ignore_variable_t), stack_ignore_variable_free_voidp);
 -  
 -    mc_stack_ignore_variable_t var = NULL;
 -    var = xbt_new0(s_mc_stack_ignore_variable_t, 1);
 -    var->var_name = strdup(var_name);
 -    var->frame = strdup(frame_name);
 -  
 -    if(xbt_dynar_is_empty(mc_stack_comparison_ignore)){
 -
 -      xbt_dynar_insert_at(mc_stack_comparison_ignore, 0, &var);
 -
 -    }else{
 -    
 -      unsigned int cursor = 0;
 -      int start = 0;
 -      int end = xbt_dynar_length(mc_stack_comparison_ignore) - 1;
 -      mc_stack_ignore_variable_t current_var = NULL;
 -
 -      while(start <= end){
 -        cursor = (start + end) / 2;
 -        current_var = (mc_stack_ignore_variable_t)xbt_dynar_get_as(mc_stack_comparison_ignore, cursor, mc_stack_ignore_variable_t);
 -        if(strcmp(current_var->frame, frame_name) == 0){
 -          if(strcmp(current_var->var_name, var_name) == 0){
 -            stack_ignore_variable_free(var);
 -            if(!raw_mem_set)
 -              MC_UNSET_RAW_MEM;
 -            return;
 -          }else if(strcmp(current_var->var_name, var_name) < 0){
 -            start = cursor + 1;
 -          }else{
 -            end = cursor - 1;
 -          }
 -        }else if(strcmp(current_var->frame, frame_name) < 0){
 -          start = cursor + 1;
 -        }else{
 -          end = cursor - 1;
 -        }
 -      }
 -
 -      if(strcmp(current_var->frame, frame_name) == 0){
 -        if(strcmp(current_var->var_name, var_name) < 0){
 -          xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor + 1, &var);
 -        }else{
 -          xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor, &var);
 -        }
 -      }else if(strcmp(current_var->frame, frame_name) < 0){
 -        xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor + 1, &var);
 -      }else{
 -        xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor, &var);
 -      }
 -    }
 -  }
  
    if(!raw_mem_set)
      MC_UNSET_RAW_MEM;
@@@ -904,39 -1655,44 +903,39 @@@ void MC_ignore(void *addr, size_t size)
  /*******************************  Initialisation of MC *******************************/
  /*********************************************************************************/
  
 -static void MC_dump_ignored_local_variables(void){
 -
 -  if(mc_stack_comparison_ignore == NULL || xbt_dynar_is_empty(mc_stack_comparison_ignore))
 -    return;
 -
 -  unsigned int cursor = 0;
 -  mc_stack_ignore_variable_t current_var;
 -
 -  xbt_dynar_foreach(mc_stack_comparison_ignore, cursor, current_var){
 -    MC_ignore_local_variable(current_var->var_name, current_var->frame);
 +static void MC_post_process_object_info(mc_object_info_t info) {
 +  mc_object_info_t other_info = info == mc_binary_info ? mc_libsimgrid_info : mc_binary_info;
 +  xbt_dict_cursor_t cursor = NULL;
 +  char* key = NULL;
 +  dw_type_t type = NULL;
 +  xbt_dict_foreach(info->types, cursor, key, type){
 +    if(type->name && type->byte_size == 0) {
 +      type->other_object_same_type = xbt_dict_get_or_null(other_info->types_by_name, type->name);
 +    }
    }
 -
 -  xbt_dynar_free(&mc_stack_comparison_ignore);
 -  mc_stack_comparison_ignore = NULL;
 - 
  }
  
 -static void MC_dump_ignored_global_variables(void){
 -
 -  if(mc_data_bss_comparison_ignore == NULL || xbt_dynar_is_empty(mc_data_bss_comparison_ignore))
 -    return;
 +static void MC_init_debug_info(void) {
 +  XBT_INFO("Get debug information ...");
  
 -  unsigned int cursor = 0;
 -  mc_data_bss_ignore_variable_t current_var;
 +  memory_map_t maps = MC_get_memory_map();
  
 -  xbt_dynar_foreach(mc_data_bss_comparison_ignore, cursor, current_var){
 -    MC_ignore_global_variable(current_var->name);
 -  } 
 +  /* Get local variables for state equality detection */
 +  mc_binary_info = MC_find_object_info(maps, xbt_binary_name, 1);
 +  mc_libsimgrid_info = MC_find_object_info(maps, libsimgrid_path, 0);
  
 -  xbt_dynar_free(&mc_data_bss_comparison_ignore);
 -  mc_data_bss_comparison_ignore = NULL;
 +  // Use information of the other objects:
 +  MC_post_process_object_info(mc_binary_info);
 +  MC_post_process_object_info(mc_libsimgrid_info);
  
 +  MC_free_memory_map(maps);
 +  XBT_INFO("Get debug information done !");
  }
  
  void MC_init(){
  
    int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 -  
 +
    compare = 0;
  
    /* Initialize the data structures that must be persistent across every
    MC_SET_RAW_MEM;
  
    MC_init_memory_map_info();
 -  
 -  mc_local_variables_libsimgrid = xbt_dict_new_homogeneous(NULL);
 -  mc_local_variables_binary = xbt_dict_new_homogeneous(NULL);
 -  mc_global_variables_libsimgrid = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp);
 -  mc_global_variables_binary = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp);
 -  mc_variables_type_libsimgrid = xbt_dict_new_homogeneous(NULL);
 -  mc_variables_type_binary = xbt_dict_new_homogeneous(NULL);
 -
 -  XBT_INFO("Get debug information ...");
 -
 -  /* Get local variables in binary for state equality detection */
 -  xbt_dict_t binary_location_list = MC_dwarf_get_location_list(xbt_binary_name);
 -  MC_dwarf_get_variables(xbt_binary_name, binary_location_list, &mc_local_variables_binary, &mc_global_variables_binary, &mc_variables_type_binary);
 -
 -  /* Get local variables in libsimgrid for state equality detection */
 -  xbt_dict_t libsimgrid_location_list = MC_dwarf_get_location_list(libsimgrid_path);
 -  MC_dwarf_get_variables(libsimgrid_path, libsimgrid_location_list, &mc_local_variables_libsimgrid, &mc_global_variables_libsimgrid, &mc_variables_type_libsimgrid);
 -
 -  xbt_dict_free(&libsimgrid_location_list);
 -  xbt_dict_free(&binary_location_list);
 -
 -  XBT_INFO("Get debug information done !");
 -
 -  /* Remove variables ignored before getting list of variables */
 -  MC_dump_ignored_local_variables();
 -  MC_dump_ignored_global_variables();
 -  
 -  /* Get .plt section (start and end addresses) for data libsimgrid and data program comparison */
 -  MC_get_libsimgrid_plt_section();
 -  MC_get_binary_plt_section();
 +  MC_init_debug_info();
  
     /* Init parmap */
    parmap = xbt_parmap_mc_new(xbt_os_get_numcores(), XBT_PARMAP_DEFAULT);
    MC_ignore_global_variable("counter"); /* Static variable used for tracing */
    MC_ignore_global_variable("maestro_stack_start");
    MC_ignore_global_variable("maestro_stack_end");
 +  MC_ignore_global_variable("smx_total_comms");
  
    MC_ignore_heap(&(simix_global->process_to_run), sizeof(simix_global->process_to_run));
    MC_ignore_heap(&(simix_global->process_that_ran), sizeof(simix_global->process_that_ran));
@@@ -1081,7 -1865,8 +1080,7 @@@ void MC_modelcheck_safety(void
    }else{
      MC_SET_RAW_MEM;
      MC_init_memory_map_info();
 -    MC_get_libsimgrid_plt_section();
 -    MC_get_binary_plt_section();
 +    MC_init_debug_info();
      MC_UNSET_RAW_MEM;
    }
  
    /* Save the initial state */
    initial_state_safety = xbt_new0(s_mc_global_t, 1);
    initial_state_safety->snapshot = MC_take_snapshot(0);
 +  initial_state_safety->initial_communications_pattern_done = 0;
 +  initial_state_safety->comm_deterministic = 1;
 +  initial_state_safety->send_deterministic = 1;
    MC_UNSET_RAW_MEM;
  
    MC_dpor();
@@@ -1148,7 -1930,6 +1147,7 @@@ void MC_modelcheck_liveness()
  void MC_exit(void)
  {
    xbt_free(mc_time);
 +
    MC_memory_exit();
    //xbt_abort();
  }
@@@ -1217,7 -1998,6 +1216,7 @@@ void MC_replay(xbt_fifo_t stack, int st
    xbt_fifo_item_t item, start_item;
    mc_state_t state;
    smx_process_t process = NULL;
 +  int comm_pattern = 0;
  
    XBT_DEBUG("**** Begin Replay ****");
  
        xbt_free(key);
      }
    }
 +  if(_sg_mc_comms_determinism)
 +    xbt_dynar_reset(communications_pattern);
    MC_UNSET_RAW_MEM;
    
  
          xbt_free(req_str);
        }
      }
 -    
 +
 +    if(_sg_mc_comms_determinism){
 +      if(req->call == SIMCALL_COMM_ISEND)
 +        comm_pattern = 1;
 +      else if(req->call == SIMCALL_COMM_IRECV)
 +      comm_pattern = 2;
 +    }
 +
      SIMIX_simcall_pre(req, value);
 +
 +    if(_sg_mc_comms_determinism){
 +      MC_SET_RAW_MEM;
 +      if(comm_pattern != 0){
 +        get_comm_pattern(communications_pattern, req, comm_pattern);
 +      }
 +      MC_UNSET_RAW_MEM;
 +      comm_pattern = 0;
 +    }
 +    
      MC_wait_for_requests();
  
      count++;
@@@ -1577,10 -2338,6 +1576,10 @@@ void MC_print_statistics(mc_stats_t sta
      fprintf(dot_output, "}\n");
      fclose(dot_output);
    }
 +  if(initial_state_safety != NULL && _sg_mc_comms_determinism){
 +    XBT_INFO("Communication-deterministic : %s", !initial_state_safety->comm_deterministic ? "No" : "Yes");
 +    XBT_INFO("Send-deterministic : %s", !initial_state_safety->send_deterministic ? "No" : "Yes");
 +  }
    MC_UNSET_RAW_MEM;
  }
  
diff --combined src/mc/mc_liveness.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2011-2013. The SimGrid Team.
+ /* Copyright (c) 2011-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -36,10 -36,6 +36,10 @@@ static xbt_dynar_t get_atomic_propositi
    return values;
  }
  
 +/** \brief Find a suitable subrange of candidate duplicates for a given state
 + *
 + *  See mc_dpor.c with a similar (same?) function.
 + */
  static int get_search_interval(xbt_dynar_t all_pairs, mc_visited_pair_t pair, int *min, int *max){
  
    int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
@@@ -118,15 -114,12 +118,15 @@@ static mc_visited_pair_t is_reached_acc
      index = get_search_interval(acceptance_pairs, pair, &min, &max);
  
      if(min != -1 && max != -1){ // Acceptance pair with same number of processes and same heap bytes used exists
 +
 +      // Parallell implementation
        /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(acceptance_pairs, min), (max-min)+1, pair);
        if(res != -1){
          if(!raw_mem_set)
            MC_UNSET_RAW_MEM;
          return ((mc_pair_t)xbt_dynar_get_as(acceptance_pairs, (min+res)-1, mc_pair_t))->num;
          }*/
 +
        cursor = min;
        while(cursor <= max){
          pair_test = (mc_visited_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_visited_pair_t);
@@@ -199,9 -192,6 +199,9 @@@ static void remove_acceptance_pair(int 
      MC_UNSET_RAW_MEM;
  }
  
 +/** \brief Checks whether a given state has already been visited by the algorithm.
 + *
 + */
  static int is_visited_pair(mc_visited_pair_t pair, int pair_num, xbt_automaton_state_t automaton_state, xbt_dynar_t atomic_propositions){
  
    if(_sg_mc_visited == 0)
                  if(dot_output == NULL)
                    XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", new_pair->num, pair_test->num);
                  else
 -                  XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", new_pair->num, pair_test->num, pair->other_num);
 +                  XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", new_pair->num, pair_test->num, new_pair->other_num);
                  xbt_dynar_remove_at(visited_pairs, cursor, NULL);
                  xbt_dynar_insert_at(visited_pairs, cursor, &new_pair);
                  pair_test->visited_removed = 1;
diff --combined src/mc/mc_memory.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -39,9 -39,6 +39,9 @@@ void MC_memory_init(
  #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/mc/mc_private.h
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007-2013. The SimGrid Team.
+ /* Copyright (c) 2007-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -12,8 -12,6 +12,8 @@@
  #ifndef WIN32
  #include <sys/mman.h>
  #endif
 +#include <elfutils/libdw.h>
 +
  #include "mc/mc.h"
  #include "mc/datatypes.h"
  #include "xbt/fifo.h"
@@@ -28,9 -26,6 +28,9 @@@
  #include "xbt/strbuff.h"
  #include "xbt/parmap.h"
  
 +typedef struct s_dw_frame s_dw_frame_t, *dw_frame_t;
 +typedef struct s_mc_function_index_item s_mc_function_index_item_t, *mc_function_index_item_t;
 +
  /****************************** Snapshots ***********************************/
  
  #define NB_REGIONS 3 /* binary data (data + BSS) (type = 2), libsimgrid data (data + BSS) (type = 1), std_heap (type = 0)*/ 
@@@ -48,28 -43,14 +48,28 @@@ typedef struct s_mc_snapshot
    size_t *stack_sizes;
    xbt_dynar_t stacks;
    xbt_dynar_t to_ignore;
 -  char hash_global[41];
 -  char hash_local[41];
 +  uint64_t hash;
  } s_mc_snapshot_t, *mc_snapshot_t;
  
 +/** Information about a given stack frame
 + *
 + */
 +typedef struct s_mc_stack_frame {
 +  /** Instruction pointer */
 +  unw_word_t ip;
 +  /** Stack pointer */
 +  unw_word_t sp;
 +  unw_word_t frame_base;
 +  dw_frame_t frame;
 +  char* frame_name;
 +  unw_cursor_t unw_cursor;
 +} s_mc_stack_frame_t, *mc_stack_frame_t;
 +
  typedef struct s_mc_snapshot_stack{
    xbt_dynar_t local_variables;
    void *stack_pointer;
    void *real_address;
 +  xbt_dynar_t stack_frames; // mc_stack_frame_t
  }s_mc_snapshot_stack_t, *mc_snapshot_stack_t;
  
  typedef struct s_mc_global_t{
@@@ -77,9 -58,6 +77,9 @@@
    int raw_mem_set;
    int prev_pair;
    char *prev_req;
 +  int initial_communications_pattern_done;
 +  int comm_deterministic;
 +  int send_deterministic;
  }s_mc_global_t, *mc_global_t;
  
  typedef struct s_mc_checkpoint_ignore_region{
@@@ -240,8 -218,25 +240,8 @@@ typedef struct s_memory_map 
  void MC_init_memory_map_info(void);
  memory_map_t MC_get_memory_map(void);
  void MC_free_memory_map(memory_map_t map);
 -void MC_get_libsimgrid_plt_section(void);
 -void MC_get_binary_plt_section(void);
  
 -extern void *start_data_libsimgrid;
 -extern void *start_data_binary;
 -extern void *start_bss_binary;
  extern char *libsimgrid_path;
 -extern void *start_text_libsimgrid;
 -extern void *start_text_binary;
 -extern void *start_bss_libsimgrid;
 -extern void *start_plt_libsimgrid;
 -extern void *end_plt_libsimgrid;
 -extern void *start_plt_binary;
 -extern void *end_plt_binary;
 -extern void *start_got_plt_libsimgrid;
 -extern void *end_got_plt_libsimgrid;
 -extern void *start_got_plt_binary;
 -extern void *end_got_plt_binary;
 -
  
  /********************************** Snapshot comparison **********************************/
  
@@@ -253,6 -248,8 +253,6 @@@ typedef struct s_mc_comparison_times
    double libsimgrid_global_variables_comparison_time;
    double heap_comparison_time;
    double stacks_comparison_time;
 -  double hash_global_variables_comparison_time;
 -  double hash_local_variables_comparison_time;
  }s_mc_comparison_times_t, *mc_comparison_times_t;
  
  extern __thread mc_comparison_times_t mc_comp_times;
@@@ -265,6 -262,7 +265,6 @@@ void print_comparison_times(void)
  //#define MC_DEBUG 1
  #define MC_VERBOSE 1
  
 -
  /********************************** DPOR for safety property **************************************/
  
  typedef enum {
@@@ -296,6 -294,8 +296,6 @@@ extern xbt_fifo_t mc_stack_liveness
  extern mc_global_t initial_state_liveness;
  extern xbt_automaton_t _mc_property_automaton;
  extern int compare;
 -extern xbt_dynar_t mc_stack_comparison_ignore;
 -extern xbt_dynar_t mc_data_bss_comparison_ignore;
  
  typedef struct s_mc_pair{
    int num;
@@@ -333,42 -333,12 +333,42 @@@ void MC_dump_stack_liveness(xbt_fifo_t 
  
  /********************************** Variables with DWARF **********************************/
  
 -extern xbt_dict_t mc_local_variables_libsimgrid;
 -extern xbt_dict_t mc_local_variables_binary;
 -extern xbt_dynar_t mc_global_variables_libsimgrid;
 -extern xbt_dynar_t mc_global_variables_binary;
 -extern xbt_dict_t mc_variables_type_libsimgrid;
 -extern xbt_dict_t mc_variables_type_binary;
 +#define MC_OBJECT_INFO_EXECUTABLE 1
 +
 +struct s_mc_object_info {
 +  size_t flags;
 +  char* file_name;
 +  char *start_exec, *end_exec; // Executable segment
 +  char *start_rw, *end_rw; // Read-write segment
 +  char *start_ro, *end_ro; // read-only segment
 +  xbt_dict_t local_variables; // xbt_dict_t<frame_name, dw_frame_t>
 +  xbt_dynar_t global_variables; // xbt_dynar_t<dw_variable_t>
 +  xbt_dict_t types; // xbt_dict_t<origin as hexadecimal string, dw_type_t>
 +  xbt_dict_t types_by_name; // xbt_dict_t<name, dw_type_t> (full defined type only)
 +
 +  // Here we sort the minimal information for an efficient (and cache-efficient)
 +  // lookup of a function given an instruction pointer.
 +  // The entries are sorted by low_pc and a binary search can be used to look them up.
 +  xbt_dynar_t functions_index;
 +};
 +
 +mc_object_info_t MC_new_object_info(void);
 +mc_object_info_t MC_find_object_info(memory_map_t maps, char* name, int executable);
 +void MC_free_object_info(mc_object_info_t* p);
 +
 +void MC_dwarf_get_variables(mc_object_info_t info);
 +void MC_dwarf_get_variables_libdw(mc_object_info_t info);
 +const char* MC_dwarf_attrname(int attr);
 +const char* MC_dwarf_tagname(int tag);
 +
 +dw_frame_t MC_find_function_by_ip(void* ip);
 +mc_object_info_t MC_ip_find_object_info(void* ip);
 +
 +extern mc_object_info_t mc_libsimgrid_info;
 +extern mc_object_info_t mc_binary_info;
 +
 +void MC_find_object_address(memory_map_t maps, mc_object_info_t result);
 +void MC_post_process_types(mc_object_info_t info);
  
  typedef enum {
    e_dw_loclist,
@@@ -427,53 -397,30 +427,53 @@@ typedef struct s_dw_location
  }s_dw_location_t, *dw_location_t;
  
  typedef struct s_dw_location_entry{
 -  unsigned long lowpc;
 -  unsigned long highpc;
 +  void* lowpc;
 +  void* highpc;
    dw_location_t location;
  }s_dw_location_entry_t, *dw_location_entry_t;
  
  typedef struct s_dw_variable{
 +  Dwarf_Off dwarf_offset; /* Global offset of the field. */
    int global;
    char *name;
    char *type_origin;
 -  union{
 -    dw_location_t location;
 -    void *address;
 -  }address;
 +  dw_type_t type;
 +
 +  // Use either of:
 +  dw_location_t location;
 +  void* address;
 +
  }s_dw_variable_t, *dw_variable_t;
  
 -typedef struct s_dw_frame{
 +struct s_dw_frame{
    char *name;
    void *low_pc;
    void *high_pc;
    dw_location_t frame_base;
 -  xbt_dynar_t variables; /* Cannot use dict, there may be several variables with the same name (in different lexical blocks)*/
 -  unsigned long int start;
 -  unsigned long int end;
 -}s_dw_frame_t, *dw_frame_t;
 +  xbt_dynar_t /* <dw_variable_t> */ variables; /* Cannot use dict, there may be several variables with the same name (in different lexical blocks)*/
 +  unsigned long int start; /* DWARF offset of the subprogram */
 +  unsigned long int end;   /* Dwarf offset of the next sibling */
 +};
 +
 +struct s_mc_function_index_item {
 +  void* low_pc, *high_pc;
 +  dw_frame_t function;
 +};
 +
 +void dw_type_free(dw_type_t t);
 +void dw_variable_free(dw_variable_t v);
 +void dw_variable_free_voidp(void *t);
 +
 +void MC_dwarf_register_global_variable(mc_object_info_t info, dw_variable_t variable);
 +void MC_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable);
 +void MC_dwarf_register_non_global_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable);
 +void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable);
 +void* MC_object_base_address(mc_object_info_t info);
 +
 +/********************************** DWARF **********************************/
 +
 +Dwarf_Off MC_dwarf_resolve_location(unw_cursor_t* c, dw_location_t location, void* frame_pointer_address);
 +void* mc_find_frame_base(void* ip, dw_frame_t frame, unw_cursor_t* unw_cursor);
  
  /********************************** Miscellaneous **********************************/
  
@@@ -481,47 -428,10 +481,47 @@@ typedef struct s_local_variable
    char *frame;
    unsigned long ip;
    char *name;
 -  char *type;
 +  dw_type_t type;
    void *address;
    int region;
  }s_local_variable_t, *local_variable_t;
  
 +/********************************* Communications pattern ***************************/
 +
 +typedef struct s_mc_comm_pattern{
 +  int num;
 +  smx_action_t comm;
 +  e_smx_comm_type_t type;
 +  int completed;
 +  unsigned long src_proc;
 +  unsigned long dst_proc;
 +  char *rdv;
 +  size_t data_size;
 +  void *data;
 +  int matched_comm;
 +}s_mc_comm_pattern_t, *mc_comm_pattern_t;
 +
 +extern xbt_dynar_t communications_pattern;
 +
 +void get_comm_pattern(xbt_dynar_t communications_pattern, smx_simcall_t request, int call);
 +
 +/* *********** Sets *********** */
 +
 +typedef struct s_mc_address_set *mc_address_set_t;
 +
 +mc_address_set_t mc_address_set_new();
 +mc_address_set_t mc_address_set_free(mc_address_set_t* p);
 +void mc_address_add(mc_address_set_t p, const void* value);
 +bool mc_address_test(mc_address_set_t p, const void* value);
 +
 +/* *********** Hash *********** */
 +
 +/** \brief Hash the current state
 + *  \param num_state number of states
 + *  \param stacks stacks (mc_snapshot_stak_t) used fot the stack unwinding informations
 + *  \result resulting hash
 + * */
 +uint64_t mc_hash_processes_state(int num_state, xbt_dynar_t stacks);
 +
  #endif
  
diff --combined src/mc/mc_request.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -17,11 -17,7 +17,11 @@@ int MC_request_depend(smx_simcall_t r1
      return TRUE;
  
    if (r1->issuer == r2->issuer)
 -      return FALSE;
 +    return FALSE;
 +
 +  /* Wait with timeout transitions are not considered by the independance theorem, thus we consider them as dependant with all other transitions */
 +  if((r1->call == SIMCALL_COMM_WAIT && simcall_comm_wait__get__timeout(r1) > 0) || (r2->call == SIMCALL_COMM_WAIT && simcall_comm_wait__get__timeout(r2) > 0))
 +    return TRUE;
  
    if(r1->call == SIMCALL_COMM_ISEND && r2->call == SIMCALL_COMM_IRECV)
      return FALSE;
@@@ -339,8 -335,6 +339,8 @@@ int MC_request_is_enabled(smx_simcall_
        }
      }else{
        act = simcall_comm_wait__get__comm(req);
 +      if(act->comm.detached && act->comm.src_proc == NULL && act->comm.type == SIMIX_COMM_READY)
 +        return (act->comm.dst_proc != NULL);
        return (act->comm.src_proc && act->comm.dst_proc);
      }
      break;
diff --combined src/mc/mc_state.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -143,7 -143,6 +143,7 @@@ smx_simcall_t MC_state_get_request(mc_s
    smx_process_t process = NULL;
    mc_procstate_t procstate = NULL;
    unsigned int start_count;
 +  smx_action_t act = NULL;
  
    xbt_swag_foreach(process, simix_global->process_list){
      procstate = &state->proc_status[process->pid];
              break;
  
            case SIMCALL_COMM_WAIT:
 -            if(simcall_comm_wait__get__comm(&process->simcall)->comm.src_proc
 -               && simcall_comm_wait__get__comm(&process->simcall)->comm.dst_proc){
 +            act = simcall_comm_wait__get__comm(&process->simcall);
 +            if(act->comm.src_proc && act->comm.dst_proc){
                *value = 0;
              }else{
 -              *value = -1;
 +              if(act->comm.src_proc == NULL && act->comm.type == SIMIX_COMM_READY && act->comm.detached == 1)
 +                *value = 0;
 +              else
 +                *value = -1;
              }
              procstate->state = MC_DONE;
              return &process->simcall;
diff --combined src/simgrid/sg_config.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2009-2010, 2012-2013. The SimGrid Team.
+ /* Copyright (c) 2009-2010, 2012-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -67,6 -67,7 +67,7 @@@ static void sg_config_cmd_line(int *arg
  "Each of these configurations can be used by adding\n"
  "    --cfg=<option name>:<option value>\n"
  "to the command line.\n"
+ "\n"
  "You can also use --help-models to see the details of all models known by this simulator.\n"
  #ifdef HAVE_TRACING
  "\n"
      sg_cfg_exit_early();
  }
  
+ /* callback of the plugin variable */
+ static void _sg_cfg_cb__plugin(const char *name, int pos)
+ {
+   char *val;
+   XBT_VERB("PLUGIN");
+   xbt_assert(_sg_cfg_init_status < 2,
+               "Cannot load a plugin after the initialization");
+   val = xbt_cfg_get_string(_sg_cfg_set, name);
+   if (!strcmp(val, "help")) {
+     model_help("plugin", surf_plugin_description);
+     sg_cfg_exit_early();
+   }
+   /* New Module missing */
+   int plugin_id = find_model_description(surf_plugin_description, val);
+   surf_plugin_description[plugin_id].model_init_preparse();
+ }
  /* callback of the workstation/model variable */
  static void _sg_cfg_cb__workstation_model(const char *name, int pos)
  {
    find_model_description(surf_workstation_model_description, val);
  }
  
+ /* callback of the vm_workstation/model variable */
+ static void _sg_cfg_cb__vm_workstation_model(const char *name, int pos)
+ {
+   char *val;
+   xbt_assert(_sg_cfg_init_status < 2,
+               "Cannot change the model after the initialization");
+   val = xbt_cfg_get_string(_sg_cfg_set, name);
+   if (!strcmp(val, "help")) {
+     model_help("vm_workstation", surf_vm_workstation_model_description);
+     sg_cfg_exit_early();
+   }
+   /* Make sure that the model exists */
+   find_model_description(surf_vm_workstation_model_description, val);
+ }
  /* callback of the cpu/model variable */
  static void _sg_cfg_cb__cpu_model(const char *name, int pos)
  {
@@@ -407,106 -448,81 +448,81 @@@ static void _sg_cfg_cb__gtnets_jitter_s
  }
  #endif
  
+ /* build description line with possible values */
+ static void describe_model(char *result,
+                            const s_surf_model_description_t model_description[],
+                            const char *name,
+                            const char *description)
+ {
+   char *p = result +
+     sprintf(result, "%s. Possible values: %s", description,
+             model_description[0].name ? model_description[0].name : "n/a");
+   int i;
+   for (i = 1; model_description[i].name; i++)
+     p += sprintf(p, ", %s", model_description[i].name);
+   sprintf(p,
+       ".\n       (use 'help' as a value to see the long description of each %s)",
+           name);
+ }
  /* create the config set, register what should be and parse the command line*/
  void sg_config_init(int *argc, char **argv)
  {
-   char *description = xbt_malloc(1024);
-   char *p;
-   int i;
+   char description[1024];
  
    /* Create the configuration support */
    if (_sg_cfg_init_status == 0) { /* Only create stuff if not already inited */
-     sprintf(description,
-             "The model to use for the CPU. Possible values: ");
-     p = description;
-     while (*(++p) != '\0');
-     for (i = 0; surf_cpu_model_description[i].name; i++)
-       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
-                    surf_cpu_model_description[i].name);
-     sprintf(p,
-             ".\n       (use 'help' as a value to see the long description of each model)");
+     /* Plugins configuration */
+     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);
+     describe_model(description, surf_cpu_model_description,
+                    "model", "The model to use for the CPU");
      xbt_cfg_register(&_sg_cfg_set, "cpu/model", description,
                       xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__cpu_model, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/model", "Cas01");
  
-     while (*(++p) != '\0');
-     for (i = 0; surf_optimization_mode_description[i].name; i++)
-       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
-                    surf_optimization_mode_description[i].name);
-     sprintf(p,
-             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
+     describe_model(description, surf_optimization_mode_description,
+                    "optimization mode",
+                    "The optimization modes to use for the CPU");
      xbt_cfg_register(&_sg_cfg_set, "cpu/optim", description,
                       xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/optim", "Lazy");
  
-     sprintf(description,
-             "The model to use for the storage. Possible values: ");
-     p = description;
-     while (*(++p) != '\0');
-     for (i = 0; surf_storage_model_description[i].name; i++)
-       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
-                    surf_storage_model_description[i].name);
-     sprintf(p,
-             ".\n       (use 'help' as a value to see the long description of each model)");
+     describe_model(description, surf_storage_model_description,
+                    "model", "The model to use for the storage");
      xbt_cfg_register(&_sg_cfg_set, "storage/model", description,
                       xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "storage/model", "default");
  
-     /* ********************************************************************* */
-     /* TUTORIAL: New model                                                   */
-     sprintf(description,
-             "The model to use for the New model. Possible values: ");
-     p = description;
-     while (*(++p) != '\0');
-     for (i = 0; surf_new_model_description[i].name; i++)
-       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
-                    surf_new_model_description[i].name);
-     sprintf(p,
-             ".\n       (use 'help' as a value to see the long description of each model)");
-     xbt_cfg_register(&_sg_cfg_set, "new_model/model", description,
-                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
-     xbt_cfg_setdefault_string(_sg_cfg_set, "new_model/model", "default");
-     /* ********************************************************************* */
-     sprintf(description,
-             "The model to use for the network. Possible values: ");
-     p = description;
-     while (*(++p) != '\0');
-     for (i = 0; surf_network_model_description[i].name; i++)
-       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
-                    surf_network_model_description[i].name);
-     sprintf(p,
-             ".\n       (use 'help' as a value to see the long description of each model)");
+     describe_model(description, surf_network_model_description,
+                    "model", "The model to use for the network");
      xbt_cfg_register(&_sg_cfg_set, "network/model", description,
                       xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__network_model, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "network/model", "LV08");
  
-     sprintf(description,
-             "The optimization modes to use for the network. Possible values: ");
-     p = description;
-     while (*(++p) != '\0');
-     for (i = 0; surf_optimization_mode_description[i].name; i++)
-       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
-                    surf_optimization_mode_description[i].name);
-     sprintf(p,
-             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
+     describe_model(description, surf_optimization_mode_description,
+                    "optimization mode",
+                    "The optimization modes to use for the network");
      xbt_cfg_register(&_sg_cfg_set, "network/optim", description,
                       xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "network/optim", "Lazy");
  
-     sprintf(description,
-             "The model to use for the workstation. Possible values: ");
-     p = description;
-     while (*(++p) != '\0');
-     for (i = 0; surf_workstation_model_description[i].name; i++)
-       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
-                    surf_workstation_model_description[i].name);
-     sprintf(p,
-             ".\n       (use 'help' as a value to see the long description of each model)");
+     describe_model(description, surf_workstation_model_description,
+                    "model", "The model to use for the workstation");
      xbt_cfg_register(&_sg_cfg_set, "workstation/model", description,
                       xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__workstation_model, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "workstation/model", "default");
  
+     describe_model(description, surf_vm_workstation_model_description,
+                    "model", "The model to use for the vm workstation");
+     xbt_cfg_register(&_sg_cfg_set, "vm_workstation/model", description,
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__vm_workstation_model, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "vm_workstation/model", "default");
      xbt_cfg_register(&_sg_cfg_set, "network/TCP_gamma",
                       "Size of the biggest TCP window (cat /proc/sys/net/ipv4/tcp_[rw]mem for recv/send window; Use the last given value, which is the max window size)",
                       xbt_cfgelm_double, 1, 1, _sg_cfg_cb__tcp_gamma, NULL);
      /* 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=on, one checkpoint is saved for each step => faster verification, but huge memory consumption; higher values are good compromises between speed and memory consumption.",
 +                     "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_cfg_setdefault_int(_sg_cfg_set, "model-check/checkpoint", 0);
  
                       xbt_cfgelm_string, 0, 1, _mc_cfg_cb_property, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/property", "");
  
 +    /* do 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_comms_determinism, NULL);
 +    xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/communications_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_boolean, 0, 1, _mc_cfg_cb_timeout, NULL);
      xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", "no");
  
 +    /* 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, 0, 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_cfg_setdefault_boolean(_sg_cfg_set, "verbose-exit", "yes");
  
      /* context factory */
-     sprintf(description,
-             "Context factory to use in SIMIX. Possible values: thread");
      const char *dflt_ctx_fact = "thread";
+     {
+       char *p = description +
+         sprintf(description,
+                 "Context factory to use in SIMIX. Possible values: %s",
+                 dflt_ctx_fact);
  #ifdef CONTEXT_UCONTEXT
-     dflt_ctx_fact = "ucontext";
-     strcat(strcat(description, ", "), dflt_ctx_fact);
+       dflt_ctx_fact = "ucontext";
+       p += sprintf(p, ", %s", dflt_ctx_fact);
  #endif
  #ifdef HAVE_RAWCTX
-     dflt_ctx_fact = "raw";
-     strcat(strcat(description, ", "), dflt_ctx_fact);
+       dflt_ctx_fact = "raw";
+       p += sprintf(p, ", %s", dflt_ctx_fact);
  #endif
-     strcat(description, ".");
+       sprintf(p, ".");
+     }
      xbt_cfg_register(&_sg_cfg_set, "contexts/factory", description,
                       xbt_cfgelm_string, 1, 1, _sg_cfg_cb_context_factory, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/factory", dflt_ctx_fact);
    } else {
      XBT_WARN("Call to sg_config_init() after initialization ignored");
    }
-   xbt_free(description);
  }
  
  void sg_config_finalize(void)
  void surf_config_models_setup()
  {
    const char *workstation_model_name;
+   const char *vm_workstation_model_name;
    int workstation_id = -1;
+   int vm_workstation_id = -1;
    char *network_model_name = NULL;
    char *cpu_model_name = NULL;
    int storage_id = -1;
  
    workstation_model_name =
        xbt_cfg_get_string(_sg_cfg_set, "workstation/model");
+   vm_workstation_model_name =
+       xbt_cfg_get_string(_sg_cfg_set, "vm_workstation/model");
    network_model_name = xbt_cfg_get_string(_sg_cfg_set, "network/model");
    cpu_model_name = xbt_cfg_get_string(_sg_cfg_set, "cpu/model");
    storage_model_name = xbt_cfg_get_string(_sg_cfg_set, "storage/model");
    XBT_DEBUG("Call workstation_model_init");
    surf_workstation_model_description[workstation_id].model_init_preparse();
  
+   XBT_DEBUG("Call vm_workstation_model_init");
+   vm_workstation_id = find_model_description(surf_vm_workstation_model_description,
+                                           vm_workstation_model_name);
+   surf_vm_workstation_model_description[vm_workstation_id].model_init_preparse();
    XBT_DEBUG("Call storage_model_init");
    storage_id = find_model_description(surf_storage_model_description, storage_model_name);
    surf_storage_model_description[storage_id].model_init_preparse();
  
-   /* ********************************************************************* */
-   /* TUTORIAL: New model                                                   */
-   int new_model_id = -1;
-   char *new_model_name = NULL;
-   new_model_name = xbt_cfg_get_string(_sg_cfg_set, "new_model/model");
-   XBT_DEBUG("Call new model_init");
-   new_model_id = find_model_description(surf_new_model_description, new_model_name);
-   surf_new_model_description[new_model_id].model_init_preparse();
-   /* ********************************************************************* */
+ }
+ int sg_cfg_is_default_value(const char *name)
+ {
+   return xbt_cfg_is_default_value(_sg_cfg_set, name);
  }
  
  int sg_cfg_get_int(const char* name)
  {
-   return xbt_cfg_get_int(_sg_cfg_set,name);
+   return xbt_cfg_get_int(_sg_cfg_set, name);
  }
  
  double sg_cfg_get_double(const char* name)
  {
-   return xbt_cfg_get_double(_sg_cfg_set,name);
+   return xbt_cfg_get_double(_sg_cfg_set, name);
  }
  
  char* sg_cfg_get_string(const char* name)
  {
-   return xbt_cfg_get_string(_sg_cfg_set,name);
+   return xbt_cfg_get_string(_sg_cfg_set, name);
  }
  
  int sg_cfg_get_boolean(const char* name)
  {
-   return xbt_cfg_get_boolean(_sg_cfg_set,name);
+   return xbt_cfg_get_boolean(_sg_cfg_set, name);
  }
  
  void sg_cfg_get_peer(const char *name, char **peer, int *port)
  {
-   xbt_cfg_get_peer(_sg_cfg_set,name, peer, port);
+   xbt_cfg_get_peer(_sg_cfg_set, name, peer, port);
  }
  
  xbt_dynar_t sg_cfg_get_dynar(const char* name)
  {
-   return xbt_cfg_get_dynar(_sg_cfg_set,name);
+   return xbt_cfg_get_dynar(_sg_cfg_set, name);
  }
diff --combined src/simix/smx_network.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2009-2013. The SimGrid Team.
+ /* Copyright (c) 2009-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -31,6 -31,8 +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)
@@@ -288,9 -290,6 +288,6 @@@ smx_action_t SIMIX_comm_new(e_smx_comm_
    return act;
  }
  
- void SIMIX_pre_comm_destroy(smx_simcall_t simcall, smx_action_t action){
-   SIMIX_comm_destroy(action);
- }
  /**
   *  \brief Destroy a communicate action
   *  \param action The communicate action to be destroyed
@@@ -339,17 -338,17 +336,17 @@@ void SIMIX_comm_destroy_internal_action
  #ifdef HAVE_LATENCY_BOUND_TRACKING
      action->latency_limited = SIMIX_comm_is_latency_bounded(action);
  #endif
-     action->comm.surf_comm->model_type->action_unref(action->comm.surf_comm);
+     surf_action_unref(action->comm.surf_comm);
      action->comm.surf_comm = NULL;
    }
  
    if (action->comm.src_timeout){
-     action->comm.src_timeout->model_type->action_unref(action->comm.src_timeout);
+     surf_action_unref(action->comm.src_timeout);
      action->comm.src_timeout = NULL;
    }
  
    if (action->comm.dst_timeout){
-     action->comm.dst_timeout->model_type->action_unref(action->comm.dst_timeout);
+     surf_action_unref(action->comm.dst_timeout);
      action->comm.dst_timeout = NULL;
    }
  }
@@@ -451,20 -450,11 +448,11 @@@ smx_action_t SIMIX_comm_isend(smx_proce
  }
  
  void SIMIX_pre_comm_recv(smx_simcall_t simcall, smx_rdv_t rdv,
-                                   void *dst_buff, size_t *dst_buff_size,
-                                   int (*match_fun)(void *, void *, smx_action_t),
-                                 void *data, double timeout){
+                          void *dst_buff, size_t *dst_buff_size,
+                          int (*match_fun)(void *, void *, smx_action_t),
+                          void *data, double timeout, double rate)
+ {
    smx_action_t comm = SIMIX_comm_irecv(simcall->issuer, rdv, dst_buff,
-                                      dst_buff_size, match_fun, data);
-   simcall->mc_value = 0;
-   SIMIX_pre_comm_wait(simcall, comm, timeout);
- }
- void SIMIX_pre_comm_recv_bounded(smx_simcall_t simcall, smx_rdv_t rdv,
-                                   void *dst_buff, size_t *dst_buff_size,
-                                   int (*match_fun)(void *, void *, smx_action_t),
-                                 void *data, double timeout, double rate){
-   smx_action_t comm = SIMIX_comm_irecv_bounded(simcall->issuer, rdv, dst_buff,
                                       dst_buff_size, match_fun, data, rate);
    simcall->mc_value = 0;
    SIMIX_pre_comm_wait(simcall, comm, timeout);
  smx_action_t SIMIX_pre_comm_irecv(smx_simcall_t simcall, smx_rdv_t rdv,
                                    void *dst_buff, size_t *dst_buff_size,
                                    int (*match_fun)(void *, void *, smx_action_t),
-                                 void *data){
-   return SIMIX_comm_irecv(simcall->issuer, rdv, dst_buff, dst_buff_size,
-                         match_fun, data);
- }
- smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
-                               void *dst_buff, size_t *dst_buff_size,
-                               int (*match_fun)(void *, void *, smx_action_t), void *data)
+                                 void *data, double rate)
  {
-   XBT_DEBUG("recv from %p %p\n", rdv, rdv->comm_fifo);
-   smx_action_t this_action = SIMIX_comm_new(SIMIX_COMM_RECEIVE);
-   smx_action_t other_action;
-   //communication already done, get it inside the fifo of completed comms
-   //permanent receive v1
-   //int already_received=0;
-   if(rdv->permanent_receiver && xbt_fifo_size(rdv->done_comm_fifo)!=0){
-     XBT_DEBUG("We have a comm that has probably already been received, trying to match it, to skip the communication\n");
-     //find a match in the already received fifo
-     other_action = SIMIX_fifo_get_comm(rdv->done_comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
-     //if not found, assume the receiver came first, register it to the mailbox in the classical way
-     if (!other_action)  {
-       XBT_DEBUG("We have messages in the permanent receive list, but not the one we are looking for, pushing request into fifo\n");
-       other_action = this_action;
-       SIMIX_rdv_push(rdv, this_action);
-     }else{
-       if(other_action->comm.surf_comm &&      SIMIX_comm_get_remains(other_action)==0.0)
-       {
-         XBT_DEBUG("comm %p has been already sent, and is finished, destroy it\n",&(other_action->comm));
-         other_action->state = SIMIX_DONE;
-         other_action->comm.type = SIMIX_COMM_DONE;
-         other_action->comm.rdv = NULL;
-         //SIMIX_comm_destroy(this_action);
-         //--smx_total_comms; // this creation was a pure waste
-         //already_received=1;
-         //other_action->comm.refcount--;
-       }/*else{
-          XBT_DEBUG("Not yet finished, we have to wait %d\n", xbt_fifo_size(rdv->comm_fifo));
-          }*/
-       other_action->comm.refcount--;
-       SIMIX_comm_destroy(this_action);
-       --smx_total_comms; // this creation was a pure waste
-     }
-   }else{
-     /* Prepare an action describing us, so that it gets passed to the user-provided filter of other side */
-     /* Look for communication action matching our needs. We also provide a description of
-      * ourself so that the other side also gets a chance of choosing if it wants to match with us.
-      *
-      * If it is not found then push our communication into the rendez-vous point */
-     other_action = SIMIX_fifo_get_comm(rdv->comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
-     if (!other_action) {
-       XBT_DEBUG("Receive pushed first %d\n", xbt_fifo_size(rdv->comm_fifo));
-       other_action = this_action;
-       SIMIX_rdv_push(rdv, this_action);
-     } else {
-       SIMIX_comm_destroy(this_action);
-       --smx_total_comms; // this creation was a pure waste
-       other_action->state = SIMIX_READY;
-       other_action->comm.type = SIMIX_COMM_READY;
-       //other_action->comm.refcount--;
-     }
-     xbt_fifo_push(dst_proc->comms, other_action);
-   }
-   /* Setup communication action */
-   other_action->comm.dst_proc = dst_proc;
-   other_action->comm.dst_buff = dst_buff;
-   other_action->comm.dst_buff_size = dst_buff_size;
-   other_action->comm.dst_data = data;
-   other_action->comm.match_fun = match_fun;
-   /*if(already_received)//do the actual copy, because the first one after the comm didn't have all the info
-     SIMIX_comm_copy_data(other_action);*/
-   if (MC_is_active()) {
-     other_action->state = SIMIX_RUNNING;
-     return other_action;
-   }
-   SIMIX_comm_start(other_action);
-   // }
-   return other_action;
- }
- smx_action_t SIMIX_pre_comm_irecv_bounded(smx_simcall_t simcall, smx_rdv_t rdv,
-                                   void *dst_buff, size_t *dst_buff_size,
-                                   int (*match_fun)(void *, void *, smx_action_t),
-                                 void *data, double rate){
-   return SIMIX_comm_irecv_bounded(simcall->issuer, rdv, dst_buff, dst_buff_size,
+   return SIMIX_comm_irecv(simcall->issuer, rdv, dst_buff, dst_buff_size,
                          match_fun, data, rate);
  }
  
- smx_action_t SIMIX_comm_irecv_bounded(smx_process_t dst_proc, smx_rdv_t rdv,
+ smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
                                void *dst_buff, size_t *dst_buff_size,
-                               int (*match_fun)(void *, void *, smx_action_t), void *data, double rate)
+                               int (*match_fun)(void *, void *, smx_action_t),
+                               void *data, double rate)
  {
    XBT_DEBUG("recv from %p %p\n", rdv, rdv->comm_fifo);
    smx_action_t this_action = SIMIX_comm_new(SIMIX_COMM_RECEIVE);
    other_action->comm.dst_buff_size = dst_buff_size;
    other_action->comm.dst_data = data;
  
-   if (rate < other_action->comm.rate || other_action->comm.rate == -1.0)
-         other_action->comm.rate = rate;
+   if (rate != -1.0 &&
+       (other_action->comm.rate == -1.0 || rate < other_action->comm.rate))
+     other_action->comm.rate = rate;
  
    other_action->comm.match_fun = match_fun;
  
@@@ -728,8 -628,8 +626,8 @@@ void SIMIX_pre_comm_wait(smx_simcall_t 
    if (action->state != SIMIX_WAITING && action->state != SIMIX_RUNNING) {
      SIMIX_comm_finish(action);
    } else { /* if (timeout >= 0) { we need a surf sleep action even when there is no timeout, otherwise surf won't tell us when the host fails */
-     sleep = surf_workstation_model->extension.workstation.sleep(simcall->issuer->smx_host, timeout);
-     surf_workstation_model->action_data_set(sleep, action);
+     sleep = surf_workstation_sleep(simcall->issuer->smx_host, timeout);
+     surf_action_set_data(sleep, action);
  
      if (simcall->issuer == action->comm.src_proc)
        action->comm.src_timeout = sleep;
@@@ -845,15 -745,16 +743,16 @@@ static XBT_INLINE void SIMIX_comm_start
      XBT_DEBUG("Starting communication %p from '%s' to '%s'", action,
                SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
  
-     action->comm.surf_comm = surf_workstation_model->extension.workstation.
-       communicate(sender, receiver, action->comm.task_size, action->comm.rate);
+     action->comm.surf_comm = surf_workstation_model_communicate(surf_workstation_model,
+                                                                   sender, receiver,
+                                                                   action->comm.task_size, action->comm.rate);
  
-     surf_workstation_model->action_data_set(action->comm.surf_comm, action);
+     surf_action_set_data(action->comm.surf_comm, action);
  
      action->state = SIMIX_RUNNING;
  
      /* If a link is failed, detect it immediately */
-     if (surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
+     if (surf_action_get_state(action->comm.surf_comm) == SURF_ACTION_FAILED) {
        XBT_DEBUG("Communication from '%s' to '%s' failed to start because of a link failure",
                  SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
        action->state = SIMIX_LINK_FAILURE;
          XBT_DEBUG("The communication is suspended on startup because dst (%s:%s) were suspended since it initiated the communication",
                    SIMIX_host_get_name(action->comm.dst_proc->smx_host), action->comm.dst_proc->name);
  
-       surf_workstation_model->suspend(action->comm.surf_comm);
+       surf_action_suspend(action->comm.surf_comm);
  
      }
    }
@@@ -888,6 -789,7 +787,7 @@@ void SIMIX_comm_finish(smx_action_t act
    unsigned int destroy_count = 0;
    smx_simcall_t simcall;
  
    while ((simcall = xbt_fifo_shift(action->simcalls))) {
  
      /* If a waitany simcall is waiting for this action to finish, then remove
        }
      }
  
-     if (surf_workstation_model->extension.
-         workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+     if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
        simcall->issuer->context->iwannadie = 1;
      }
  
      simcall->issuer->waiting_action = NULL;
      xbt_fifo_remove(simcall->issuer->comms, action);
      if(action->comm.detached){
+       smx_process_t proc;
+       int still_alive = 0;
        if(simcall->issuer == action->comm.src_proc){
-         if(action->comm.dst_proc)
-           xbt_fifo_remove(action->comm.dst_proc->comms, action);
+         if(action->comm.dst_proc){
+             xbt_swag_foreach(proc, simix_global->process_list)
+             {
+                if(proc==action->comm.dst_proc){
+                    still_alive=1;
+                    break;
+                }
+             }
+         }
+         if(still_alive) xbt_fifo_remove(action->comm.dst_proc->comms, action);
        }
        if(simcall->issuer == action->comm.dst_proc){
          if(action->comm.src_proc)
-           xbt_fifo_remove(action->comm.src_proc->comms, action);
+           if(action->comm.dst_proc){
+             xbt_swag_foreach(proc, simix_global->process_list)
+             {
+               if(proc==action->comm.src_proc){
+                   still_alive=1;
+                   break;
+               }
+             }
+           }
+           if(still_alive) xbt_fifo_remove(action->comm.src_proc->comms, action);
        }
      }
      SIMIX_simcall_answer(simcall);
@@@ -1012,19 -933,19 +931,19 @@@ void SIMIX_post_comm(smx_action_t actio
  {
    /* Update action state */
    if (action->comm.src_timeout &&
-       surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_DONE)
+       surf_action_get_state(action->comm.src_timeout) == SURF_ACTION_DONE)
      action->state = SIMIX_SRC_TIMEOUT;
    else if (action->comm.dst_timeout &&
-            surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_DONE)
+         surf_action_get_state(action->comm.dst_timeout) == SURF_ACTION_DONE)
      action->state = SIMIX_DST_TIMEOUT;
    else if (action->comm.src_timeout &&
-            surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_FAILED)
+         surf_action_get_state(action->comm.src_timeout) == SURF_ACTION_FAILED)
      action->state = SIMIX_SRC_HOST_FAILURE;
    else if (action->comm.dst_timeout &&
-            surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_FAILED)
+       surf_action_get_state(action->comm.dst_timeout) == SURF_ACTION_FAILED)
      action->state = SIMIX_DST_HOST_FAILURE;
    else if (action->comm.surf_comm &&
-            surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
+         surf_action_get_state(action->comm.surf_comm) == SURF_ACTION_FAILED) {
      XBT_DEBUG("Puta madre. Surf says that the link broke");
      action->state = SIMIX_LINK_FAILURE;
    } else
@@@ -1065,7 -986,7 +984,7 @@@ void SIMIX_comm_cancel(smx_action_t act
    else if (!MC_is_active() /* when running the MC there are no surf actions */
             && (action->state == SIMIX_READY || action->state == SIMIX_RUNNING)) {
  
-     surf_workstation_model->action_cancel(action->comm.surf_comm);
+     surf_action_cancel(action->comm.surf_comm);
    }
  }
  
@@@ -1073,7 -994,7 +992,7 @@@ void SIMIX_comm_suspend(smx_action_t ac
  {
    /*FIXME: shall we suspend also the timeout actions? */
    if (action->comm.surf_comm)
-     surf_workstation_model->suspend(action->comm.surf_comm);
+     surf_action_suspend(action->comm.surf_comm);
    /* in the other case, the action will be suspended on creation, in SIMIX_comm_start() */
  }
  
@@@ -1081,7 -1002,7 +1000,7 @@@ void SIMIX_comm_resume(smx_action_t act
  {
    /*FIXME: check what happen with the timeouts */
    if (action->comm.surf_comm)
-     surf_workstation_model->resume(action->comm.surf_comm);
+     surf_action_resume(action->comm.surf_comm);
    /* in the other case, the action were not really suspended yet, see SIMIX_comm_suspend() and SIMIX_comm_start() */
  }
  
@@@ -1106,7 -1027,7 +1025,7 @@@ double SIMIX_comm_get_remains(smx_actio
    switch (action->state) {
  
    case SIMIX_RUNNING:
-     remains = surf_workstation_model->get_remains(action->comm.surf_comm);
+     remains = surf_action_get_remains(action->comm.surf_comm);
      break;
  
    case SIMIX_WAITING:
@@@ -1181,14 -1102,14 +1100,14 @@@ int SIMIX_pre_comm_is_latency_bounded(s
   *  \brief verify if communication is latency bounded
   *  \param comm The communication
   */
XBT_INLINE int SIMIX_comm_is_latency_bounded(smx_action_t action)
+ int SIMIX_comm_is_latency_bounded(smx_action_t action)
  {
    if(!action){
      return 0;
    }
    if (action->comm.surf_comm){
      XBT_DEBUG("Getting latency limited for surf_action (%p)", action->comm.surf_comm);
-     action->latency_limited = surf_workstation_model->get_latency_limited(action->comm.surf_comm);
+     action->latency_limited = surf_network_action_get_latency_limited(action->comm.surf_comm);
      XBT_DEBUG("Action limited is %d", action->latency_limited);
    }
    return action->latency_limited;
@@@ -1,7 -1,7 +1,7 @@@
  /* backtrace_linux - backtrace displaying on linux platform                 */
  /* This file is included by ex.c on need (have execinfo.h, popen & addrline)*/
  
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -13,7 -13,6 +13,7 @@@
  #include "xbt/module.h"         /* xbt_binary_name */
  #include "xbt_modinter.h"       /* backtrace initialization headers */
  #ifdef HAVE_MC
 +#define UNW_LOCAL_ONLY
  #include <libunwind.h>
  #endif
  /* end of "useless" inclusions */
@@@ -1,6 -1,6 +1,6 @@@
  /* mm_diff - Memory snapshooting and comparison                             */
  
- /* Copyright (c) 2008-2013. The SimGrid Team.
+ /* Copyright (c) 2008-2014. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -11,7 -11,6 +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");
@@@ -133,16 -132,12 +133,16 @@@ 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, heapsize1, heapsize2;
 +  xbt_dynar_t to_ignore1, to_ignore2;
 +  heap_area_t **equals_to1, **equals_to2;
 +  type_name **types1, **types2;
 +};
 +
 +__thread struct s_mm_diff* mm_diff_info = NULL;
  
  /*********************************** Free functions ************************************/
  
@@@ -247,7 -242,7 +247,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){
 +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){
 +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 - getpagesize();
 +  state->s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
  
 -  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;
 +      xbt_free(state->types1[i][j]);
 +      state->types1[i][j] = NULL;
 +      xbt_free(state->types2[i][j]);
 +      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(xbt_mheap_t heap1, xbt_mheap_t heap2, mc_object_info_t info, mc_object_info_t other_info){
 +
 +  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, NULL, info, other_info, 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, NULL, info, other_info, 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, NULL, info, other_info, 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, NULL, info, other_info, 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){
 +static int compare_heap_area_without_type(struct s_mm_diff *state, void *real_area1, void *real_area2, void *area1, void *area2, xbt_dynar_t previous, mc_object_info_t info, mc_object_info_t other_info, 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, previous, info, other_info, 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, 
 +// area_size is either a byte_size or an elements_count?&
 +static int compare_heap_area_with_type(struct s_mm_diff *state, void *real_area1, void *real_area2, void *area1, void *area2,
 +                                       xbt_dynar_t previous, mc_object_info_t info, mc_object_info_t other_info, char *type_id,
                                         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 type = xbt_dict_get_or_null(info->types, type_id);
    dw_type_t subtype, subsubtype;
    int res, elm_size, i, switch_types = 0;
    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_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, previous, info, other_info, type->dw_type_id, 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 = xbt_dict_get_or_null(info->types, type->dw_type_id);
      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));
 +    case DW_TAG_base_type:
 +    case DW_TAG_enumeration_type:
 +    case DW_TAG_pointer_type:
 +    case DW_TAG_structure_type:
 +    case DW_TAG_union_type:
 +      if(subtype->byte_size == 0){ /*declaration of the type, need the complete description */
 +          subtype = xbt_dict_get_or_null(other_info->types_by_name, subtype->name);
            switch_types = 1;
 -        }
        }
 -      elm_size = subtype->size;
 +      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));
 +    // 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->byte_size == 0){ /*declaration of the type, need the complete description */
 +          subsubtype = xbt_dict_get_or_null(other_info->types_by_name, subtype->name);
            switch_types = 1;
 -        }
        }
 -      elm_size = subsubtype->size;
 +      elm_size = subsubtype->byte_size;
        break;
      default : 
        return 0;
        break;
      }
 -    for(i=0; i<type->size; i++){ 
 +    for(i=0; i<type->element_count; i++){
 +      // TODO, add support for variable stride (DW_AT_byte_stride)
        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);
 +        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), previous, other_info, info, type->dw_type_id, subtype->byte_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);
 +        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), previous, info, other_info, type->dw_type_id, 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_pointer_type:
 +    if(type->dw_type_id && ((dw_type_t)xbt_dict_get_or_null(info->types, type->dw_type_id))->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, previous, info, other_info, type->dw_type_id, 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, previous, info, other_info, type->dw_type_id, 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);
 +  case DW_TAG_structure_type:
 +    if(type->byte_size == 0){ /*declaration of the structure, need the complete description */
 +      dw_type_t full_type = xbt_dict_get_or_null(info->types_by_name, type->name);
 +      if(full_type){
 +        type = full_type;
        }else{
 -        type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
 +        type = xbt_dict_get_or_null(other_info->types_by_name, 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(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++){
            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); 
 +            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), previous, other_info, info, 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); 
 +            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), previous, info, other_info, type_id, -1, check_ignore, 0);
            if(res == 1)
              return res;
          }
        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);
 +          res = compare_heap_area_with_type(state, (char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, other_info, info, 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);  
 +          res = compare_heap_area_with_type(state, (char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, info, other_info, member->dw_type_id, -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, previous, info, other_info, 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);
 +static char* get_offset_type(char* type_id, int offset, mc_object_info_t info, mc_object_info_t other_info, int area_size, int *switch_type){
 +  dw_type_t type = xbt_dict_get_or_null(info->types, type_id);
    if(type == NULL){
 -    type = xbt_dict_get_or_null(other_types, type_id);
 +    type = xbt_dict_get_or_null(other_info->types, type_id);
      *switch_type = 1;
    }
 -  char* type_desc;
    switch(type->type){
 -  case e_dw_structure_type :
 -    if(type->size == 0){ /*declaration of the structure, need the complete description */
 +  case DW_TAG_structure_type :
 +    if(type->byte_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);
 +        dw_type_t full_type = xbt_dict_get_or_null(info->types_by_name, type->name);
 +        if(full_type){
 +          type = full_type;
          }else{
 -          type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
 +          type = xbt_dict_get_or_null(other_info->types_by_name, 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);
 +        dw_type_t full_type = xbt_dict_get_or_null(other_info->types_by_name, type->name);
 +        if(full_type){
 +          type = full_type;
          }else{
 -          type = xbt_dict_get_or_null(all_types, get_type_description(other_types, type->name));
 +          type = xbt_dict_get_or_null(info->types_by_name, type->name);
            *switch_type = 0;
          }
        }
      
      }
 -    if(area_size != -1 && type->size != area_size){
 -      if(area_size>type->size && area_size%type->size == 0)
 +    if(area_size != -1 && type->byte_size != area_size){
 +      if(area_size>type->byte_size && area_size%type->byte_size == 0)
          return type_id;
        else
          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){
 +int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, mc_object_info_t info, mc_object_info_t other_info, char *type_id, 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;
      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;
 +  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(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(((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));
 +  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));
 +  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);
 +    type = xbt_dict_get_or_null(info->types, type_id);
 +    if(type->byte_size == 0){
 +      if(type->subtype == NULL){
 +        dw_type_t full_type = xbt_dict_get_or_null(info->types_by_name, type->name);
 +        if(full_type)
 +          type = full_type;
          else
 -          type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
 +          type = xbt_dict_get_or_null(other_info->types_by_name, type->name);
        }else{
 -        type = xbt_dict_get_or_null(all_types, type->dw_type_id);
 +        type = type->subtype;
        }
      }
 -    if((type->type == e_dw_pointer_type) || ((type->type == e_dw_base_type) && (!strcmp(type->name, "char"))))
 +    if((type->byte_size == 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)){
 +    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);
 +      xbt_free(state->types1[block1][0]);
 +      xbt_free(state->types2[block2][0]);
 +      state->types1[block1][0] = strdup(type_id);
 +      state->types2[block2][0] = strdup(type_id);
      }
  
      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;
 +    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));
 +    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));
 +    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));
  
      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)){
 +    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]){
 +    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 = 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);
 +      xbt_free(state->types1[block1][frag1]);
 +      xbt_free(state->types2[block2][frag2]);
 +      state->types1[block1][frag1] = strdup(type_id);
 +      state->types2[block2][frag2] = strdup(type_id);
      }
  
      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_type_id1 = get_offset_type(state->types1[block1][frag1], offset1, info, other_info, size, &switch_type);
 +        new_type_id2 = get_offset_type(state->types2[block2][frag2], offset1, info, other_info, size, &switch_type);
 +      }else if(state->types1[block1][frag1] != NULL){
 +        new_type_id1 = get_offset_type(state->types1[block1][frag1], offset1, info, other_info, size, &switch_type);
 +        new_type_id2 = get_offset_type(state->types1[block1][frag1], offset2, info, other_info, size, &switch_type);
 +      }else if(state->types2[block2][frag2] != NULL){
 +        new_type_id1 = get_offset_type(state->types2[block2][frag2], offset1, info, other_info, size, &switch_type);
 +        new_type_id2 = get_offset_type(state->types2[block2][frag2], offset2, info, other_info, size, &switch_type);
        }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;
 +          type = xbt_dict_get_or_null(other_info->types, new_type_id1);
 +          while(type->byte_size == 0 && type->dw_type_id != NULL)
 +            type = xbt_dict_get_or_null(other_info->types, type->dw_type_id);
 +          new_size1 = type->byte_size;
 +          type = xbt_dict_get_or_null(other_info->types, new_type_id2);
 +          while(type->byte_size == 0 && type->dw_type_id != NULL)
 +            type = xbt_dict_get_or_null(other_info->types, type->dw_type_id);
 +          new_size2 = type->byte_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;
 +          type = xbt_dict_get_or_null(info->types, new_type_id1);
 +          while(type->byte_size == 0 && type->dw_type_id != NULL)
 +            type = xbt_dict_get_or_null(info->types, type->dw_type_id);
 +          new_size1 = type->byte_size;
 +          type = xbt_dict_get_or_null(info->types, new_type_id2);
 +          while(type->byte_size == 0 && type->dw_type_id != NULL)
 +            type = xbt_dict_get_or_null(info->types, type->dw_type_id);
 +          new_size2 = type->byte_size;
          }
        }else{
          if(match_pairs){
 -          match_equals(previous);
 +          match_equals(state, previous);
            xbt_dynar_free(&previous);
          }
          return -1;
      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);
 +      res_compare = compare_heap_area_with_type(state, area1, area2, area1_to_compare, area2_to_compare, previous, other_info, info, 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);
 +      res_compare = compare_heap_area_with_type(state, area1, area2, area1_to_compare, area2_to_compare, previous, info, other_info, type_id, size, check_ignore, pointer_level);
      if(res_compare == 1){
        if(match_pairs)
          xbt_dynar_free(&previous);
      }
    }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);
 +      res_compare = compare_heap_area_without_type(state, area1, area2, area1_to_compare, area2_to_compare, previous, other_info, info, 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);
 +      res_compare = compare_heap_area_without_type(state, area1, area2, area1_to_compare, area2_to_compare, previous, info, other_info, size, check_ignore);
      if(res_compare == 1){
        if(match_pairs)
          xbt_dynar_free(&previous);
    }
  
    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 - getpagesize();
 +  state->s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
  
 -  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 ++;
              }