From: Martin Quinson Date: Thu, 1 Dec 2016 21:10:47 +0000 (+0100) Subject: Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid X-Git-Tag: v3_14~132 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/ea5ba71aa6e9e92becf2763c71c92fed3228c794?hp=d314c935dc20cc774a3c3be17a9863c492d6663c Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid --- diff --git a/CMakeLists.txt b/CMakeLists.txt index dba5f6ccd5..4857bd4a0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -335,7 +335,7 @@ else() set(HAVE_THREAD_LOCAL_STORAGE 0) endif() -if(enable_model-checking AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux") +if(enable_model-checking AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux|FreeBSD") message(WARNING "Support for model-checking has not been enabled on ${CMAKE_SYSTEM}: disabling it") set(enable_model-checking FALSE) endif() @@ -371,7 +371,7 @@ if(HAVE_LIBUNWIND) # So let's comply and link against the System framework SET(SIMGRID_DEP "${SIMGRID_DEP} -lSystem") endif() - if("${CMAKE_SYSTEM}" MATCHES "Linux") + if("${CMAKE_SYSTEM}" MATCHES "Linux|FreeBSD") set(SIMGRID_DEP "${SIMGRID_DEP} -lunwind-ptrace") # 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) @@ -388,10 +388,15 @@ else() endif() if(enable_model-checking) - SET(HAVE_MC 1) - - include(FindLibdw) - SET(SIMGRID_DEP "${SIMGRID_DEP} -ldw") + find_package(Libdw REQUIRED) + find_package(Libevent REQUIRED) + include_directories(${LIBDW_INCLUDE_DIRS} ${LIBEVENT_INCLUDE_DIRS}) + set(SIMGRID_DEP "${SIMGRID_DEP} ${LIBEVENT_LIBRARIES} ${LIBDW_LIBRARIES}") + set(HAVE_MC 1) + if("${CMAKE_SYSTEM}" MATCHES "FreeBSD" AND enable_java) + message(WARNING "FreeBSD + Model-Checking + Java = too much for now. Disabling java") + set(enable_java FALSE) + endif() else() SET(HAVE_MC 0) set(HAVE_MMALLOC 0) diff --git a/src/kernel/routing/AsFull.cpp b/src/kernel/routing/AsFull.cpp index 95f8f72b40..2daa182ca2 100644 --- a/src/kernel/routing/AsFull.cpp +++ b/src/kernel/routing/AsFull.cpp @@ -81,9 +81,6 @@ void AsFull::addRoute(sg_platf_route_cbarg_t route) { NetCard* src = route->src; NetCard* dst = route->dst; - const char* srcName = src->name().c_str(); - const char* dstName = dst->name().c_str(); - addRouteCheckParams(route); size_t table_size = vertices_.size(); @@ -94,11 +91,11 @@ void AsFull::addRoute(sg_platf_route_cbarg_t route) /* Check that the route does not already exist */ if (route->gw_dst) // AS route (to adapt the error message, if any) xbt_assert(nullptr == TO_ROUTE_FULL(src->id(), dst->id()), - "The route between %s@%s and %s@%s already exists (Rq: routes are symmetrical by default).", srcName, - route->gw_src->name().c_str(), dstName, route->gw_dst->name().c_str()); + "The route between %s@%s and %s@%s already exists (Rq: routes are symmetrical by default).", src->name().c_str(), + route->gw_src->name().c_str(), dst->name().c_str(), route->gw_dst->name().c_str()); else xbt_assert(nullptr == TO_ROUTE_FULL(src->id(), dst->id()), - "The route between %s and %s already exists (Rq: routes are symmetrical by default).", srcName, dstName); + "The route between %s and %s already exists (Rq: routes are symmetrical by default).", src->name().c_str(), dst->name().c_str()); /* Add the route to the base */ TO_ROUTE_FULL(src->id(), dst->id()) = newExtendedRoute(hierarchy_, route, 1); @@ -114,11 +111,11 @@ void AsFull::addRoute(sg_platf_route_cbarg_t route) xbt_assert( nullptr == TO_ROUTE_FULL(dst->id(), src->id()), "The route between %s@%s and %s@%s already exists. You should not declare the reverse path as symmetrical.", - dstName, route->gw_dst->name().c_str(), srcName, route->gw_src->name().c_str()); + dst->name().c_str(), route->gw_dst->name().c_str(), src->name().c_str(), route->gw_src->name().c_str()); else xbt_assert(nullptr == TO_ROUTE_FULL(dst->id(), src->id()), "The route between %s and %s already exists. You should not declare the reverse path as symmetrical.", - dstName, srcName); + dst->name().c_str(), src->name().c_str()); TO_ROUTE_FULL(dst->id(), src->id()) = newExtendedRoute(hierarchy_, route, 0); TO_ROUTE_FULL(dst->id(), src->id())->link_list->shrink_to_fit(); diff --git a/src/mc/ModelChecker.cpp b/src/mc/ModelChecker.cpp index 160074896a..af0c6668cb 100644 --- a/src/mc/ModelChecker.cpp +++ b/src/mc/ModelChecker.cpp @@ -6,11 +6,9 @@ #include -#include #include #include #include -#include #include #include @@ -46,14 +44,13 @@ using simgrid::mc::remote; # define WAITPID_CHECKED_FLAGS 0 #endif -// Hardcoded index for now: -#define SOCKET_FD_INDEX 0 -#define SIGNAL_FD_INDEX 1 - namespace simgrid { namespace mc { ModelChecker::ModelChecker(std::unique_ptr process) : + base_(nullptr), + socket_event_(nullptr), + signal_event_(nullptr), page_store_(500), process_(std::move(process)), parent_snapshot_(nullptr) @@ -61,37 +58,34 @@ ModelChecker::ModelChecker(std::unique_ptr process) : } -ModelChecker::~ModelChecker() {} +ModelChecker::~ModelChecker() { + if (socket_event_ != nullptr) + event_free(socket_event_); + if (signal_event_ != nullptr) + event_free(signal_event_); + if (base_ != nullptr) + event_base_free(base_); +} void ModelChecker::start() { const pid_t pid = process_->pid(); - // Block SIGCHLD (this will be handled with accept/signalfd): - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - if (sigprocmask(SIG_BLOCK, &set, nullptr) == -1) - throw simgrid::xbt::errno_error(); - - sigset_t full_set; - sigfillset(&full_set); - - // Prepare data for poll: - - struct pollfd* socket_pollfd = &fds_[SOCKET_FD_INDEX]; - socket_pollfd->fd = process_->getChannel().getSocket(); - socket_pollfd->events = POLLIN; - socket_pollfd->revents = 0; - - int signal_fd = signalfd(-1, &set, 0); - if (signal_fd == -1) - throw simgrid::xbt::errno_error(); - - struct pollfd* signalfd_pollfd = &fds_[SIGNAL_FD_INDEX]; - signalfd_pollfd->fd = signal_fd; - signalfd_pollfd->events = POLLIN; - signalfd_pollfd->revents = 0; + base_ = event_base_new(); + event_callback_fn event_callback = [](evutil_socket_t fd, short events, void *arg) + { + ((ModelChecker *)arg)->handle_events(fd, events); + }; + socket_event_ = event_new(base_, + process_->getChannel().getSocket(), + EV_READ|EV_PERSIST, + event_callback, this); + event_add(socket_event_, NULL); + signal_event_ = event_new(base_, + SIGCHLD, + EV_SIGNAL|EV_PERSIST, + event_callback, this); + event_add(signal_event_, NULL); XBT_DEBUG("Waiting for the model-checked process"); int status; @@ -315,72 +309,29 @@ void ModelChecker::exit(int status) ::exit(status); } -bool ModelChecker::handle_events() +void ModelChecker::handle_events(int fd, short events) { - char buffer[MC_MESSAGE_LENGTH]; - struct pollfd* socket_pollfd = &fds_[SOCKET_FD_INDEX]; - struct pollfd* signalfd_pollfd = &fds_[SIGNAL_FD_INDEX]; - - while(poll(fds_, 2, -1) == -1) { - switch(errno) { - case EINTR: - continue; - default: + if (events == EV_READ) { + char buffer[MC_MESSAGE_LENGTH]; + ssize_t size = process_->getChannel().receive(buffer, sizeof(buffer), false); + if (size == -1 && errno != EAGAIN) throw simgrid::xbt::errno_error(); + if (!handle_message(buffer, size)) { + event_base_loopbreak(base_); } } - - if (socket_pollfd->revents) { - if (socket_pollfd->revents & POLLIN) { - ssize_t size = process_->getChannel().receive(buffer, sizeof(buffer), false); - if (size == -1 && errno != EAGAIN) - throw simgrid::xbt::errno_error(); - return handle_message(buffer, size); - } - if (socket_pollfd->revents & POLLERR) - throw_socket_error(socket_pollfd->fd); - if (socket_pollfd->revents & POLLHUP) - xbt_die("Socket hang up?"); + else if (events == EV_SIGNAL) { + on_signal(fd); } - - if (signalfd_pollfd->revents) { - if (signalfd_pollfd->revents & POLLIN) { - this->handle_signals(); - return true; - } - if (signalfd_pollfd->revents & POLLERR) - throw_socket_error(signalfd_pollfd->fd); - if (signalfd_pollfd->revents & POLLHUP) - xbt_die("Signalfd hang up?"); + else { + xbt_die("Unexpected event"); } - - return true; } void ModelChecker::loop() { - while (this->process().running()) - this->handle_events(); -} - -void ModelChecker::handle_signals() -{ - struct signalfd_siginfo info; - struct pollfd* signalfd_pollfd = &fds_[SIGNAL_FD_INDEX]; - while (1) { - ssize_t size = read(signalfd_pollfd->fd, &info, sizeof(info)); - if (size == -1) { - if (errno == EINTR) - continue; - else - throw simgrid::xbt::errno_error(); - } else if (size != sizeof(info)) - return throw std::runtime_error( - "Bad communication with model-checked application"); - else - break; - } - this->on_signal(&info); + if (this->process().running()) + event_base_dispatch(base_); } void ModelChecker::handle_waitpid() @@ -423,7 +374,7 @@ void ModelChecker::handle_waitpid() #ifdef __linux__ ptrace(PTRACE_CONT, this->process().pid(), 0, WSTOPSIG(status)); #elif defined BSD - ptrace(PT_CONTINUE, this->process().pid(), nullptr, WSTOPSIG(status)); + ptrace(PT_CONTINUE, this->process().pid(), (caddr_t)1, WSTOPSIG(status)); #endif if (errno != 0) xbt_die("Could not PTRACE_CONT"); @@ -437,9 +388,9 @@ void ModelChecker::handle_waitpid() } } -void ModelChecker::on_signal(const struct signalfd_siginfo* info) +void ModelChecker::on_signal(int signo) { - switch(info->ssi_signo) { + switch(signo) { case SIGCHLD: this->handle_waitpid(); break; @@ -451,9 +402,8 @@ void ModelChecker::on_signal(const struct signalfd_siginfo* info) void ModelChecker::wait_client(simgrid::mc::Process& process) { this->resume(process); - while (this->process().running()) - if (!this->handle_events()) - return; + if (this->process().running()) + event_base_dispatch(base_); } void ModelChecker::handle_simcall(Transition const& transition) @@ -465,9 +415,8 @@ void ModelChecker::handle_simcall(Transition const& transition) m.value = transition.argument; this->process_->getChannel().send(m); this->process_->clear_cache(); - while (this->process_->running()) - if (!this->handle_events()) - return; + if (this->process_->running()) + event_base_dispatch(base_); } bool ModelChecker::checkDeadlock() diff --git a/src/mc/ModelChecker.hpp b/src/mc/ModelChecker.hpp index 0e7ed9d9f3..a1138ce0ea 100644 --- a/src/mc/ModelChecker.hpp +++ b/src/mc/ModelChecker.hpp @@ -9,12 +9,12 @@ #include -#include - #include #include #include +#include + #include #include #include @@ -31,7 +31,8 @@ namespace mc { /** State of the model-checker (global variables for the model checker) */ class ModelChecker { - struct pollfd fds_[2]; + struct event_base *base_; + struct event *socket_event_, *signal_event_; /** String pool for host names */ // TODO, use std::set with heterogeneous comparison lookup (C++14)? std::set hostnames_; @@ -70,7 +71,7 @@ public: void shutdown(); void resume(simgrid::mc::Process& process); void loop(); - bool handle_events(); + void handle_events(int fd, short events); void wait_client(simgrid::mc::Process& process); void handle_simcall(Transition const& transition); void wait_for_requests() @@ -87,9 +88,8 @@ public: private: void setup_ignore(); bool handle_message(char* buffer, ssize_t size); - void handle_signals(); void handle_waitpid(); - void on_signal(const struct signalfd_siginfo* info); + void on_signal(int signo); public: unsigned long visited_states = 0; diff --git a/src/mc/Process.cpp b/src/mc/Process.cpp index 61dc6afa2f..ee5df35082 100644 --- a/src/mc/Process.cpp +++ b/src/mc/Process.cpp @@ -57,8 +57,18 @@ namespace mc { // List of library which memory segments are not considered: static const char *const filtered_libraries[] = { +#ifdef __linux__ "ld", +#elif defined __FreeBSD__ + "ld-elf", + "ld-elf32", + "libkvm", /* kernel data access library */ + "libprocstat", /* process and file information retrieval */ + "libthr", /* thread library */ + "libutil", +#endif "libasan", /* gcc sanitizers */ + "libargp", /* workarounds for glibc-less systems */ "libtsan", "libubsan", "libbz2", @@ -70,9 +80,11 @@ static const char *const filtered_libraries[] = { "libc++", "libcdt", "libcgraph", + "libcxxrt", "libdl", "libdw", "libelf", + "libevent", "libgcc_s", "liblua5.1", "liblua5.3", diff --git a/src/mc/mc_dwarf.cpp b/src/mc/mc_dwarf.cpp index 93489b414f..c177458fa2 100644 --- a/src/mc/mc_dwarf.cpp +++ b/src/mc/mc_dwarf.cpp @@ -874,7 +874,7 @@ static void MC_dwarf_handle_scope_die(simgrid::mc::ObjectInformation* info, Dwar if (klass == simgrid::dwarf::TagClass::Subprogram) { const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name); - if (ns) + if (name && ns) frame.name = std::string(ns) + "::" + name; else if (name) frame.name = name; diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 1deef26e76..14884e6202 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -1010,6 +1010,7 @@ set(CMAKE_SOURCE_FILES tools/cmake/Modules/FindGraphviz.cmake tools/cmake/Modules/FindLibdw.cmake tools/cmake/Modules/FindLibunwind.cmake + tools/cmake/Modules/FindLibevent.cmake tools/cmake/Modules/FindLuaSimgrid.cmake tools/cmake/Modules/FindNS3.cmake tools/cmake/Modules/FindPAPI.cmake diff --git a/tools/cmake/Modules/FindLibdw.cmake b/tools/cmake/Modules/FindLibdw.cmake index 77ffc4711b..9574bda8c0 100644 --- a/tools/cmake/Modules/FindLibdw.cmake +++ b/tools/cmake/Modules/FindLibdw.cmake @@ -1,53 +1,34 @@ -find_library(PATH_LIBDW_LIB - NAMES dw +find_path(LIBDW_INCLUDE_DIR "elfutils/libdw.h" HINTS $ENV{SIMGRID_LIBDW_LIBRARY_PATH} $ENV{LD_LIBRARY_PATH} $ENV{LIBDW_LIBRARY_PATH} - PATH_SUFFIXES lib/ GnuWin32/lib + PATH_SUFFIXES include/ GnuWin32/include PATHS /opt /opt/local /opt/csw /sw /usr) - -find_path(PATH_LIBDW_H "elfutils/libdw.h" +find_library(LIBDW_LIBRARY + NAMES dw HINTS $ENV{SIMGRID_LIBDW_LIBRARY_PATH} $ENV{LD_LIBRARY_PATH} $ENV{LIBDW_LIBRARY_PATH} - PATH_SUFFIXES include/ GnuWin32/include + PATH_SUFFIXES lib/ GnuWin32/lib PATHS /opt /opt/local /opt/csw /sw /usr) +set(LIBDW_LIBRARIES "${LIBDW_LIBRARY}") -message(STATUS "Looking for libdw.h") -if(PATH_LIBDW_H) - message(STATUS "Looking for libdw.h - found") -else() - message(STATUS "Looking for libdw.h - not found") -endif() - -message(STATUS "Looking for libdw") -if(PATH_LIBDW_LIB) - message(STATUS "Looking for libdw - found") -else() - message(STATUS "Looking for libdw - not found") -endif() - -if(PATH_LIBDW_LIB AND PATH_LIBDW_H) - string(REGEX REPLACE "/libdw.*[.]${LIB_EXE}$" "" PATH_LIBDW_LIB "${PATH_LIBDW_LIB}") - string(REGEX REPLACE "/libdw.h" "" PATH_LIBDW_H "${PATH_LIBDW_H}") - - include_directories(${PATH_LIBDW_H}) - link_directories(${PATH_LIBDW_LIB}) -else() - message(FATAL_ERROR "Please either install the libdw-dev package (or equivalent) or turn off the model-checking option of SimGrid.") -endif() - -mark_as_advanced(PATH_LIBDW_H) -mark_as_advanced(PATH_LIBDW_LIB) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + Libdw + DEFAULT_MSG + LIBDW_LIBRARIES + LIBDW_INCLUDE_DIR) +mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARIES) diff --git a/tools/cmake/Modules/FindLibevent.cmake b/tools/cmake/Modules/FindLibevent.cmake new file mode 100644 index 0000000000..c55399591c --- /dev/null +++ b/tools/cmake/Modules/FindLibevent.cmake @@ -0,0 +1,12 @@ +find_path(LIBEVENT_INCLUDE_DIR event2/event.h) +find_library(LIBEVENT_LIBRARY NAMES event) +find_library(LIBEVENT_THREADS_LIBRARY NAMES event_pthreads) +set(LIBEVENT_LIBRARIES "${LIBEVENT_LIBRARY}") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + Libevent + DEFAULT_MSG + LIBEVENT_LIBRARIES + LIBEVENT_INCLUDE_DIR) +mark_as_advanced(LIBEVENT_INCLUDE_DIR LIBEVENT_LIBRARIES)