-#ifdef __linux__
-# define WAITPID_CHECKED_FLAGS __WALL
-#else
-# define WAITPID_CHECKED_FLAGS 0
-#endif
-
-namespace simgrid {
-namespace mc {
-
-ModelChecker::ModelChecker(std::unique_ptr<RemoteClient> process) : process_(std::move(process)) {}
-
-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()
-{
- 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_->get_channel().get_socket(), 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;
-
- // The model-checked process SIGSTOP itself to signal it's ready:
- const pid_t pid = process_->pid();
-
- pid_t res = waitpid(pid, &status, WAITPID_CHECKED_FLAGS);
- if (res < 0 || not WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP)
- xbt_die("Could not wait model-checked process");
-
- process_->init();
-
- if (not _sg_mc_dot_output_file.get().empty())
- MC_init_dot_output();
-
- setup_ignore();
-
-#ifdef __linux__
- ptrace(PTRACE_SETOPTIONS, pid, nullptr, PTRACE_O_TRACEEXIT);
- ptrace(PTRACE_CONT, pid, 0, 0);
-#elif defined BSD
- ptrace(PT_CONTINUE, pid, (caddr_t)1, 0);
-#else
-# error "no ptrace equivalent coded for this platform"
-#endif
-}
-
-static const std::pair<const char*, const char*> ignored_local_variables[] = {
- std::pair<const char*, const char*>{ "e", "*" },
- std::pair<const char*, const char*>{ "_log_ev", "*" },
-
- /* Ignore local variable about time used for tracing */
- std::pair<const char*, const char*>{ "start_time", "*" },
-};
-
-void ModelChecker::setup_ignore()
-{
- RemoteClient& process = this->process();
- for (std::pair<const char*, const char*> const& var :
- ignored_local_variables)
- process.ignore_local_variable(var.first, var.second);
-
- /* Static variable used for tracing */
- process.ignore_global_variable("counter");
-}
-
-void ModelChecker::shutdown()
-{
- XBT_DEBUG("Shuting down model-checker");
-
- RemoteClient* process = &this->process();
- if (process->running()) {
- XBT_DEBUG("Killing process");
- kill(process->pid(), SIGKILL);
- process->terminate();
- }
-}
-
-void ModelChecker::resume(RemoteClient& process)
-{
- int res = process.get_channel().send(MC_MESSAGE_CONTINUE);
- if (res)
- throw xbt::errno_error();
- process.clear_cache();
-}
-
-static void MC_report_crash(int status)