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
# 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
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()
### 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)
TEST_BIG_ENDIAN(BIGENDIAN)
include(FindGraphviz)
+ include(FindLibSigc++)
set(HAVE_GTNETS 0)
if(enable_gtnets)
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)
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)
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()
###############
## 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)
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)
${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}")
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
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
src/xbt_modinter.h
)
- if(HAVE_MMAP)
+ if(HAVE_MMALLOC)
set(XBT_SRC
${XBT_SRC}
src/xbt/mmalloc/mm.c
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
)
src/simix/smx_smurf.c
src/simix/smx_synchro.c
src/simix/smx_user.c
+ src/simix/smx_vm.c
)
set(SIMGRID_SRC
)
#* ****************************************************************************************** *#
- #* ****************************************************************************************** *#
- #* 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
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
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
src/smpi/smpiff.in
src/smpi/smpif90.in
src/smpi/smpirun.in
+ src/smpi/smpitools.sh
)
set(txt_files
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
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
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
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
###############################
# 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})
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})
endif()
endif()
+ if(HAVE_LIBSIGC++)
+ SET(SIMGRID_DEP "${SIMGRID_DEP} -lsigc-2.0")
+ endif()
+
if(HAVE_GTNETS)
SET(SIMGRID_DEP "${SIMGRID_DEP} -lgtnets")
endif()
# (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)
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()
# 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()
- /* 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
/* 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
#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
/* 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'. */
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);
- /* 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
#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 **********************************/
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 */
- /* 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
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;
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);
- /* 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 **************************************/
/*****************************************************************************************/
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);
}
}
static void local_variable_free(local_variable_t v){
xbt_free(v->frame);
xbt_free(v->name);
- xbt_free(v->type);
xbt_free(v);
}
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);
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));
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)
- /* 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"
/************************** 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;
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:
}
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);
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;
}
- /* 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
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);
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);
}
/* 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);
}
- /* 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
#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"
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;
_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.");
_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;
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;
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));
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;
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);
}
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){
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);
}
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;
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;
/******************************* 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));
}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();
void MC_exit(void)
{
xbt_free(mc_time);
+
MC_memory_exit();
//xbt_abort();
}
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++;
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;
}
- /* 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
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);
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);
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;
- /* 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
#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);
}
- /* 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
#ifndef WIN32
#include <sys/mman.h>
#endif
+#include <elfutils/libdw.h>
+
#include "mc/mc.h"
#include "mc/datatypes.h"
#include "xbt/fifo.h"
#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)*/
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{
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{
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 **********************************/
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;
//#define MC_DEBUG 1
#define MC_VERBOSE 1
-
/********************************** DPOR for safety property **************************************/
typedef enum {
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;
/********************************** 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,
}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 **********************************/
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
- /* 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
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;
}
}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;
- /* 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
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;
- /* 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
"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)
{
}
#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);
}
- /* 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
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)
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
#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;
}
}
}
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;
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;
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);
}
}
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);
{
/* 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
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);
}
}
{
/*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() */
}
{
/*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() */
}
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:
* \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;
/* 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
#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 */
/* 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
#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");
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 ************************************/
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 ++;
}