X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/96cedde3cdbc0b8ffc3f096a1b65d021b0226f99..b5bfcc5ac199bc0d2ed00a832d08fec1462b9e83:/src/mc/sosp/mc_checkpoint.cpp diff --git a/src/mc/sosp/mc_checkpoint.cpp b/src/mc/sosp/mc_checkpoint.cpp index 0d172a822c..99cd848898 100644 --- a/src/mc/sosp/mc_checkpoint.cpp +++ b/src/mc/sosp/mc_checkpoint.cpp @@ -5,11 +5,6 @@ #include -#include -#include -#include -#include - #ifndef WIN32 #include #endif @@ -35,13 +30,9 @@ #include "src/mc/mc_hash.hpp" #include "src/mc/mc_mmu.hpp" #include "src/mc/mc_smx.hpp" -#include "src/mc/mc_unw.hpp" #include "src/mc/remote/mc_protocol.h" #include "src/mc/sosp/mc_snapshot.hpp" -#include "src/mc/Frame.hpp" -#include "src/mc/ObjectInformation.hpp" -#include "src/mc/Variable.hpp" #include "src/mc/sosp/RegionSnapshot.hpp" using simgrid::mc::remote; @@ -62,7 +53,7 @@ namespace mc { * * @param region Target region */ -static void restore(mc_mem_region_t region) +static void restore(RegionSnapshot* region) { switch (region->storage_type()) { case simgrid::mc::StorageType::Flat: @@ -70,7 +61,16 @@ static void restore(mc_mem_region_t region) break; case simgrid::mc::StorageType::Chunked: - mc_region_restore_sparse(&mc_model_checker->process(), region); + xbt_assert(((region->permanent_address().address()) & (xbt_pagesize - 1)) == 0, "Not at the beginning of a page"); + xbt_assert(simgrid::mc::mmu::chunk_count(region->size()) == region->page_data().page_count()); + + for (size_t i = 0; i != region->page_data().page_count(); ++i) { + void* target_page = + (void*)simgrid::mc::mmu::join(i, (std::uintptr_t)(void*)region->permanent_address().address()); + const void* source_page = region->page_data().page(i); + mc_model_checker->process().write_bytes(source_page, xbt_pagesize, remote(target_page)); + } + break; case simgrid::mc::StorageType::Privatized: @@ -97,65 +97,41 @@ RegionSnapshot privatized_region(RegionType region_type, void* start_addr, void* mc_model_checker->process().read_bytes(&privatization_regions, sizeof(privatization_regions), remote(remote_smpi_privatization_regions)); - std::vector data; + std::vector data; data.reserve(process_count); for (size_t i = 0; i < process_count; i++) - data.push_back(simgrid::mc::region(region_type, start_addr, privatization_regions[i].address, size)); + data.push_back(region(region_type, start_addr, privatization_regions[i].address, size)); - simgrid::mc::RegionSnapshot region = simgrid::mc::RegionSnapshot(region_type, start_addr, permanent_addr, size); + RegionSnapshot region = RegionSnapshot(region_type, start_addr, permanent_addr, size); region.privatized_data(std::move(data)); return region; } #endif -static void add_region(int index, simgrid::mc::Snapshot* snapshot, simgrid::mc::RegionType type, - simgrid::mc::ObjectInformation* object_info, void* start_addr, void* permanent_addr, - std::size_t size) -{ - if (type == simgrid::mc::RegionType::Data) - xbt_assert(object_info, "Missing object info for object."); - else if (type == simgrid::mc::RegionType::Heap) - xbt_assert(not object_info, "Unexpected object info for heap region."); - - simgrid::mc::RegionSnapshot region; -#if HAVE_SMPI - const bool privatization_aware = object_info && mc_model_checker->process().privatized(*object_info); - if (privatization_aware && MC_smpi_process_count()) - region = simgrid::mc::privatized_region(type, start_addr, permanent_addr, size); - else -#endif - region = simgrid::mc::region(type, start_addr, permanent_addr, size); - - region.object_info(object_info); - snapshot->snapshot_regions[index] = - std::unique_ptr(new simgrid::mc::RegionSnapshot(std::move(region))); -} - static void get_memory_regions(simgrid::mc::RemoteClient* process, simgrid::mc::Snapshot* snapshot) { - const size_t n = process->object_infos.size(); - snapshot->snapshot_regions.resize(n + 1); - int i = 0; + snapshot->snapshot_regions_.clear(); + for (auto const& object_info : process->object_infos) - add_region(i++, snapshot, simgrid::mc::RegionType::Data, object_info.get(), object_info->start_rw, - object_info->start_rw, object_info->end_rw - object_info->start_rw); + snapshot->add_region(simgrid::mc::RegionType::Data, object_info.get(), object_info->start_rw, object_info->start_rw, + object_info->end_rw - object_info->start_rw); xbt_mheap_t heap = process->get_heap(); void* start_heap = heap->base; void* end_heap = heap->breakval; - add_region(n, snapshot, simgrid::mc::RegionType::Heap, nullptr, start_heap, start_heap, - (char*)end_heap - (char*)start_heap); - snapshot->heap_bytes_used = mmalloc_get_bytes_used_remote(heap->heaplimit, process->get_malloc_info()); + snapshot->add_region(simgrid::mc::RegionType::Heap, nullptr, start_heap, start_heap, + (char*)end_heap - (char*)start_heap); + snapshot->heap_bytes_used_ = mmalloc_get_bytes_used_remote(heap->heaplimit, process->get_malloc_info()); #if HAVE_SMPI if (mc_model_checker->process().privatized() && MC_smpi_process_count()) // snapshot->privatization_index = smpi_loaded_page - mc_model_checker->process().read_variable("smpi_loaded_page", &snapshot->privatization_index, - sizeof(snapshot->privatization_index)); + mc_model_checker->process().read_variable("smpi_loaded_page", &snapshot->privatization_index_, + sizeof(snapshot->privatization_index_)); else #endif - snapshot->privatization_index = simgrid::mc::ProcessIndexMissing; + snapshot->privatization_index_ = simgrid::mc::ProcessIndexMissing; } /** @brief Fills the position of the segments (executable, read-only, read/write). @@ -247,8 +223,6 @@ static bool valid_variable(simgrid::mc::Variable* var, simgrid::mc::Frame* scope static void fill_local_variables_values(mc_stack_frame_t stack_frame, simgrid::mc::Frame* scope, int process_index, std::vector& result) { - simgrid::mc::RemoteClient* process = &mc_model_checker->process(); - if (not scope || not scope->range.contain(stack_frame->ip)) return; @@ -257,19 +231,11 @@ static void fill_local_variables_values(mc_stack_frame_t stack_frame, simgrid::m if (not valid_variable(¤t_variable, scope, (void*)stack_frame->ip)) continue; - int region_type; - // FIXME, get rid of `region_type` - if ((long)stack_frame->ip > (long)process->libsimgrid_info->start_exec) - region_type = 1; - else - region_type = 2; - s_local_variable_t new_var; new_var.subprogram = stack_frame->frame; new_var.ip = stack_frame->ip; new_var.name = current_variable.name; new_var.type = current_variable.type; - new_var.region = region_type; new_var.address = nullptr; if (current_variable.address != nullptr) @@ -343,7 +309,7 @@ static std::vector unwind_stack_frames(simgrid::mc::UnwindCo result.push_back(std::move(stack_frame)); /* Stop before context switch with maestro */ - if (frame != nullptr && frame->name == "smx_ctx_sysv_wrapper") + if (frame != nullptr && frame->name == "smx_ctx_wrapper") break; int ret = unw_step(&c); @@ -353,18 +319,13 @@ static std::vector unwind_stack_frames(simgrid::mc::UnwindCo xbt_die("Error while unwinding stack"); } - if (result.empty()) { - XBT_INFO("unw_init_local failed"); - xbt_abort(); - } + xbt_assert(not result.empty(), "unw_init_local failed"); return result; } -static std::vector take_snapshot_stacks(simgrid::mc::Snapshot* snapshot) +static void take_snapshot_stacks(simgrid::mc::Snapshot* snapshot) { - std::vector res; - for (auto const& stack : mc_model_checker->process().stack_areas()) { s_mc_snapshot_stack_t st; @@ -380,13 +341,11 @@ static std::vector take_snapshot_stacks(simgrid::mc::Snap unw_word_t sp = st.stack_frames[0].sp; - res.push_back(std::move(st)); + snapshot->stacks_.push_back(std::move(st)); size_t stack_size = (char*)stack.address + stack.size - (char*)sp; - snapshot->stack_sizes.push_back(stack_size); + snapshot->stack_sizes_.push_back(stack_size); } - - return res; } static void snapshot_handle_ignore(simgrid::mc::Snapshot* snapshot) @@ -401,7 +360,7 @@ static void snapshot_handle_ignore(simgrid::mc::Snapshot* snapshot) // TODO, we should do this once per privatization segment: snapshot->process()->read_bytes(ignored_data.data.data(), region.size, remote(region.addr), simgrid::mc::ProcessIndexDisabled); - snapshot->ignored_data.push_back(std::move(ignored_data)); + snapshot->ignored_data_.push_back(std::move(ignored_data)); } // Zero the memory: @@ -411,90 +370,10 @@ static void snapshot_handle_ignore(simgrid::mc::Snapshot* snapshot) static void snapshot_ignore_restore(simgrid::mc::Snapshot* snapshot) { - for (auto const& ignored_data : snapshot->ignored_data) + for (auto const& ignored_data : snapshot->ignored_data_) snapshot->process()->write_bytes(ignored_data.data.data(), ignored_data.data.size(), remote(ignored_data.start)); } -static std::vector get_current_fds(pid_t pid) -{ - const size_t fd_dir_path_size = 20; - char fd_dir_path[fd_dir_path_size]; - int res = snprintf(fd_dir_path, fd_dir_path_size, "/proc/%lli/fd", (long long int)pid); - xbt_assert(res >= 0); - if ((size_t)res > fd_dir_path_size) - xbt_die("Unexpected buffer is too small for fd_dir_path"); - - DIR* fd_dir = opendir(fd_dir_path); - if (fd_dir == nullptr) - xbt_die("Cannot open directory '/proc/self/fd'\n"); - - std::vector fds; - - struct dirent* fd_number; - while ((fd_number = readdir(fd_dir))) { - - int fd_value = xbt_str_parse_int(fd_number->d_name, "Found a non-numerical FD: %s. Freaking out!"); - - if (fd_value < 3) - continue; - - const size_t source_size = 25; - char source[25]; - int res = snprintf(source, source_size, "/proc/%lli/fd/%s", (long long int)pid, fd_number->d_name); - xbt_assert(res >= 0); - if ((size_t)res > source_size) - xbt_die("Unexpected buffer is too small for fd %s", fd_number->d_name); - - const size_t link_size = 200; - char link[200]; - res = readlink(source, link, link_size); - - if (res < 0) - xbt_die("Could not read link for %s", source); - if (res == 200) - xbt_die("Buffer to small for link of %s", source); - - link[res] = '\0'; - -#if HAVE_SMPI - if (smpi_is_privatization_file(link)) - continue; -#endif - - // This is (probably) the DIR* we are reading: - // TODO, read all the file entries at once and close the DIR.* - if (strcmp(fd_dir_path, link) == 0) - continue; - - // We don't handle them. - // It does not mean we should silently ignore them however. - if (strncmp(link, "pipe:", std::strlen("pipe:")) == 0 || strncmp(link, "socket:", std::strlen("socket:")) == 0) - continue; - - // If dot_output enabled, do not handle the corresponding file - if (dot_output != nullptr) { - std::string link_basename = simgrid::xbt::Path(link).get_base_name(); - if (link_basename == _sg_mc_dot_output_file.get()) - continue; - } - - // This is probably a shared memory used by lttng-ust: - if (strncmp("/dev/shm/ust-shm-tmp-", link, std::strlen("/dev/shm/ust-shm-tmp-")) == 0) - continue; - - // Add an entry for this FD in the snapshot: - s_fd_infos_t fd; - fd.filename = std::string(link); - fd.number = fd_value; - fd.flags = fcntl(fd_value, F_GETFL) | fcntl(fd_value, F_GETFD); - fd.current_position = lseek(fd_value, 0, SEEK_CUR); - fds.push_back(std::move(fd)); - } - - closedir(fd_dir); - return fds; -} - std::shared_ptr take_snapshot(int num_state) { XBT_DEBUG("Taking snapshot %i", num_state); @@ -504,26 +383,20 @@ std::shared_ptr take_snapshot(int num_state) std::shared_ptr snapshot = std::make_shared(mc_process, num_state); for (auto const& p : mc_model_checker->process().actors()) - snapshot->enabled_processes.insert(p.copy.getBuffer()->pid_); + snapshot->enabled_processes_.insert(p.copy.getBuffer()->get_pid()); snapshot_handle_ignore(snapshot.get()); - if (_sg_mc_snapshot_fds) - snapshot->current_fds = get_current_fds(mc_model_checker->process().pid()); - /* Save the std heap and the writable mapped pages of libsimgrid and binary */ get_memory_regions(mc_process, snapshot.get()); - snapshot->to_ignore = mc_model_checker->process().ignored_heap(); + snapshot->to_ignore_ = mc_model_checker->process().ignored_heap(); if (_sg_mc_max_visited_states > 0 || not _sg_mc_property_file.get().empty()) { - snapshot->stacks = take_snapshot_stacks(snapshot.get()); + take_snapshot_stacks(snapshot.get()); if (_sg_mc_hash) - snapshot->hash = simgrid::mc::hash(*snapshot); - else - snapshot->hash = 0; - } else - snapshot->hash = 0; + snapshot->hash_ = simgrid::mc::hash(*snapshot); + } snapshot_ignore_restore(snapshot.get()); return snapshot; @@ -531,44 +404,25 @@ std::shared_ptr take_snapshot(int num_state) static inline void restore_snapshot_regions(simgrid::mc::Snapshot* snapshot) { - for (std::unique_ptr const& region : snapshot->snapshot_regions) { + for (std::unique_ptr const& region : snapshot->snapshot_regions_) { // For privatized, variables we decided it was not necessary to take the snapshot: if (region) restore(region.get()); } #if HAVE_SMPI - if (snapshot->privatization_index >= 0) { + if (snapshot->privatization_index_ >= 0) { // Fix the privatization mmap: - s_mc_message_restore_t message{MC_MESSAGE_RESTORE, snapshot->privatization_index}; + s_mc_message_restore_t message{MC_MESSAGE_RESTORE, snapshot->privatization_index_}; mc_model_checker->process().getChannel().send(message); } #endif } -static inline void restore_snapshot_fds(simgrid::mc::Snapshot* snapshot) -{ - xbt_die("FD snapshot not implemented in client/server mode."); - - for (auto const& fd : snapshot->current_fds) { - - int new_fd = open(fd.filename.c_str(), fd.flags); - if (new_fd < 0) - xbt_die("Could not reopen the file %s fo restoring the file descriptor", fd.filename.c_str()); - if (new_fd != fd.number) { - dup2(new_fd, fd.number); - close(new_fd); - } - lseek(fd.number, fd.current_position, SEEK_SET); - } -} - void restore_snapshot(std::shared_ptr snapshot) { - XBT_DEBUG("Restore snapshot %i", snapshot->num_state); + XBT_DEBUG("Restore snapshot %i", snapshot->num_state_); restore_snapshot_regions(snapshot.get()); - if (_sg_mc_snapshot_fds) - restore_snapshot_fds(snapshot.get()); snapshot_ignore_restore(snapshot.get()); mc_model_checker->process().clear_cache(); }