X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/5954f11308de69ea37c6f6fdd993925f90749984..2376a01092173679830310f4d57b267445959f97:/src/mc/mc_checkpoint.cpp diff --git a/src/mc/mc_checkpoint.cpp b/src/mc/mc_checkpoint.cpp index 961936eafe..3658048dc0 100644 --- a/src/mc/mc_checkpoint.cpp +++ b/src/mc/mc_checkpoint.cpp @@ -110,7 +110,7 @@ RegionSnapshot privatized_region( simgrid::mc::RegionSnapshot region = simgrid::mc::RegionSnapshot( region_type, start_addr, permanent_addr, size); region.privatized_data(std::move(data)); - return std::move(region); + return region; } #endif @@ -181,10 +181,13 @@ static void get_memory_regions(simgrid::mc::Process* process, simgrid::mc::Snaps snapshot->privatization_index = simgrid::mc::ProcessIndexMissing; } +#define PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC) +#define PROT_RW (PROT_READ | PROT_WRITE) +#define PROT_RX (PROT_READ | PROT_EXEC) + /** \brief Fills the position of the segments (executable, read-only, read/write). - * - * `dl_iterate_phdr` would be more robust but would not work in cross-process. * */ +// TODO, use the ELF segment information for more robustness void find_object_address( std::vector const& maps, simgrid::mc::ObjectInformation* result) @@ -201,24 +204,43 @@ void find_object_address( continue; } free(map_basename); - if ((reg.prot & PROT_WRITE)) { + + // This is the non-GNU_RELRO-part of the data segment: + if (reg.prot == PROT_RW) { xbt_assert(!result->start_rw, "Multiple read-write segments for %s, not supported", maps[i].pathname.c_str()); result->start_rw = (char*) reg.start_addr; result->end_rw = (char*) reg.end_addr; - // .bss is usually after the .data: - simgrid::xbt::VmMap const& next = maps[i + 1]; - if (next.pathname.empty() && (next.prot & PROT_WRITE) - && next.start_addr == reg.end_addr) + + // The next VMA might be end of the data segment: + if (i + 1 < maps.size() + && maps[i + 1].pathname.empty() + && maps[i + 1].prot == PROT_RW + && maps[i + 1].start_addr == reg.end_addr) result->end_rw = (char*) maps[i + 1].end_addr; - } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)) { + } + + // This is the text segment: + else if (reg.prot == PROT_RX) { xbt_assert(!result->start_exec, "Multiple executable segments for %s, not supported", maps[i].pathname.c_str()); result->start_exec = (char*) reg.start_addr; result->end_exec = (char*) reg.end_addr; - } else if ((reg.prot & PROT_READ) && !(reg.prot & PROT_EXEC)) { + + // The next VMA might be end of the data segment: + if (i + 1 < maps.size() + && maps[i + 1].pathname.empty() + && maps[i + 1].prot == PROT_RW + && maps[i + 1].start_addr == reg.end_addr) { + result->start_rw = (char*) maps[i + 1].start_addr; + result->end_rw = (char*) maps[i + 1].end_addr; + } + } + + // This is the GNU_RELRO-part of the data segment: + else if (reg.prot == PROT_READ) { xbt_assert(!result->start_ro, "Multiple read only segments for %s, not supported", maps[i].pathname.c_str()); @@ -239,8 +261,7 @@ void find_object_address( if (result->end_exec && (const void*) result->end_exec > result->end) result->end = result->end_exec; - xbt_assert(result->start_rw); - xbt_assert(result->start_exec); + xbt_assert(result->start_exec || result->start_rw || result->start_ro); free(name); } @@ -332,7 +353,7 @@ static std::vector get_local_variables_values( std::vector variables; for (s_mc_stack_frame_t& stack_frame : stack_frames) fill_local_variables_values(&stack_frame, stack_frame.frame, process_index, variables); - return std::move(variables); + return variables; } static std::vector unwind_stack_frames(simgrid::mc::UnwindContext* stack_context) @@ -391,10 +412,10 @@ static std::vector unwind_stack_frames(simgrid::mc::UnwindCo xbt_abort(); } - return std::move(result); + return result; }; -static std::vector take_snapshot_stacks(simgrid::mc::Snapshot* * snapshot) +static std::vector take_snapshot_stacks(simgrid::mc::Snapshot* snapshot) { std::vector res; @@ -418,10 +439,10 @@ static std::vector take_snapshot_stacks(simgrid::mc::Snap 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 std::move(res); + return res; } @@ -537,23 +558,24 @@ static std::vector get_current_fds(pid_t pid) } closedir (fd_dir); - return std::move(fds); + return fds; } -simgrid::mc::Snapshot* take_snapshot(int num_state) +std::shared_ptr take_snapshot(int num_state) { XBT_DEBUG("Taking snapshot %i", num_state); simgrid::mc::Process* mc_process = &mc_model_checker->process(); - simgrid::mc::Snapshot* snapshot = new simgrid::mc::Snapshot(mc_process); + std::shared_ptr snapshot = + std::make_shared(mc_process); snapshot->num_state = num_state; for (auto& p : mc_model_checker->process().simix_processes()) snapshot->enabled_processes.insert(p.copy.pid); - snapshot_handle_ignore(snapshot); + snapshot_handle_ignore(snapshot.get()); if (_sg_mc_snapshot_fds) snapshot->current_fds = get_current_fds(mc_model_checker->process().pid()); @@ -561,15 +583,14 @@ simgrid::mc::Snapshot* take_snapshot(int num_state) const bool use_soft_dirty = _sg_mc_sparse_checkpoint && _sg_mc_soft_dirty; /* Save the std heap and the writable mapped pages of libsimgrid and binary */ - get_memory_regions(mc_process, snapshot); + get_memory_regions(mc_process, snapshot.get()); if (use_soft_dirty) mc_process->reset_soft_dirty(); snapshot->to_ignore = mc_model_checker->process().ignored_heap(); if (_sg_mc_visited > 0 || strcmp(_sg_mc_property_file, "")) { - snapshot->stacks = - take_snapshot_stacks(&snapshot); + snapshot->stacks = take_snapshot_stacks(snapshot.get()); if (_sg_mc_hash) snapshot->hash = simgrid::mc::hash(*snapshot); else @@ -577,7 +598,7 @@ simgrid::mc::Snapshot* take_snapshot(int num_state) } else snapshot->hash = 0; - snapshot_ignore_restore(snapshot); + snapshot_ignore_restore(snapshot.get()); if (use_soft_dirty) mc_model_checker->parent_snapshot_ = snapshot; return snapshot; @@ -624,16 +645,16 @@ void restore_snapshot_fds(simgrid::mc::Snapshot* snapshot) } } -void restore_snapshot(simgrid::mc::Snapshot* snapshot) +void restore_snapshot(std::shared_ptr snapshot) { XBT_DEBUG("Restore snapshot %i", snapshot->num_state); const bool use_soft_dirty = _sg_mc_sparse_checkpoint && _sg_mc_soft_dirty; - restore_snapshot_regions(snapshot); + restore_snapshot_regions(snapshot.get()); if (_sg_mc_snapshot_fds) - restore_snapshot_fds(snapshot); + restore_snapshot_fds(snapshot.get()); if (use_soft_dirty) mc_model_checker->process().reset_soft_dirty(); - snapshot_ignore_restore(snapshot); + snapshot_ignore_restore(snapshot.get()); mc_model_checker->process().clear_cache(); if (use_soft_dirty) mc_model_checker->parent_snapshot_ = snapshot;