Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid
authorMartin Quinson <martin.quinson@loria.fr>
Thu, 1 Dec 2016 21:10:47 +0000 (22:10 +0100)
committerMartin Quinson <martin.quinson@loria.fr>
Thu, 1 Dec 2016 21:10:47 +0000 (22:10 +0100)
CMakeLists.txt
src/kernel/routing/AsFull.cpp
src/mc/ModelChecker.cpp
src/mc/ModelChecker.hpp
src/mc/Process.cpp
src/mc/mc_dwarf.cpp
tools/cmake/DefinePackages.cmake
tools/cmake/Modules/FindLibdw.cmake
tools/cmake/Modules/FindLibevent.cmake [new file with mode: 0644]

index dba5f6c..4857bd4 100644 (file)
@@ -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)
index 95f8f72..2daa182 100644 (file)
@@ -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();
index 1600748..af0c666 100644 (file)
@@ -6,11 +6,9 @@
 
 #include <cassert>
 
-#include <poll.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/socket.h>
-#include <sys/signalfd.h>
 #include <sys/ptrace.h>
 
 #include <memory>
@@ -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> 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> 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()
index 0e7ed9d..a1138ce 100644 (file)
@@ -9,12 +9,12 @@
 
 #include <sys/types.h>
 
-#include <poll.h>
-
 #include <memory>
 #include <set>
 #include <string>
 
+#include <event2/event.h>
+
 #include <simgrid_config.h>
 #include <xbt/base.h>
 #include <sys/types.h>
@@ -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<std::string> 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;
index 61dc6af..ee5df35 100644 (file)
@@ -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",
index 93489b4..c177458 100644 (file)
@@ -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;
index 1deef26..14884e6 100644 (file)
@@ -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
index 77ffc47..9574bda 100644 (file)
@@ -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 (file)
index 0000000..c553995
--- /dev/null
@@ -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)