From 78ad8111935dd39520e2cbae135e042817d78583 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Mon, 18 May 2015 15:55:28 +0200 Subject: [PATCH] [mc] Make C++ classes out of addres_space, process, snapshot --- buildtools/Cmake/DefinePackages.cmake | 4 +- include/xbt/mmalloc.h | 6 +- ...{mc_address_space.cpp => AddressSpace.cpp} | 12 ++- src/mc/AddressSpace.hpp | 84 +++++++++++++++ src/mc/ModelChecker.cpp | 9 +- src/mc/ModelChecker.hpp | 6 +- src/mc/mc_address_space.h | 102 ------------------ src/mc/mc_checkpoint.cpp | 25 +---- src/mc/mc_compare.cpp | 4 +- src/mc/mc_diff.cpp | 2 +- src/mc/mc_forward.h | 22 +++- src/mc/mc_location.h | 2 +- src/mc/mc_process.cpp | 71 +++++++----- src/mc/mc_process.h | 44 ++++---- src/mc/mc_smx.cpp | 7 +- src/mc/mc_snapshot.cpp | 66 ++++++++---- src/mc/mc_snapshot.h | 34 ++++-- src/mc/mc_state.cpp | 2 +- src/mc/mc_unw.cpp | 6 +- src/mc/mc_visited.cpp | 5 +- src/simix/popping_generated.c | 2 +- src/simix/simcalls.py | 2 +- teshsuite/mc/dwarf/dwarf.cpp | 3 +- teshsuite/mc/dwarf_expression/CMakeLists.txt | 4 +- ...warf_expression.c => dwarf_expression.cpp} | 6 +- 25 files changed, 291 insertions(+), 239 deletions(-) rename src/mc/{mc_address_space.cpp => AddressSpace.cpp} (72%) create mode 100644 src/mc/AddressSpace.hpp delete mode 100644 src/mc/mc_address_space.h rename teshsuite/mc/dwarf_expression/{dwarf_expression.c => dwarf_expression.cpp} (96%) diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index dd757286ed..836b430f7b 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -590,8 +590,8 @@ set(MC_SRC_BASE ) set(MC_SRC - src/mc/mc_address_space.h - src/mc/mc_address_space.cpp + src/mc/AddressSpace.hpp + src/mc/AddressSpace.cpp src/mc/mc_forward.h src/mc/mc_process.h src/mc/mc_process.cpp diff --git a/include/xbt/mmalloc.h b/include/xbt/mmalloc.h index 6523a01304..33ad32278c 100644 --- a/include/xbt/mmalloc.h +++ b/include/xbt/mmalloc.h @@ -22,6 +22,7 @@ #include "xbt/dynar.h" #include "xbt/dict.h" +#include "mc/mc_forward.h" SG_BEGIN_DECL() @@ -66,13 +67,12 @@ XBT_PUBLIC( xbt_mheap_t ) mmalloc_get_default_md(void); xbt_mheap_t mmalloc_set_current_heap(xbt_mheap_t new_heap); xbt_mheap_t mmalloc_get_current_heap(void); -struct s_mc_snapshot; struct s_dw_type; -int mmalloc_compare_heap(struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2); +int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2); int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2); int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t to_ignore1, xbt_dynar_t to_ignore2); -int compare_heap_area(int process_index, const void *area1, const void* area2, struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2, xbt_dynar_t previous, struct s_dw_type *type, int pointer_level); +int compare_heap_area(int process_index, const void *area1, const void* area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_dynar_t previous, struct s_dw_type *type, int pointer_level); void reset_heap_information(void); size_t mmalloc_get_bytes_used(xbt_mheap_t); diff --git a/src/mc/mc_address_space.cpp b/src/mc/AddressSpace.cpp similarity index 72% rename from src/mc/mc_address_space.cpp rename to src/mc/AddressSpace.cpp index df738ecf2d..5a95cd87ec 100644 --- a/src/mc/mc_address_space.cpp +++ b/src/mc/AddressSpace.cpp @@ -4,4 +4,14 @@ /* 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 "mc_address_space.h" +#include "AddressSpace.hpp" + +namespace simgrid { +namespace mc { + +AddressSpace::~AddressSpace() +{ +} + +} +} diff --git a/src/mc/AddressSpace.hpp b/src/mc/AddressSpace.hpp new file mode 100644 index 0000000000..8ac72ea462 --- /dev/null +++ b/src/mc/AddressSpace.hpp @@ -0,0 +1,84 @@ +/* Copyright (c) 2008-2014. 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. */ + +#ifndef MC_ADDRESS_SPACE_H +#define MC_ADDRESS_SPACE_H + +#include +#include + +#include + +#include + +#include "mc_forward.h" + +// Compatibility stuff, will be removed: +#define MC_ADDRESS_SPACE_READ_FLAGS_NONE ::simgrid::mc::AddressSpace::Normal +#define MC_ADDRESS_SPACE_READ_FLAGS_LAZY ::simgrid::mc::AddressSpace::Lazy + +// Compatibility stuff, will be removed: +#define MC_PROCESS_INDEX_MISSING ::simgrid::mc::ProcessIndexMissing +#define MC_PROCESS_INDEX_DISABLED ::simgrid::mc::ProcessIndexDisabled +#define MC_PROCESS_INDEX_ANY ::simgrid::mc::ProcessIndexAny + +namespace simgrid { +namespace mc { + +/** Process index used when no process is available + * + * The expected behaviour is that if a process index is needed it will fail. + * */ +const int ProcessIndexMissing = -1; + +/** Process index used when we don't care about the process index + * */ +const int ProcessIndexDisabled = -2; + +/** Constant used when any process will do. + * + * This is is index of the first process. + */ +const int ProcessIndexAny = 0; + +class AddressSpace { +public: + enum ReadMode { + Normal, + /** Allows the `read_bytes` to return a pointer to another buffer + * where the data ins available instead of copying the data into the buffer + */ + Lazy + }; + virtual ~AddressSpace(); + virtual const void* read_bytes(void* buffer, std::size_t size, + std::uint64_t address, int process_index = ProcessIndexAny, + ReadMode mode = Normal) = 0; + template + T read(uint64_t address, int process_index = ProcessIndexMissing) + { + static_assert(std::is_trivial::value, "Cannot read a non-trivial type"); + T res; + this->read_bytes(&res, sizeof(T), address, process_index); + return res; + } +}; + +} +} + +// Deprecated compatibility wrapper: +static inline +const void* MC_address_space_read( + mc_address_space_t address_space, simgrid::mc::AddressSpace::ReadMode mode, + void* target, const void* addr, size_t size, + int process_index) +{ + return address_space->read_bytes(target, size, (std::uint64_t) addr, + process_index, mode); +} + +#endif diff --git a/src/mc/ModelChecker.cpp b/src/mc/ModelChecker.cpp index 2adb8955a1..2e41784400 100644 --- a/src/mc/ModelChecker.cpp +++ b/src/mc/ModelChecker.cpp @@ -14,16 +14,15 @@ namespace simgrid { namespace mc { -ModelChecker::ModelChecker(pid_t pid, int socket) - : page_store_(500) +ModelChecker::ModelChecker(pid_t pid, int socket) : + hostnames_(xbt_dict_new()), + page_store_(500), + process_(pid, socket) { - this->hostnames_ = xbt_dict_new(); - MC_process_init(&this->process(), pid, socket); } ModelChecker::~ModelChecker() { - MC_process_clear(&this->process_); xbt_dict_free(&this->hostnames_); } diff --git a/src/mc/ModelChecker.hpp b/src/mc/ModelChecker.hpp index 4e3a56505b..f9a13427e4 100644 --- a/src/mc/ModelChecker.hpp +++ b/src/mc/ModelChecker.hpp @@ -28,12 +28,12 @@ namespace mc { * on the model-checker heap, we avoid those issues. */ class ModelChecker { - // This is the parent snapshot of the current state: - s_mc_pages_store_t page_store_; - s_mc_process_t process_; /** String pool for host names */ // TODO, use std::unordered_set with heterogeneous comparison lookup (C++14) xbt_dict_t /* */ hostnames_; + // This is the parent snapshot of the current state: + s_mc_pages_store_t page_store_; + s_mc_process_t process_; public: ModelChecker(ModelChecker const&) = delete; ModelChecker& operator=(ModelChecker const&) = delete; diff --git a/src/mc/mc_address_space.h b/src/mc/mc_address_space.h deleted file mode 100644 index a64b07c888..0000000000 --- a/src/mc/mc_address_space.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright (c) 2008-2014. 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. */ - -#ifndef MC_ADDRESS_SPACE_H -#define MC_ADDRESS_SPACE_H - -#include - -#include - -#include "mc_forward.h" - -SG_BEGIN_DECL() - -// ***** Data types - -/** Options for the read() operation - * - * - MC_ADDRESS_SPACE_READ_FLAGS_LAZY, avoid a copy when the data is - * available in the current process. In this case, the return value - * of MC_address_space_read might be different from the provided one. - */ -typedef int adress_space_read_flags_t; -#define MC_ADDRESS_SPACE_READ_FLAGS_NONE 0 -#define MC_ADDRESS_SPACE_READ_FLAGS_LAZY 1 - -/** Process index used when no process is available - * - * The expected behaviour is that if a process index is needed it will fail. - * */ -#define MC_PROCESS_INDEX_MISSING -1 - -#define MC_PROCESS_INDEX_DISABLED -2 - -/** Process index when any process is suitable - * - * We could use a special negative value in the future. - */ -#define MC_PROCESS_INDEX_ANY 0 - -// ***** Class definition - -typedef struct s_mc_address_space s_mc_address_space_t, *mc_address_space_t; -typedef struct s_mc_address_space_class s_mc_address_space_class_t, *mc_address_space_class_t; - -/** Abstract base class for an address space - * - * This is the base class for all virtual address spaces (process, snapshot). - * It uses dynamic dispatch based on a vtable (`address_space_class`). - */ -struct s_mc_address_space { - const s_mc_address_space_class_t* address_space_class; -}; - -/** Class object (vtable) for the virtual address spaces - */ -struct s_mc_address_space_class { - const void* (*read)( - mc_address_space_t address_space, adress_space_read_flags_t flags, - void* target, const void* addr, size_t size, - int process_index); - mc_process_t (*get_process)(mc_address_space_t address_space); -}; - -typedef const void* (*mc_address_space_class_read_callback_t)( - mc_address_space_t address_space, adress_space_read_flags_t flags, - void* target, const void* addr, size_t size, - int process_index); -typedef mc_process_t (*mc_address_space_class_get_process_callback_t)(mc_address_space_t address_space); - -// ***** Virtual/non-final methods - -/** Read data from the given address space - * - * Dysnamic dispatch. - */ -static inline __attribute__((always_inline)) -const void* MC_address_space_read( - mc_address_space_t address_space, adress_space_read_flags_t flags, - void* target, const void* addr, size_t size, - int process_index) -{ - return address_space->address_space_class->read( - address_space, flags, target, addr, size, - process_index); -} - -static inline __attribute__((always_inline)) -const void* MC_address_space_get_process(mc_address_space_t address_space) -{ - if (address_space->address_space_class->get_process) - return address_space->address_space_class->get_process(address_space); - else - return NULL; -} - -SG_END_DECL() - -#endif diff --git a/src/mc/mc_checkpoint.cpp b/src/mc/mc_checkpoint.cpp index 11d66fc7be..ec0a117bf7 100644 --- a/src/mc/mc_checkpoint.cpp +++ b/src/mc/mc_checkpoint.cpp @@ -98,19 +98,6 @@ void MC_region_destroy(mc_mem_region_t region) xbt_free(region); } -void MC_free_snapshot(mc_snapshot_t snapshot) -{ - for (size_t i = 0; i < snapshot->snapshot_regions_count; i++) { - MC_region_destroy(snapshot->snapshot_regions[i]); - } - xbt_free(snapshot->snapshot_regions); - xbt_free(snapshot->stack_sizes); - xbt_dynar_free(&(snapshot->stacks)); - xbt_dynar_free(&(snapshot->to_ignore)); - xbt_dynar_free(&snapshot->ignored_data); - xbt_free(snapshot); -} - /******************************* Snapshot regions ********************************/ /*********************************************************************************/ @@ -392,7 +379,7 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, current_variable->object_info, &(stack_frame->unw_cursor), (void *) stack_frame->frame_base, - (mc_address_space_t) &mc_model_checker->process(), process_index); + &mc_model_checker->process(), process_index); switch(mc_get_location_type(&location)) { case MC_LOCATION_TYPE_ADDRESS: @@ -697,20 +684,16 @@ static void MC_get_current_fd(mc_snapshot_t snapshot) closedir (fd_dir); } -static s_mc_address_space_class_t mc_snapshot_class = { - (mc_address_space_class_read_callback_t) &MC_snapshot_read, - NULL -}; - mc_snapshot_t MC_take_snapshot(int num_state) { XBT_DEBUG("Taking snapshot %i", num_state); mc_process_t mc_process = &mc_model_checker->process(); - mc_snapshot_t snapshot = xbt_new0(s_mc_snapshot_t, 1); + + mc_snapshot_t snapshot = new simgrid::mc::Snapshot(); + snapshot->process = mc_process; snapshot->num_state = num_state; - snapshot->address_space.address_space_class = &mc_snapshot_class; snapshot->enabled_processes = xbt_dynar_new(sizeof(int), NULL); diff --git a/src/mc/mc_compare.cpp b/src/mc/mc_compare.cpp index d6204d40e9..fd01c586a2 100644 --- a/src/mc/mc_compare.cpp +++ b/src/mc/mc_compare.cpp @@ -232,9 +232,9 @@ static int compare_areas_with_type(struct mc_compare_state& state, case DW_TAG_class_type: xbt_dynar_foreach(type->members, cursor, member) { void *member1 = - mc_member_resolve(real_area1, type, member, (mc_address_space_t) snapshot1, process_index); + mc_member_resolve(real_area1, type, member, snapshot1, process_index); void *member2 = - mc_member_resolve(real_area2, type, member, (mc_address_space_t) snapshot2, process_index); + mc_member_resolve(real_area2, type, member, snapshot2, process_index); mc_mem_region_t subregion1 = mc_get_region_hinted(member1, snapshot1, process_index, region1); mc_mem_region_t subregion2 = mc_get_region_hinted(member2, snapshot2, process_index, region2); res = diff --git a/src/mc/mc_diff.cpp b/src/mc/mc_diff.cpp index abeaf9cfd1..3773c00283 100644 --- a/src/mc/mc_diff.cpp +++ b/src/mc/mc_diff.cpp @@ -1106,7 +1106,7 @@ static dw_type_t get_offset_type(void *real_base_address, dw_type_t type, } else { void *real_member = mc_member_resolve(real_base_address, type, member, - (mc_address_space_t) snapshot, process_index); + snapshot, process_index); if ((char*) real_member - (char *) real_base_address == offset) return member->subtype; } diff --git a/src/mc/mc_forward.h b/src/mc/mc_forward.h index 2152fe8bcc..2abc34a28e 100644 --- a/src/mc/mc_forward.h +++ b/src/mc/mc_forward.h @@ -14,18 +14,29 @@ namespace simgrid { namespace mc { - class PageStore; - class ModelChecker; + +class PageStore; +class ModelChecker; +class AddressSpace; +class Process; +class Snapshot; + } } typedef ::simgrid::mc::ModelChecker s_mc_model_checker_t; typedef ::simgrid::mc::PageStore s_mc_pages_store_t; +typedef ::simgrid::mc::AddressSpace s_mc_address_space_t; +typedef ::simgrid::mc::Process s_mc_process_t; +typedef ::simgrid::mc::Snapshot s_mc_snapshot_t; #else typedef struct _s_mc_model_checker s_mc_model_checker_t; typedef struct _s_mc_pages_store s_mc_pages_store_t; +typedef struct _s_mc_address_space_t s_mc_address_space_t; +typedef struct _s_mc_process_t s_mc_process_t; +typedef struct _s_mc_snapshot_t s_mc_snapshot_t; #endif @@ -34,10 +45,13 @@ typedef struct s_dw_type s_dw_type_t, *dw_type_t; typedef struct s_memory_map s_memory_map_t, *memory_map_t; typedef struct s_dw_variable s_dw_variable_t, *dw_variable_t; typedef struct s_dw_frame s_dw_frame_t, *dw_frame_t; + + typedef s_mc_pages_store_t *mc_pages_store_t; -typedef struct s_mc_snapshot s_mc_snapshot_t, *mc_snapshot_t; -typedef struct s_mc_process s_mc_process_t, * mc_process_t; typedef s_mc_model_checker_t *mc_model_checker_t; +typedef s_mc_address_space_t *mc_address_space_t; +typedef s_mc_process_t *mc_process_t; +typedef s_mc_snapshot_t *mc_snapshot_t; SG_BEGIN_DECL() extern mc_model_checker_t mc_model_checker; diff --git a/src/mc/mc_location.h b/src/mc/mc_location.h index 88841f2226..3dd7308746 100644 --- a/src/mc/mc_location.h +++ b/src/mc/mc_location.h @@ -18,7 +18,7 @@ #include "mc_forward.h" #include "mc_object_info.h" #include "mc_forward.h" -#include "mc_address_space.h" +#include "AddressSpace.hpp" SG_BEGIN_DECL() diff --git a/src/mc/mc_process.cpp b/src/mc/mc_process.cpp index 1ebc9a7fce..cad5f36bb3 100644 --- a/src/mc/mc_process.cpp +++ b/src/mc/mc_process.cpp @@ -27,7 +27,7 @@ #include "mc_process.h" #include "mc_object_info.h" -#include "mc_address_space.h" +#include "AddressSpace.hpp" #include "mc_unw.h" #include "mc_snapshot.h" #include "mc_ignore.h" @@ -50,21 +50,17 @@ static mc_process_t MC_process_get_process(mc_process_t p) { return p; } -static const s_mc_address_space_class_t mc_process_class = { - (mc_address_space_class_read_callback_t) &MC_process_read, - (mc_address_space_class_get_process_callback_t) MC_process_get_process -}; - -bool MC_is_process(mc_address_space_t p) -{ - return p->address_space_class == &mc_process_class; } // ***** mc_process -void MC_process_init(mc_process_t process, pid_t pid, int sockfd) +namespace simgrid { +namespace mc { + +Process::Process(pid_t pid, int sockfd) { - process->address_space.address_space_class = &mc_process_class; + Process* process = this; + process->process_flags = MC_PROCESS_NO_FLAG; process->socket = sockfd; process->pid = pid; @@ -106,9 +102,10 @@ void MC_process_init(mc_process_t process, pid_t pid, int sockfd) } } -void MC_process_clear(mc_process_t process) +Process::~Process() { - process->address_space.address_space_class = NULL; + Process* process = this; + process->process_flags = MC_PROCESS_NO_FLAG; process->pid = 0; @@ -153,6 +150,11 @@ void MC_process_clear(mc_process_t process) process->heap_info = NULL; } +} +} + +extern "C" { + void MC_process_refresh_heap(mc_process_t process) { xbt_assert(mc_mode == MC_MODE_SERVER); @@ -518,42 +520,53 @@ static ssize_t pwrite_whole(int fd, const void *buf, size_t count, off_t offset) return real_count; } -const void* MC_process_read(mc_process_t process, adress_space_read_flags_t flags, - void* local, const void* remote, size_t len, - int process_index) +} + +namespace simgrid { +namespace mc { + +const void *Process::read_bytes(void* buffer, std::size_t size, + std::uint64_t address, int process_index, + AddressSpace::ReadMode mode) { if (process_index != MC_PROCESS_INDEX_DISABLED) { - mc_object_info_t info = MC_process_find_object_info_rw(process, remote); + mc_object_info_t info = MC_process_find_object_info_rw(this, (void*)address); // Segment overlap is not handled. if (MC_object_info_is_privatized(info)) { if (process_index < 0) xbt_die("Missing process index"); // Address translation in the privaization segment: - size_t offset = (const char*) remote - info->start_rw; - remote = (const char*) remote - offset; + // TODO, fix me (broken) + size_t offset = address - (std::uint64_t)info->start_rw; + address = address - offset; } } - if (MC_process_is_self(process)) { - if (flags & MC_ADDRESS_SPACE_READ_FLAGS_LAZY) - return remote; + if (MC_process_is_self(this)) { + if (mode == MC_ADDRESS_SPACE_READ_FLAGS_LAZY) + return (void*)address; else { - memcpy(local, remote, len); - return local; + memcpy(buffer, (void*)address, size); + return buffer; } } else { - if (pread_whole(process->memory_file, local, len, (off_t) remote) < 0) - xbt_die("Read from process %lli failed", (long long) process->pid); - return local; + if (pread_whole(this->memory_file, buffer, size, (off_t) address) < 0) + xbt_die("Read from process %lli failed", (long long) this->pid); + return buffer; } } +} +} + +extern "C" { + const void* MC_process_read_simple(mc_process_t process, void* local, const void* remote, size_t len) { - adress_space_read_flags_t flags = MC_ADDRESS_SPACE_READ_FLAGS_NONE; + simgrid::mc::AddressSpace::ReadMode mode = MC_ADDRESS_SPACE_READ_FLAGS_NONE; int index = MC_PROCESS_INDEX_ANY; - MC_process_read(process, flags, local, remote, len, index); + MC_process_read(process, mode, local, remote, len, index); return local; } diff --git a/src/mc/mc_process.h b/src/mc/mc_process.h index 666d5f3b21..53aa8d1832 100644 --- a/src/mc/mc_process.h +++ b/src/mc/mc_process.h @@ -27,13 +27,9 @@ #include "mc_base.h" #include "mc_mmalloc.h" // std_heap #include "mc_memory_map.h" -#include "mc_address_space.h" +#include "AddressSpace.hpp" #include "mc_protocol.h" -SG_BEGIN_DECL() - -int MC_process_vm_open(pid_t pid, int flags); - typedef int mc_process_flags_t; #define MC_PROCESS_NO_FLAG 0 #define MC_PROCESS_SELF_FLAG 1 @@ -48,10 +44,19 @@ typedef int mc_process_cache_flags_t; typedef struct s_mc_smx_process_info s_mc_smx_process_info_t, *mc_smx_process_info_t; +namespace simgrid { +namespace mc { + /** Representation of a process */ -struct s_mc_process { - s_mc_address_space_t address_space; +class Process : public AddressSpace { +public: + Process(pid_t pid, int sockfd); + ~Process(); + const void* read_bytes(void* buffer, std::size_t size, + std::uint64_t address, int process_index = ProcessIndexAny, + ReadMode mode = Normal) override; +public: // to be private mc_process_flags_t process_flags; pid_t pid; int socket; @@ -123,10 +128,12 @@ struct s_mc_process { xbt_dynar_t checkpoint_ignore; }; -XBT_INTERNAL bool MC_is_process(mc_address_space_t p); +} +} -MC_SHOULD_BE_INTERNAL void MC_process_init(mc_process_t process, pid_t pid, int sockfd); -XBT_INTERNAL void MC_process_clear(mc_process_t process); +SG_BEGIN_DECL() + +int MC_process_vm_open(pid_t pid, int flags); /** Refresh the information about the process * @@ -150,17 +157,14 @@ bool MC_process_is_self(mc_process_t process) /* Process memory access: */ -/** Read data from a process memory - * - * @param process the process - * @param local local memory address (destination) - * @param remote target process memory address (source) - * @param len data size - */ -XBT_INTERNAL const void* MC_process_read(mc_process_t process, - adress_space_read_flags_t flags, +static inline +const void* MC_process_read(mc_process_t process, + simgrid::mc::AddressSpace::ReadMode mode, void* local, const void* remote, size_t len, - int process_index); + int process_index) +{ + return process->read_bytes(local, len, (std::uint64_t)remote, process_index, mode); +} // Simplified versions/wrappers (whould be moved in mc_address_space): XBT_INTERNAL const void* MC_process_read_simple(mc_process_t process, diff --git a/src/mc/mc_smx.cpp b/src/mc/mc_smx.cpp index ab326898e6..a859956088 100644 --- a/src/mc/mc_smx.cpp +++ b/src/mc/mc_smx.cpp @@ -60,7 +60,7 @@ static void MC_process_refresh_simix_process_list( { // swag = REMOTE(*simix_global->process_list) s_xbt_swag_t swag; - MC_process_read(process, MC_PROCESS_NO_FLAG, &swag, remote_swag, sizeof(swag), + MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, &swag, remote_swag, sizeof(swag), MC_PROCESS_INDEX_ANY); smx_process_t p; @@ -74,7 +74,7 @@ static void MC_process_refresh_simix_process_list( info.address = p; info.name = NULL; info.hostname = NULL; - MC_process_read(process, MC_PROCESS_NO_FLAG, + MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, &info.copy, p, sizeof(info.copy), MC_PROCESS_INDEX_ANY); xbt_dynar_push(target, &info); @@ -99,7 +99,8 @@ void MC_process_smx_refresh(mc_process_t process) // simix_global = REMOTE(*simix_global) s_smx_global_t simix_global; - MC_process_read(process, MC_PROCESS_NO_FLAG, &simix_global, simix_global_p, sizeof(simix_global), + MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, &simix_global, + simix_global_p, sizeof(simix_global), MC_PROCESS_INDEX_ANY); MC_process_refresh_simix_process_list( diff --git a/src/mc/mc_snapshot.cpp b/src/mc/mc_snapshot.cpp index 7c587f9e6d..345e23b23d 100644 --- a/src/mc/mc_snapshot.cpp +++ b/src/mc/mc_snapshot.cpp @@ -97,25 +97,6 @@ const void* MC_region_read_fragmented(mc_mem_region_t region, void* target, cons return target; } -/** @brief Read memory from a snapshot - * - * @param addr Process (non-snapshot) address of the data - * @param snapshot Snapshot (or NULL is no snapshot) - * @param target Buffer to store the value - * @param size Size of the data to read in bytes - * @return Pointer where the data is located (target buffer or original location) - */ -const void* MC_snapshot_read( - mc_snapshot_t snapshot, adress_space_read_flags_t flags, - void* target, const void* addr, size_t size, int process_index) -{ - mc_mem_region_t region = mc_get_snapshot_region(addr, snapshot, process_index); - if (region) - return MC_region_read(region, target, addr, size); - else - return MC_process_read(snapshot->process, flags, target, addr, size, process_index); -} - /** Compare memory between snapshots (with known regions) * * @param addr1 Address in the first snapshot @@ -168,6 +149,53 @@ int MC_snapshot_memcmp( return MC_snapshot_region_memcmp(addr1, region1, addr2, region2, size); } +namespace simgrid { +namespace mc { + +Snapshot::Snapshot() : + process(nullptr), + num_state(0), + heap_bytes_used(0), + snapshot_regions(nullptr), + snapshot_regions_count(0), + enabled_processes(0), + privatization_index(0), + stack_sizes(nullptr), + stacks(nullptr), + to_ignore(nullptr), + hash(0), + ignored_data(nullptr), + total_fd(0), + current_fd(nullptr) +{ + +} +Snapshot::~Snapshot() +{ + for (size_t i = 0; i < this->snapshot_regions_count; i++) { + MC_region_destroy(this->snapshot_regions[i]); + } + xbt_free(this->snapshot_regions); + xbt_free(this->stack_sizes); + xbt_dynar_free(&(this->stacks)); + xbt_dynar_free(&(this->to_ignore)); + xbt_dynar_free(&this->ignored_data); +} + +const void* Snapshot::read_bytes(void* buffer, std::size_t size, + std::uint64_t address, int process_index, + AddressSpace::ReadMode mode) +{ + mc_mem_region_t region = mc_get_snapshot_region((void*)address, this, process_index); + if (region) + return MC_region_read(region, buffer, (void*)address, size); + else + return MC_process_read(this->process, mode, buffer, (void*)address, size, process_index); +} + +} +} + #ifdef SIMGRID_TEST #include diff --git a/src/mc/mc_snapshot.h b/src/mc/mc_snapshot.h index 4d93f1c002..5bd9d7a0f0 100644 --- a/src/mc/mc_snapshot.h +++ b/src/mc/mc_snapshot.h @@ -19,7 +19,7 @@ #include "ModelChecker.hpp" #include "PageStore.hpp" #include "mc_mmalloc.h" -#include "mc_address_space.h" +#include "mc/AddressSpace.hpp" #include "mc_unw.h" SG_BEGIN_DECL() @@ -199,10 +199,21 @@ typedef struct s_fd_infos{ int flags; }s_fd_infos_t, *fd_infos_t; -struct s_mc_snapshot { +} + +namespace simgrid { +namespace mc { + +class Snapshot : public AddressSpace { +public: + Snapshot(); + ~Snapshot(); + const void* read_bytes(void* buffer, std::size_t size, + std::uint64_t address, int process_index = ProcessIndexAny, + ReadMode mode = Normal) override; +public: // To be private mc_process_t process; int num_state; - s_mc_address_space_t address_space; size_t heap_bytes_used; mc_mem_region_t* snapshot_regions; size_t snapshot_regions_count; @@ -217,6 +228,11 @@ struct s_mc_snapshot { fd_infos_t *current_fd; }; +} +} + +extern "C" { + static inline __attribute__ ((always_inline)) mc_mem_region_t mc_get_region_hinted(void* addr, mc_snapshot_t snapshot, int process_index, mc_mem_region_t region) { @@ -267,7 +283,6 @@ static const void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot); XBT_INTERNAL mc_snapshot_t MC_take_snapshot(int num_state); XBT_INTERNAL void MC_restore_snapshot(mc_snapshot_t); -XBT_INTERNAL void MC_free_snapshot(mc_snapshot_t); XBT_INTERNAL size_t* mc_take_page_snapshot_region(mc_process_t process, void* data, size_t page_count); @@ -279,9 +294,14 @@ XBT_INTERNAL void mc_restore_page_snapshot_region( MC_SHOULD_BE_INTERNAL const void* MC_region_read_fragmented( mc_mem_region_t region, void* target, const void* addr, size_t size); -XBT_INTERNAL const void* MC_snapshot_read(mc_snapshot_t snapshot, - adress_space_read_flags_t flags, - void* target, const void* addr, size_t size, int process_index); +// Deprecated compatibility wrapper +static inline +const void* MC_snapshot_read(mc_snapshot_t snapshot, + simgrid::mc::AddressSpace::ReadMode mode, + void* target, const void* addr, size_t size, int process_index) +{ + return snapshot->read_bytes(target, size, (uint64_t)addr, process_index, mode); +} MC_SHOULD_BE_INTERNAL int MC_snapshot_region_memcmp( const void* addr1, mc_mem_region_t region1, const void* addr2, mc_mem_region_t region2, size_t size); diff --git a/src/mc/mc_state.cpp b/src/mc/mc_state.cpp index 0ebde42a8b..140452916f 100644 --- a/src/mc/mc_state.cpp +++ b/src/mc/mc_state.cpp @@ -49,7 +49,7 @@ mc_state_t MC_state_new() */ void MC_state_delete(mc_state_t state, int free_snapshot){ if (state->system_state && free_snapshot){ - MC_free_snapshot(state->system_state); + delete state->system_state; } if(_sg_mc_comms_determinism || _sg_mc_send_determinism){ xbt_free(state->index_comm); diff --git a/src/mc/mc_unw.cpp b/src/mc/mc_unw.cpp index aa6eaea1fe..6c894b6930 100644 --- a/src/mc/mc_unw.cpp +++ b/src/mc/mc_unw.cpp @@ -197,7 +197,7 @@ unw_accessors_t mc_unw_accessors = int mc_unw_init_context( mc_unw_context_t context, mc_process_t process, unw_context_t* c) { - context->address_space = (mc_address_space_t) process; + context->address_space = process; context->process = process; // Take a copy of the context for our own purpose: @@ -232,8 +232,8 @@ int mc_unw_init_cursor(unw_cursor_t *cursor, mc_unw_context_t context) return -UNW_EUNSPEC; mc_address_space_t as = context->address_space; - // Use local unwinding for current process: - if (MC_is_process(as) && MC_process_is_self((mc_process_t) as)) + mc_process_t process = dynamic_cast(as); + if (process && MC_process_is_self(process)) return unw_init_local(cursor, &context->context); return unw_init_remote(cursor, context->process->unw_addr_space, context); diff --git a/src/mc/mc_visited.cpp b/src/mc/mc_visited.cpp index bd6cb0a640..d0f79873f7 100644 --- a/src/mc/mc_visited.cpp +++ b/src/mc/mc_visited.cpp @@ -37,9 +37,8 @@ static int is_exploration_stack_state(mc_visited_state_t state){ void visited_state_free(mc_visited_state_t state) { if (state) { - if(!is_exploration_stack_state(state)){ - MC_free_snapshot(state->system_state); - } + if(!is_exploration_stack_state(state)) + delete state->system_state; xbt_free(state); } } diff --git a/src/simix/popping_generated.c b/src/simix/popping_generated.c index 452379c6dc..f6bcfeac86 100644 --- a/src/simix/popping_generated.c +++ b/src/simix/popping_generated.c @@ -15,7 +15,7 @@ #include "smx_private.h" #ifdef HAVE_MC -#include "mc/mc_process.h" +#include "mc/mc_forward.h" #endif XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping); diff --git a/src/simix/simcalls.py b/src/simix/simcalls.py index 15d7c9991d..f7f776d997 100755 --- a/src/simix/simcalls.py +++ b/src/simix/simcalls.py @@ -281,7 +281,7 @@ if __name__=='__main__': fd.write('#include "smx_private.h"\n'); fd.write('#ifdef HAVE_MC\n'); - fd.write('#include "mc/mc_process.h"\n'); + fd.write('#include "mc/mc_forward.h"\n'); fd.write('#endif\n'); fd.write('\n'); fd.write('XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);\n\n'); diff --git a/teshsuite/mc/dwarf/dwarf.cpp b/teshsuite/mc/dwarf/dwarf.cpp index adbe05dc37..36e6a7ec40 100644 --- a/teshsuite/mc/dwarf/dwarf.cpp +++ b/teshsuite/mc/dwarf/dwarf.cpp @@ -125,9 +125,8 @@ int main(int argc, char** argv) dw_variable_t var; dw_type_t type; - s_mc_process_t p; + s_mc_process_t p(getpid(), -1); mc_process_t process = &p; - MC_process_init(&p, getpid(), -1); test_global_variable(process, process->binary_info, "some_local_variable", &some_local_variable, sizeof(int)); diff --git a/teshsuite/mc/dwarf_expression/CMakeLists.txt b/teshsuite/mc/dwarf_expression/CMakeLists.txt index 435f38bb54..838ee57000 100644 --- a/teshsuite/mc/dwarf_expression/CMakeLists.txt +++ b/teshsuite/mc/dwarf_expression/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.6) if(HAVE_MC) set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}") - add_executable(dwarf-expression dwarf_expression.c) + add_executable(dwarf-expression dwarf_expression.cpp) target_link_libraries(dwarf-expression simgrid) endif() @@ -14,6 +14,6 @@ set(tesh_files ) set(testsuite_src ${testsuite_src} - ${CMAKE_CURRENT_SOURCE_DIR}/dwarf_expression.c + ${CMAKE_CURRENT_SOURCE_DIR}/dwarf_expression.cpp PARENT_SCOPE ) diff --git a/teshsuite/mc/dwarf_expression/dwarf_expression.c b/teshsuite/mc/dwarf_expression/dwarf_expression.cpp similarity index 96% rename from teshsuite/mc/dwarf_expression/dwarf_expression.c rename to teshsuite/mc/dwarf_expression/dwarf_expression.cpp index a4dbb9a5df..fc7ab69c7b 100644 --- a/teshsuite/mc/dwarf_expression/dwarf_expression.c +++ b/teshsuite/mc/dwarf_expression/dwarf_expression.cpp @@ -15,7 +15,7 @@ #include "../src/mc/mc_private.h" #include "../src/mc/mc_object_info.h" -static s_mc_process_t process; +static mc_process_t process; static uintptr_t eval_binary_operation(mc_expression_state_t state, int op, uintptr_t a, uintptr_t b) { @@ -115,11 +115,11 @@ void test_deref(mc_expression_state_t state) { } int main(int argc, char** argv) { - MC_process_init(&process, getpid(), -1); + process = new simgrid::mc::Process(getpid(), -1); s_mc_expression_state_t state; memset(&state, 0, sizeof(s_mc_expression_state_t)); - state.address_space = (mc_address_space_t) &process; + state.address_space = (mc_address_space_t) process; basic_test(&state); -- 2.20.1