#include <mutex>
#include <string>
#include <string_view>
-#include <sys/ptrace.h>
-#include <sys/wait.h>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information");
// ***** RemoteProcessMemory
-RemoteProcessMemory::RemoteProcessMemory(pid_t pid) : AddressSpace(this), pid_(pid), running_(true) {}
-
-void RemoteProcessMemory::init(xbt_mheap_t mmalloc_default_mdp)
+RemoteProcessMemory::RemoteProcessMemory(pid_t pid, xbt_mheap_t mmalloc_default_mdp) : AddressSpace(this), pid_(pid)
{
this->heap_address = remote(mmalloc_default_mdp);
unw_destroy_addr_space(as);
}
-bool RemoteProcessMemory::handle_message(const char* buffer, ssize_t size)
-{
- s_mc_message_t base_message;
- xbt_assert(size >= (ssize_t)sizeof(base_message), "Broken 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));
-
- this->init(message.mmalloc_default_mdp);
- break;
- }
-
- case MessageType::IGNORE_HEAP: {
- s_mc_message_ignore_heap_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
-
- IgnoredHeapRegion region;
- region.block = message.block;
- region.fragment = message.fragment;
- region.address = message.address;
- region.size = message.size;
- this->ignore_heap(region);
- break;
- }
-
- case MessageType::UNIGNORE_HEAP: {
- s_mc_message_ignore_memory_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
- this->unignore_heap((void*)(std::uintptr_t)message.addr, message.size);
- break;
- }
-
- case MessageType::IGNORE_MEMORY: {
- s_mc_message_ignore_memory_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
- this->ignore_region(message.addr, message.size);
- break;
- }
-
- case MessageType::STACK_REGION: {
- s_mc_message_stack_region_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
- this->stack_areas().push_back(message.stack_region);
- } break;
-
- case MessageType::REGISTER_SYMBOL: {
- s_mc_message_register_symbol_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
- xbt_assert(not message.callback, "Support for client-side function proposition is not implemented.");
- XBT_DEBUG("Received symbol: %s", message.name.data());
-
- LivenessChecker::automaton_register_symbol(*this, message.name.data(), remote((int*)message.data));
- break;
- }
-
- case MessageType::WAITING:
- return false;
-
- case MessageType::ASSERTION_FAILED:
- Exploration::get_instance()->report_assertion_failure();
- break;
-
- default:
- xbt_die("Unexpected message from model-checked application");
- }
- return true;
-}
-
-void RemoteProcessMemory::handle_waitpid()
-{
- XBT_DEBUG("Check for wait event");
- int status;
- pid_t pid;
- while ((pid = waitpid(-1, &status, WNOHANG)) != 0) {
- if (pid == -1) {
- if (errno == ECHILD) { // No more children:
- xbt_assert(not running(), "Inconsistent state");
- break;
- } else {
- XBT_ERROR("Could not wait for pid");
- throw simgrid::xbt::errno_error();
- }
- }
-
- if (pid == this->pid()) {
- // From PTRACE_O_TRACEEXIT:
-#ifdef __linux__
- if (status >> 8 == (SIGTRAP | (PTRACE_EVENT_EXIT << 8))) {
- unsigned long eventmsg;
- xbt_assert(ptrace(PTRACE_GETEVENTMSG, pid, 0, &eventmsg) != -1, "Could not get exit status");
- status = static_cast<int>(eventmsg);
- if (WIFSIGNALED(status))
- Exploration::get_instance()->report_crash(status);
- }
-#endif
-
- // We don't care about non-lethal signals, just reinject them:
- if (WIFSTOPPED(status)) {
- XBT_DEBUG("Stopped with signal %i", (int)WSTOPSIG(status));
- errno = 0;
-#ifdef __linux__
- ptrace(PTRACE_CONT, pid, 0, WSTOPSIG(status));
-#elif defined BSD
- ptrace(PT_CONTINUE, pid, (caddr_t)1, WSTOPSIG(status));
-#endif
- xbt_assert(errno == 0, "Could not PTRACE_CONT");
- }
-
- else if (WIFSIGNALED(status)) {
- Exploration::get_instance()->report_crash(status);
- } else if (WIFEXITED(status)) {
- XBT_DEBUG("Child process is over");
- terminate();
- }
- }
- }
-}
-
} // namespace simgrid::mc