X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/63c371bbca5afccc4708761d83af6fc2443ca553..7d5154294d0c97a3690134cc5d3a9900189055cf:/src/mc/remote/Client.cpp?ds=sidebyside diff --git a/src/mc/remote/Client.cpp b/src/mc/remote/Client.cpp index 2b25c63917..4e774042b2 100644 --- a/src/mc/remote/Client.cpp +++ b/src/mc/remote/Client.cpp @@ -1,56 +1,45 @@ -/* Copyright (c) 2015. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2015-2019. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "src/mc/remote/Client.hpp" +#include "src/internal_config.h" +#include + #include #include - +#include #include #include #include -#include -#include -#include -#include - -#include - -#include "src/internal_config.h" - -#include "src/mc/mc_request.h" -#include "src/mc/remote/Client.hpp" -#include "src/mc/remote/mc_protocol.h" - // We won't need those once the separation MCer/MCed is complete: -#include "src/mc/mc_ignore.h" -#include "src/mc/mc_smx.h" +#include "src/mc/mc_smx.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_client, mc, "MC client logic"); namespace simgrid { namespace mc { -std::unique_ptr Client::client_; +std::unique_ptr Client::instance_; Client* Client::initialize() { // We are not in MC mode: // TODO, handle this more gracefully. - if (!getenv(MC_ENV_SOCKET_FD)) + if (not std::getenv(MC_ENV_SOCKET_FD)) return nullptr; // Do not break if we are called multiple times: - if (client_) - return client_.get(); + if (instance_) + return instance_.get(); _sg_do_model_check = 1; // Fetch socket from MC_ENV_SOCKET_FD: char* fd_env = std::getenv(MC_ENV_SOCKET_FD); - if (!fd_env) + if (not fd_env) xbt_die("No MC socket passed in the environment"); int fd = xbt_str_parse_int(fd_env, bprintf("Variable %s should contain a number but contains '%%s'", MC_ENV_SOCKET_FD)); @@ -61,11 +50,11 @@ Client* Client::initialize() socklen_t socklen = sizeof(type); if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &socklen) != 0) xbt_die("Could not check socket type"); - if (type != SOCK_DGRAM) + if (type != SOCK_SEQPACKET) xbt_die("Unexpected socket type %i", type); XBT_DEBUG("Model-checked application found expected socket type"); - client_ = std::unique_ptr(new simgrid::mc::Client(fd)); + instance_.reset(new simgrid::mc::Client(fd)); // Wait for the model-checker: errno = 0; @@ -77,102 +66,115 @@ Client* Client::initialize() #error "no ptrace equivalent coded for this platform" #endif if (errno != 0 || raise(SIGSTOP) != 0) - xbt_die("Could not wait for the model-checker"); + xbt_die("Could not wait for the model-checker (errno = %d: %s)", errno, strerror(errno)); + + instance_->handle_messages(); + return instance_.get(); +} - client_->handleMessages(); - return client_.get(); +void Client::handle_deadlock_check(s_mc_message_t*) +{ + bool deadlock = false; + if (not simix_global->process_list.empty()) { + deadlock = true; + for (auto const& kv : simix_global->process_list) + if (simgrid::mc::actor_is_enabled(kv.second)) { + deadlock = false; + break; + } + } + + // Send result: + s_mc_message_int_t answer{MC_MESSAGE_DEADLOCK_CHECK_REPLY, deadlock}; + xbt_assert(channel_.send(answer) == 0, "Could not send response"); +} +void Client::handle_continue(s_mc_message_t*) +{ + /* Nothing to do */ +} +void Client::handle_simcall(s_mc_message_simcall_handle_t* message) +{ + smx_actor_t process = SIMIX_process_from_PID(message->pid); + if (not process) + xbt_die("Invalid pid %lu", (unsigned long)message->pid); + SIMIX_simcall_handle(&process->simcall, message->value); + if (channel_.send(MC_MESSAGE_WAITING)) + xbt_die("Could not send MESSAGE_WAITING to model-checker"); } -void Client::handleMessages() +void Client::handle_actor_enabled(s_mc_message_actor_enabled_t* msg) +{ + bool res = simgrid::mc::actor_is_enabled(SIMIX_process_from_PID(msg->aid)); + s_mc_message_int_t answer{MC_MESSAGE_ACTOR_ENABLED_REPLY, res}; + channel_.send(answer); +} + +void Client::handle_messages() { while (1) { XBT_DEBUG("Waiting messages from model-checker"); char message_buffer[MC_MESSAGE_LENGTH]; - ssize_t s; + ssize_t received_size = channel_.receive(&message_buffer, sizeof(message_buffer)); - if ((s = channel_.receive(&message_buffer, sizeof(message_buffer))) < 0) + if (received_size < 0) xbt_die("Could not receive commands from the model-checker"); - s_mc_message_t message; - if ((size_t)s < sizeof(message)) - xbt_die("Received message is too small"); - memcpy(&message, message_buffer, sizeof(message)); - switch (message.type) { - - case MC_MESSAGE_DEADLOCK_CHECK: { - // Check deadlock: - bool deadlock = false; - smx_actor_t actor; - if (xbt_swag_size(simix_global->process_list)) { - deadlock = true; - xbt_swag_foreach(actor, simix_global->process_list) if (simgrid::mc::actor_is_enabled(actor)) - { - deadlock = false; - break; - } - } - - // Send result: - s_mc_int_message_t answer; - answer.type = MC_MESSAGE_DEADLOCK_CHECK_REPLY; - answer.value = deadlock; - if (channel_.send(answer)) - xbt_die("Could not send response"); - } break; + s_mc_message_t* message = (s_mc_message_t*)message_buffer; + switch (message->type) { + + case MC_MESSAGE_DEADLOCK_CHECK: + xbt_assert(received_size == sizeof(s_mc_message_t), "Unexpected size for DEADLOCK_CHECK (%zd != %zu)", + received_size, sizeof(s_mc_message_t)); + handle_deadlock_check(message); + break; case MC_MESSAGE_CONTINUE: + xbt_assert(received_size == sizeof(s_mc_message_t), "Unexpected size for MESSAGE_CONTINUE (%zd != %zu)", + received_size, sizeof(s_mc_message_t)); + handle_continue(message); return; - case MC_MESSAGE_SIMCALL_HANDLE: { - s_mc_simcall_handle_message_t message; - if (s != sizeof(message)) - xbt_die("Unexpected size for SIMCALL_HANDLE"); - memcpy(&message, message_buffer, sizeof(message)); - smx_actor_t process = SIMIX_process_from_PID(message.pid); - if (!process) - xbt_die("Invalid pid %lu", (unsigned long)message.pid); - SIMIX_simcall_handle(&process->simcall, message.value); - if (channel_.send(MC_MESSAGE_WAITING)) - xbt_die("Could not send MESSAGE_WAITING to model-checker"); - } break; - - case MC_MESSAGE_RESTORE: { - s_mc_restore_message_t message; - if (s != sizeof(message)) - xbt_die("Unexpected size for SIMCALL_HANDLE"); - memcpy(&message, message_buffer, sizeof(message)); -#if HAVE_SMPI - smpi_really_switch_data_segment(message.index); -#endif - } break; + case MC_MESSAGE_SIMCALL_HANDLE: + xbt_assert(received_size == sizeof(s_mc_message_simcall_handle_t), + "Unexpected size for SIMCALL_HANDLE (%zd != %zu)", received_size, + sizeof(s_mc_message_simcall_handle_t)); + handle_simcall((s_mc_message_simcall_handle_t*)message_buffer); + break; + + case MC_MESSAGE_ACTOR_ENABLED: + xbt_assert(received_size == sizeof(s_mc_message_actor_enabled_t), + "Unexpected size for ACTOR_ENABLED (%zd != %zu)", received_size, + sizeof(s_mc_message_actor_enabled_t)); + handle_actor_enabled((s_mc_message_actor_enabled_t*)message_buffer); + break; default: - xbt_die("Received unexpected message %s (%i)", MC_message_type_name(message.type), message.type); + xbt_die("Received unexpected message %s (%i)", MC_message_type_name(message->type), message->type); + break; } } } -void Client::mainLoop(void) +void Client::main_loop() { while (1) { simgrid::mc::wait_for_requests(); - if (channel_.send(MC_MESSAGE_WAITING)) - xbt_die("Could not send WAITING mesage to model-checker"); - this->handleMessages(); + xbt_assert(channel_.send(MC_MESSAGE_WAITING) == 0, "Could not send WAITING message to model-checker"); + this->handle_messages(); } } -void Client::reportAssertionFailure(const char* description) +void Client::report_assertion_failure() { if (channel_.send(MC_MESSAGE_ASSERTION_FAILED)) xbt_die("Could not send assertion to model-checker"); - this->handleMessages(); + this->handle_messages(); } -void Client::ignoreMemory(void* addr, std::size_t size) +void Client::ignore_memory(void* addr, std::size_t size) { - s_mc_ignore_memory_message_t message; + s_mc_message_ignore_memory_t message; message.type = MC_MESSAGE_IGNORE_MEMORY; message.addr = (std::uintptr_t)addr; message.size = size; @@ -180,11 +182,11 @@ void Client::ignoreMemory(void* addr, std::size_t size) xbt_die("Could not send IGNORE_MEMORY mesage to model-checker"); } -void Client::ignoreHeap(void* address, std::size_t size) +void Client::ignore_heap(void* address, std::size_t size) { xbt_mheap_t heap = mmalloc_get_current_heap(); - s_mc_ignore_heap_message_t message; + s_mc_message_ignore_heap_t message; message.type = MC_MESSAGE_IGNORE_HEAP; message.address = address; message.size = size; @@ -201,19 +203,19 @@ void Client::ignoreHeap(void* address, std::size_t size) xbt_die("Could not send ignored region to MCer"); } -void Client::unignoreHeap(void* address, std::size_t size) +void Client::unignore_heap(void* address, std::size_t size) { - s_mc_ignore_memory_message_t message; + s_mc_message_ignore_memory_t message; message.type = MC_MESSAGE_UNIGNORE_HEAP; message.addr = (std::uintptr_t)address; message.size = size; if (channel_.send(message)) - xbt_die("Could not send IGNORE_HEAP mesasge to model-checker"); + xbt_die("Could not send IGNORE_HEAP message to model-checker"); } -void Client::declareSymbol(const char* name, int* value) +void Client::declare_symbol(const char* name, int* value) { - s_mc_register_symbol_message_t message; + s_mc_message_register_symbol_t message; message.type = MC_MESSAGE_REGISTER_SYMBOL; if (strlen(name) + 1 > sizeof(message.name)) xbt_die("Symbol is too long"); @@ -224,7 +226,7 @@ void Client::declareSymbol(const char* name, int* value) xbt_die("Could send REGISTER_SYMBOL message to model-checker"); } -void Client::declareStack(void* stack, size_t size, smx_actor_t process, ucontext_t* context) +void Client::declare_stack(void* stack, size_t size, ucontext_t* context) { xbt_mheap_t heap = mmalloc_get_current_heap(); @@ -234,18 +236,12 @@ void Client::declareStack(void* stack, size_t size, smx_actor_t process, ucontex region.context = context; region.size = size; region.block = ((char*)stack - (char*)heap->heapbase) / BLOCKSIZE + 1; -#if HAVE_SMPI - if (smpi_privatize_global_variables && process) - region.process_index = smpi_process_index_of_smx_process(process); - else -#endif - region.process_index = -1; - s_mc_stack_region_message_t message; + s_mc_message_stack_region_t message; message.type = MC_MESSAGE_STACK_REGION; message.stack_region = region; if (channel_.send(message)) - xbt_die("Coule not send STACK_REGION to model-checker"); + xbt_die("Could not send STACK_REGION to model-checker"); } } }