if (res < 0 || not WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP)
xbt_die("Could not wait model-checked process");
- remote_process_->init();
-
if (not _sg_mc_dot_output_file.get().empty())
MC_init_dot_output();
{
XBT_DEBUG("Shutting down model-checker");
- RemoteProcess* process = &this->get_remote_process();
- if (process->running()) {
+ RemoteProcess& process = get_remote_process();
+ if (process.running()) {
XBT_DEBUG("Killing process");
- kill(process->pid(), SIGKILL);
- process->terminate();
+ finalize_app(true);
+ kill(process.pid(), SIGKILL);
+ process.terminate();
}
}
-void ModelChecker::resume(RemoteProcess& process)
+void ModelChecker::resume()
{
int res = checker_side_.get_channel().send(MessageType::CONTINUE);
if (res)
throw xbt::errno_error();
- process.clear_cache();
+ remote_process_->clear_cache();
}
static void MC_report_crash(int status)
for (auto const& s : mc_model_checker->getChecker()->get_textual_trace())
XBT_INFO(" %s", s.c_str());
dumpRecordPath();
- session->log_state();
+ session_singleton->log_state();
if (xbt_log_no_loc) {
XBT_INFO("Stack trace not displayed because you passed --log=no_loc");
} else {
}
}
-static void MC_report_assertion_error()
-{
- XBT_INFO("**************************");
- XBT_INFO("*** PROPERTY NOT VALID ***");
- XBT_INFO("**************************");
- XBT_INFO("Counter-example execution trace:");
- for (auto const& s : mc_model_checker->getChecker()->get_textual_trace())
- XBT_INFO(" %s", s.c_str());
- dumpRecordPath();
- session->log_state();
-}
-
bool ModelChecker::handle_message(const char* buffer, ssize_t size)
{
s_mc_message_t base_message;
memcpy(&base_message, buffer, sizeof(base_message));
switch(base_message.type) {
+ case MessageType::INITIAL_ADDRESSES: {
+ s_mc_message_initial_addresses_t message;
+ xbt_assert(size == sizeof(message), "Broken message. Got %d bytes instead of %d.", (int)size, (int)sizeof(message));
+ memcpy(&message, buffer, sizeof(message));
+
+ get_remote_process().init(message.mmalloc_default_mdp, message.maxpid, message.actors, message.dead_actors);
+ break;
+ }
+
case MessageType::IGNORE_HEAP: {
s_mc_message_ignore_heap_t message;
xbt_assert(size == sizeof(message), "Broken message");
return false;
case MessageType::ASSERTION_FAILED:
- MC_report_assertion_error();
+ XBT_INFO("**************************");
+ XBT_INFO("*** PROPERTY NOT VALID ***");
+ XBT_INFO("**************************");
+ XBT_INFO("Counter-example execution trace:");
+ for (auto const& s : getChecker()->get_textual_trace())
+ XBT_INFO(" %s", s.c_str());
+ dumpRecordPath();
+ session_singleton->log_state();
+
this->exit(SIMGRID_MC_EXIT_SAFETY);
default:
/** Terminate the model-checker application */
void ModelChecker::exit(int status)
{
- // TODO, terminate the model checker politely instead of exiting rudely
- if (get_remote_process().running())
- kill(get_remote_process().pid(), SIGKILL);
+ shutdown();
::exit(status);
}
// From PTRACE_O_TRACEEXIT:
#ifdef __linux__
if (status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))) {
- xbt_assert(ptrace(PTRACE_GETEVENTMSG, remote_process_->pid(), 0, &status) != -1, "Could not get exit status");
+ long ptrace_res = ptrace(PTRACE_GETEVENTMSG, remote_process_->pid(), 0, &status);
+ xbt_assert(ptrace_res != -1, "Could not get exit status");
if (WIFSIGNALED(status)) {
MC_report_crash(status);
- exit(SIMGRID_MC_EXIT_PROGRAM_CRASH);
+ this->get_remote_process().terminate();
+ this->exit(SIMGRID_MC_EXIT_PROGRAM_CRASH);
}
}
#endif
else if (WIFSIGNALED(status)) {
MC_report_crash(status);
- mc_model_checker->exit(SIMGRID_MC_EXIT_PROGRAM_CRASH);
+ this->get_remote_process().terminate();
+ this->exit(SIMGRID_MC_EXIT_PROGRAM_CRASH);
} else if (WIFEXITED(status)) {
XBT_DEBUG("Child process is over");
this->get_remote_process().terminate();
void ModelChecker::wait_for_requests()
{
- this->resume(get_remote_process());
+ this->resume();
if (this->get_remote_process().running())
checker_side_.dispatch();
}
s_mc_message_simcall_handle_t m;
memset(&m, 0, sizeof(m));
m.type = MessageType::SIMCALL_HANDLE;
- m.pid_ = transition.pid_;
+ m.aid_ = transition.aid_;
m.times_considered_ = transition.times_considered_;
checker_side_.get_channel().send(m);
this->remote_process_->clear_cache();
return answer;
}
+void ModelChecker::finalize_app(bool terminate_asap)
+{
+ s_mc_message_int_t m{MessageType::FINALIZE, terminate_asap};
+ int res = checker_side_.get_channel().send(m);
+ xbt_assert(res == 0, "Could not ask the app to finalize on need");
+
+ s_mc_message_t answer;
+ ssize_t s = checker_side_.get_channel().receive(answer);
+ xbt_assert(s != -1, "Could not receive answer to FINALIZE");
+}
+
bool ModelChecker::checkDeadlock()
{
int res = checker_side_.get_channel().send(MessageType::DEADLOCK_CHECK);