X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/9cca09ad88fcaeb49f2637de97df519c3920aaa4..9698e575e77c1df3dcf1614a8404ee0e2ea55778:/src/mc/remote/RemoteClient.cpp diff --git a/src/mc/remote/RemoteClient.cpp b/src/mc/remote/RemoteClient.cpp index 37abc50b98..940d9f9b7e 100644 --- a/src/mc/remote/RemoteClient.cpp +++ b/src/mc/remote/RemoteClient.cpp @@ -1,59 +1,32 @@ -/* Copyright (c) 2014-2017. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-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. */ #define _FILE_OFFSET_BITS 64 /* needed for pread_whole to work as expected on 32bits */ -#include -#include -#include -#include - -#include +#include "src/mc/remote/RemoteClient.hpp" -#include +#include "src/mc/mc_smx.hpp" +#include "src/mc/sosp/Snapshot.hpp" +#include "xbt/file.hpp" +#include "xbt/log.h" #include -#include -#include // PROT_* -#include -#include - -#include - -#include - #include -#include - -#include "xbt/base.h" -#include "xbt/log.h" -#include - -#include "src/mc/mc_smx.hpp" -#include "src/mc/mc_snapshot.hpp" -#include "src/mc/mc_unw.hpp" - -#include "src/mc/AddressSpace.hpp" -#include "src/mc/ObjectInformation.hpp" -#include "src/mc/Variable.hpp" -#include "src/mc/remote/RemoteClient.hpp" +#include // PROT_* using simgrid::mc::remote; XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information"); -// ***** Helper stuff - namespace simgrid { namespace mc { -#define SO_RE "\\.so[\\.0-9]*$" -#define VERSION_RE "-[\\.0-9-]*$" +// ***** Helper stuff // List of library which memory segments are not considered: -static const char* const filtered_libraries[] = { +static const std::vector filtered_libraries = { #ifdef __linux__ "ld", #elif defined __FreeBSD__ @@ -64,16 +37,17 @@ static const char* const filtered_libraries[] = { "libthr", /* thread library */ "libutil", #endif - "libasan", /* gcc sanitizers */ "libargp", /* workarounds for glibc-less systems */ - "libtsan", - "libubsan", - "libbz2", + "libasan", /* gcc sanitizers */ "libboost_chrono", "libboost_context", "libboost_context-mt", + "libboost_stacktrace_addr2line", + "libboost_stacktrace_backtrace", "libboost_system", "libboost_thread", + "libboost_timer", + "libbz2", "libc", "libc++", "libcdt", @@ -84,57 +58,86 @@ static const char* const filtered_libraries[] = { "libdw", "libelf", "libevent", + "libexecinfo", + "libflang", + "libflangrti", "libgcc_s", + "libgfortran", + "libimf", + "libintlc", + "libirng", "liblua5.1", "liblua5.3", "liblzma", "libm", + "libomp", + "libpapi", + "libpcre2", + "libpfm", + "libpgmath", "libpthread", + "libquadmath", "librt", "libstdc++", + "libsvml", + "libtsan", /* gcc sanitizers */ + "libubsan", /* gcc sanitizers */ "libunwind", - "libunwind-x86_64", - "libunwind-x86", "libunwind-ptrace", - "libz"}; + "libunwind-x86", + "libunwind-x86_64", + "libz", + "libkrb5support", /*odd behaviour on fedora rawhide ... remove these when fixed*/ + "libkeyutils", + "libunistring", + "libbrotlidec", + "liblber", + "libldap", + "libcom_err", + "libk5crypto", + "libkrb5", + "libgssapi_krb5", + "libssl", + "libpsl", + "libssh", + "libidn2", + "libnghttp2", + "libcurl", + "libdebuginfod", + "libbrotlicommon", + "libsasl2", + "libresolv", + "libcrypt", + "libselinux" +}; -static bool is_simgrid_lib(const char* libname) +static bool is_simgrid_lib(const std::string& libname) { - return not strcmp(libname, "libsimgrid"); + return libname == "libsimgrid"; } -static bool is_filtered_lib(const char* libname) +static bool is_filtered_lib(const std::string& libname) { - for (const char* const& filtered_lib : filtered_libraries) - if (strcmp(libname, filtered_lib) == 0) - return true; - return false; + return std::find(begin(filtered_libraries), end(filtered_libraries), libname) != end(filtered_libraries); } -struct s_mc_memory_map_re { - regex_t so_re; - regex_t version_re; -}; - -static char* get_lib_name(const char* pathname, s_mc_memory_map_re* res) +static std::string get_lib_name(const std::string& pathname) { - char* map_basename = xbt_basename(pathname); - - regmatch_t match; - if (regexec(&res->so_re, map_basename, 1, &match, 0)) { - free(map_basename); - return nullptr; - } - - char* libname = strndup(map_basename, match.rm_so); - free(map_basename); - map_basename = nullptr; - - // Strip the version suffix: - if (libname && not regexec(&res->version_re, libname, 1, &match, 0)) { - char* temp = libname; - libname = strndup(temp, match.rm_so); - free(temp); + std::string map_basename = simgrid::xbt::Path(pathname).get_base_name(); + std::string libname; + + size_t pos = map_basename.rfind(".so"); + if (pos != std::string::npos) { + // strip the extension (matching regex "\.so.*$") + libname.assign(map_basename, 0, pos); + + // strip the version suffix (matching regex "-[.0-9-]*$") + while (true) { + pos = libname.rfind('-'); + if (pos == std::string::npos || libname.find_first_not_of(".0123456789", pos + 1) != std::string::npos) + break; + libname.erase(pos); + } } return libname; @@ -222,13 +225,12 @@ void RemoteClient::init() this->memory_file = fd; // Read std_heap (is a struct mdesc*): - simgrid::mc::Variable* std_heap_var = this->find_variable("__mmalloc_default_mdp"); + const simgrid::mc::Variable* std_heap_var = this->find_variable("__mmalloc_default_mdp"); if (not std_heap_var) xbt_die("No heap information in the target process"); if (not std_heap_var->address) xbt_die("No constant address for this variable"); - this->read_bytes(&this->heap_address, sizeof(mdesc*), remote(std_heap_var->address), - simgrid::mc::ProcessIndexDisabled); + this->read_bytes(&this->heap_address, sizeof(mdesc*), remote(std_heap_var->address)); this->smx_actors_infos.clear(); this->smx_dead_actors_infos.clear(); @@ -261,14 +263,14 @@ void RemoteClient::refresh_heap() { // Read/dereference/refresh the std_heap pointer: if (not this->heap) - this->heap = std::unique_ptr(new s_xbt_mheap_t()); - this->read_bytes(this->heap.get(), sizeof(mdesc), remote(this->heap_address), simgrid::mc::ProcessIndexDisabled); + this->heap.reset(new s_xbt_mheap_t()); + this->read_bytes(this->heap.get(), sizeof(mdesc), remote(this->heap_address)); this->cache_flags_ |= RemoteClient::cache_heap; } /** Refresh the information about the process * - * Do not use direclty, this is used by the getters when appropriate + * Do not use directly, this is used by the getters when appropriate * in order to have fresh data. * */ void RemoteClient::refresh_malloc_info() @@ -279,8 +281,7 @@ void RemoteClient::refresh_malloc_info() size_t count = this->heap->heaplimit + 1; if (this->heap_info.size() < count) this->heap_info.resize(count); - this->read_bytes(this->heap_info.data(), count * sizeof(malloc_info), remote(this->heap->heapinfo), - simgrid::mc::ProcessIndexDisabled); + this->read_bytes(this->heap_info.data(), count * sizeof(malloc_info), remote(this->heap->heapinfo)); this->cache_flags_ |= RemoteClient::cache_malloc; } @@ -294,11 +295,6 @@ void RemoteClient::init_memory_map_info() this->binary_info = nullptr; this->libsimgrid_info = nullptr; - s_mc_memory_map_re res; - - if (regcomp(&res.so_re, SO_RE, 0) || regcomp(&res.version_re, VERSION_RE, 0)) - xbt_die(".so regexp did not compile"); - std::vector const& maps = this->memory_map_; const char* current_name = nullptr; @@ -333,13 +329,10 @@ void RemoteClient::init_memory_map_info() continue; const bool is_executable = not i; - char* libname = nullptr; + std::string libname; if (not is_executable) { - libname = get_lib_name(pathname, &res); - if (not libname) - continue; + libname = get_lib_name(pathname); if (is_filtered_lib(libname)) { - free(libname); continue; } } @@ -349,14 +342,10 @@ void RemoteClient::init_memory_map_info() this->object_infos.push_back(info); if (is_executable) this->binary_info = info; - else if (libname && is_simgrid_lib(libname)) + else if (is_simgrid_lib(libname)) this->libsimgrid_info = info; - free(libname); } - regfree(&res.so_re); - regfree(&res.version_re); - // Resolve time (including across different objects): for (auto const& object_info : this->object_infos) postProcessObjectInformation(this, object_info.get()); @@ -399,21 +388,21 @@ simgrid::mc::Frame* RemoteClient::find_function(RemotePtr ip) const /** Find (one occurrence of) the named variable definition */ -simgrid::mc::Variable* RemoteClient::find_variable(const char* name) const +const simgrid::mc::Variable* RemoteClient::find_variable(const char* name) const { // First lookup the variable in the executable shared object. // A global variable used directly by the executable code from a library - // is reinstanciated in the executable memory .data/.bss. + // is reinstantiated in the executable memory .data/.bss. // We need to look up the variable in the executable first. if (this->binary_info) { std::shared_ptr const& info = this->binary_info; - simgrid::mc::Variable* var = info->find_variable(name); + const simgrid::mc::Variable* var = info->find_variable(name); if (var) return var; } for (std::shared_ptr const& info : this->object_infos) { - simgrid::mc::Variable* var = info->find_variable(name); + const simgrid::mc::Variable* var = info->find_variable(name); if (var) return var; } @@ -423,7 +412,8 @@ simgrid::mc::Variable* RemoteClient::find_variable(const char* name) const void RemoteClient::read_variable(const char* name, void* target, size_t size) const { - simgrid::mc::Variable* var = this->find_variable(name); + const simgrid::mc::Variable* var = this->find_variable(name); + xbt_assert(var, "Variable %s not found", name); xbt_assert(var->address, "No simple location for this variable"); xbt_assert(var->type->full_type, "Partial type for %s, cannot check size", name); xbt_assert((size_t)var->type->full_type->byte_size == size, "Unexpected size for %s (expected %zu, was %zu)", name, @@ -436,20 +426,14 @@ std::string RemoteClient::read_string(RemotePtr address) const if (not address) return {}; - // TODO, use std::vector with .data() in C++17 to avoid useless copies std::vector res(128); off_t off = 0; while (1) { ssize_t c = pread(this->memory_file, res.data() + off, res.size() - off, (off_t)address.address() + off); - if (c == -1) { - if (errno == EINTR) - continue; - else - xbt_die("Could not read from from remote process"); - } - if (c == 0) - xbt_die("Could not read string from remote process"); + if (c == -1 && errno == EINTR) + continue; + xbt_assert(c > 0, "Could not read string from remote process"); void* p = memchr(res.data() + off, '\0', c); if (p) @@ -461,33 +445,8 @@ std::string RemoteClient::read_string(RemotePtr address) const } } -const void* RemoteClient::read_bytes(void* buffer, std::size_t size, RemotePtr address, int process_index, - ReadOptions options) const +void* RemoteClient::read_bytes(void* buffer, std::size_t size, RemotePtr address, ReadOptions /*options*/) const { - if (process_index != simgrid::mc::ProcessIndexDisabled) { - std::shared_ptr const& info = this->find_object_info_rw((void*)address.address()); -// Segment overlap is not handled. -#if HAVE_SMPI - if (info.get() && this->privatized(*info)) { - if (process_index < 0) - xbt_die("Missing process index"); - if (process_index >= (int)MC_smpi_process_count()) - xbt_die("Invalid process index"); - - // Read smpi_privatization_regions from MCed: - smpi_privatization_region_t remote_smpi_privatization_regions = - mc_model_checker->process().read_variable("smpi_privatization_regions"); - - s_smpi_privatization_region_t privatization_region = - mc_model_checker->process().read( - remote(remote_smpi_privatization_regions + process_index)); - - // Address translation in the privatization segment: - size_t offset = address.address() - (std::uint64_t)info->start_rw; - address = remote((char*)privatization_region.address + offset); - } -#endif - } if (pread_whole(this->memory_file, buffer, size, (size_t)address.address()) < 0) xbt_die("Read at %p from process %lli failed", (void*)address.address(), (long long)this->pid_); return buffer; @@ -607,10 +566,7 @@ void RemoteClient::unignore_heap(void* address, size_t size) while (start <= end) { cursor = (start + end) / 2; auto& region = ignored_heap_[cursor]; - if (region.address == address) { - ignored_heap_.erase(ignored_heap_.begin() + cursor); - return; - } else if (region.address < address) + if (region.address < address) start = cursor + 1; else if ((char*)region.address <= ((char*)address + size)) { ignored_heap_.erase(ignored_heap_.begin() + cursor); @@ -643,7 +599,7 @@ std::vector& RemoteClient::dead_actors() return smx_dead_actors_infos; } -void RemoteClient::dumpStack() +void RemoteClient::dump_stack() { unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, BYTE_ORDER); if (as == nullptr) { @@ -666,21 +622,20 @@ void RemoteClient::dumpStack() return; } - simgrid::mc::dumpStack(stderr, cursor); + simgrid::mc::dumpStack(stderr, std::move(cursor)); _UPT_destroy(context); unw_destroy_addr_space(as); - return; } bool RemoteClient::actor_is_enabled(aid_t pid) { - s_mc_message_actor_enabled msg{MC_MESSAGE_ACTOR_ENABLED, pid}; - process()->getChannel().send(msg); + s_mc_message_actor_enabled_t msg{MC_MESSAGE_ACTOR_ENABLED, pid}; + process()->get_channel().send(msg); char buff[MC_MESSAGE_LENGTH]; - ssize_t received = process()->getChannel().receive(buff, MC_MESSAGE_LENGTH, true); - xbt_assert(received == sizeof(s_mc_message_int), "Unexpected size in answer to ACTOR_ENABLED"); - return ((mc_message_int_t*)buff)->value; + ssize_t received = process()->get_channel().receive(buff, MC_MESSAGE_LENGTH, true); + xbt_assert(received == sizeof(s_mc_message_int_t), "Unexpected size in answer to ACTOR_ENABLED"); + return ((s_mc_message_int_t*)buff)->value; } } }