X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/31fdb2a73f84ad56d97facc52298766e4b6aed33..e1459ae1f3ca27cf74f3592980445151049defd1:/src/mc/Process.hpp diff --git a/src/mc/Process.hpp b/src/mc/Process.hpp index f6b941a7f8..7f4127e5c1 100644 --- a/src/mc/Process.hpp +++ b/src/mc/Process.hpp @@ -7,56 +7,100 @@ #ifndef SIMGRID_MC_PROCESS_H #define SIMGRID_MC_PROCESS_H -#include - -#include +#include +#include +#include #include #include +#include -#include "simgrid_config.h" #include +#include + #include #include -#ifdef HAVE_MC #include "src/xbt/mmalloc/mmprivate.h" -#endif +#include "src/mc/Channel.hpp" #include #include "src/simix/popping_private.h" #include "src/simix/smx_private.h" -#include "mc_forward.hpp" -#include "mc_base.h" -#include "mc_mmalloc.h" // std_heap -#include "mc_memory_map.h" -#include "AddressSpace.hpp" -#include "mc_protocol.h" - -// Those flags are used to track down which cached information -// is still up to date and which information needs to be updated. -typedef int mc_process_cache_flags_t; -#define MC_PROCESS_CACHE_FLAG_NONE 0 -#define MC_PROCESS_CACHE_FLAG_HEAP 1 -#define MC_PROCESS_CACHE_FLAG_MALLOC_INFO 2 -#define MC_PROCESS_CACHE_FLAG_SIMIX_PROCESSES 4 +#include "src/xbt/memory_map.hpp" + +#include "src/mc/mc_forward.hpp" +#include "src/mc/mc_base.h" +#include "src/mc/RemotePtr.hpp" +#include "src/mc/AddressSpace.hpp" +#include "src/mc/mc_protocol.h" +#include "src/mc/ObjectInformation.hpp" + namespace simgrid { namespace mc { +class SimixProcessInformation { +public: + /** MCed address of the process */ + RemotePtr address = nullptr; + union { + /** (Flat) Copy of the process data structure */ + struct s_smx_process copy; + }; + /** Hostname (owned by `mc_modelchecker->hostnames`) */ + const char* hostname = nullptr; + std::string name; + + void clear() + { + name.clear(); + address = nullptr; + hostname = nullptr; + } +}; + struct IgnoredRegion { std::uint64_t addr; - size_t size; + std::size_t size; +}; + +struct IgnoredHeapRegion { + int block; + int fragment; + void *address; + std::size_t size; }; /** Representation of a process + * + * This class is mixing a lot of different responsabilities and is tied + * to SIMIX. It should probably be split into different classes. + * + * Responsabilities: + * + * - reading from the process memory (`AddressSpace`); + * - accessing the system state of the porcess (heap, …); + * - storing the SIMIX state of the process; + * - privatization; + * - communication with the model-checked process; + * - stack unwinding; + * - etc. */ class Process final : public AddressSpace { +private: + // Those flags are used to track down which cached information + // is still up to date and which information needs to be updated. + static constexpr int cache_none = 0; + static constexpr int cache_heap = 1; + static constexpr int cache_malloc = 2; + static constexpr int cache_simix_processes = 4; public: Process(pid_t pid, int sockfd); ~Process(); + void init(); Process(Process const&) = delete; Process(Process &&) = delete; @@ -65,8 +109,8 @@ public: // Read memory: const void* read_bytes(void* buffer, std::size_t size, - remote_ptr address, int process_index = ProcessIndexAny, - ReadMode mode = Normal) const override; + RemotePtr address, int process_index = ProcessIndexAny, + ReadOptions options = ReadOptions::none()) const override; void read_variable(const char* name, void* target, size_t size) const; template T read_variable(const char *name) const @@ -76,32 +120,40 @@ public: read_variable(name, &res, sizeof(T)); return res; } - char* read_string(remote_ptr address) const; + std::string read_string(RemotePtr address) const; // Write memory: - void write_bytes(const void* buffer, size_t len, remote_ptr address); - void clear_bytes(remote_ptr address, size_t len); + void write_bytes(const void* buffer, size_t len, RemotePtr address); + void clear_bytes(RemotePtr address, size_t len); // Debug information: - std::shared_ptr find_object_info(remote_ptr addr) const; - std::shared_ptr find_object_info_exec(remote_ptr addr) const; - std::shared_ptr find_object_info_rw(remote_ptr addr) const; - simgrid::mc::Frame* find_function(remote_ptr ip) const; + std::shared_ptr find_object_info(RemotePtr addr) const; + std::shared_ptr find_object_info_exec(RemotePtr addr) const; + std::shared_ptr find_object_info_rw(RemotePtr addr) const; + simgrid::mc::Frame* find_function(RemotePtr ip) const; simgrid::mc::Variable* find_variable(const char* name) const; // Heap access: xbt_mheap_t get_heap() { - if (!(this->cache_flags & MC_PROCESS_CACHE_FLAG_HEAP)) + if (!(this->cache_flags_ & Process::cache_heap)) this->refresh_heap(); return this->heap.get(); } malloc_info* get_malloc_info() { - if (!(this->cache_flags & MC_PROCESS_CACHE_FLAG_MALLOC_INFO)) + if (!(this->cache_flags_ & Process::cache_malloc)) this->refresh_malloc_info(); - return this->heap_info; + return this->heap_info.data(); } + + void clear_cache() + { + this->cache_flags_ = Process::cache_none; + } + + Channel const& getChannel() const { return channel_; } + Channel& getChannel() { return channel_; } std::vector const& ignored_regions() const { @@ -111,7 +163,7 @@ public: pid_t pid() const { return pid_; } - bool in_maestro_stack(remote_ptr p) const + bool in_maestro_stack(RemotePtr p) const { return p >= this->maestro_stack_start_ && p < this->maestro_stack_end_; } @@ -121,54 +173,101 @@ public: return running_; } - void terminate(int status) + void terminate() { - status_ = status; running_ = false; } - int status() const + void reset_soft_dirty(); + void read_pagemap(uint64_t* pagemap, size_t start_page, size_t page_count); + + bool privatized(ObjectInformation const& info) const + { + return privatized_ && info.executable(); + } + bool privatized() const + { + return privatized_; + } + void privatized(bool privatized) { privatized_ = privatized; } + + void ignore_global_variable(const char* name) { - return status_; + for (std::shared_ptr const& info : + this->object_infos) + info->remove_global_variable(name); } - template - typename std::enable_if< std::is_class::value && std::is_trivial::value, int >::type - send_message(M const& m) + std::vector& stack_areas() { - return MC_protocol_send(this->socket_, &m, sizeof(M)); + return stack_areas_; + } + std::vector const& stack_areas() const + { + return stack_areas_; } - int send_message(e_mc_message_type message_id) + std::vector const& ignored_heap() const { - return MC_protocol_send_simple_message(this->socket_, message_id); + return ignored_heap_; } + void ignore_heap(IgnoredHeapRegion const& region); + void unignore_heap(void *address, size_t size); + + void ignore_local_variable(const char *var_name, const char *frame_name); + std::vector& simix_processes(); + std::vector& old_simix_processes(); - template - typename std::enable_if< std::is_class::value && std::is_trivial::value, ssize_t >::type - receive_message(M& m) + /** Get a local description of a remote SIMIX process */ + simgrid::mc::SimixProcessInformation* resolveProcessInfo( + simgrid::mc::RemotePtr process) { - return MC_receive_message(this->socket_, &m, sizeof(M), 0); + xbt_assert(mc_mode == MC_MODE_SERVER); + if (!process) + return nullptr; + this->refresh_simix(); + for (auto& process_info : this->smx_process_infos) + if (process_info.address == process) + return &process_info; + for (auto& process_info : this->smx_old_process_infos) + if (process_info.address == process) + return &process_info; + return nullptr; } - void reset_soft_dirty(); - void read_pagemap(uint64_t* pagemap, size_t start_page, size_t page_count); + /** Get a local copy of the SIMIX process structure */ + smx_process_t resolveProcess(simgrid::mc::RemotePtr process) + { + simgrid::mc::SimixProcessInformation* process_info = + this->resolveProcessInfo(process); + if (process_info) + return &process_info->copy; + else + return nullptr; + } + + void dumpStack(); private: void init_memory_map_info(); void refresh_heap(); void refresh_malloc_info(); + void refresh_simix(); + private: - pid_t pid_; - int socket_; - int status_; - bool running_; - std::vector memory_map_; - remote_ptr maestro_stack_start_, maestro_stack_end_; - int memory_file; + pid_t pid_ = -1; + Channel channel_; + bool running_ = false; + std::vector memory_map_; + RemotePtr maestro_stack_start_, maestro_stack_end_; + int memory_file = -1; std::vector ignored_regions_; - int clear_refs_fd_; - int pagemap_fd_; + int clear_refs_fd_ = -1; + int pagemap_fd_ = -1; + bool privatized_ = false; + std::vector stack_areas_; + std::vector ignored_heap_; + public: // object info // TODO, make private (first, objectify simgrid::mc::ObjectInformation*) std::vector> object_infos; @@ -180,17 +279,19 @@ public: // Copies of MCed SMX data structures * * See mc_smx.c. */ - xbt_dynar_t smx_process_infos; + std::vector smx_process_infos; /** Copy of `simix_global->process_to_destroy` * * See mc_smx.c. */ - xbt_dynar_t smx_old_process_infos; + std::vector smx_old_process_infos; +private: /** State of the cache (which variables are up to date) */ - mc_process_cache_flags_t cache_flags; + int cache_flags_ = Process::cache_none; +public: /** Address of the heap structure in the MCed process. */ void* heap_address; @@ -208,13 +309,13 @@ public: // Copies of MCed SMX data structures * This is not used if the process is the current one: * use `get_malloc_info()` in order to use it. */ - malloc_info* heap_info; + std::vector heap_info; public: // Libunwind-data /** Full-featured MC-aware libunwind address space for the process * - * This address space is using a mc_unw_context_t + * This address space is using a simgrid::mc::UnwindContext* * (with simgrid::mc::Process* / simgrid::mc::AddressSpace* * and unw_context_t). */ @@ -240,10 +341,4 @@ XBT_PRIVATE int open_vm(pid_t pid, int flags); } } -SG_BEGIN_DECL() - -XBT_PRIVATE void MC_invalidate_cache(void); - -SG_END_DECL() - #endif