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()
# 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)
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)
{
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();
/* 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);
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();
#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>
# 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)
}
-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;
::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()
#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");
}
}
-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;
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)
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()
#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>
/** 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_;
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()
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;
// 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",
"libc++",
"libcdt",
"libcgraph",
+ "libcxxrt",
"libdl",
"libdw",
"libelf",
+ "libevent",
"libgcc_s",
"liblua5.1",
"liblua5.3",
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;
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
-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)
--- /dev/null
+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)