X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/b3b356352e87ae00a20f737c48e19b0c8413455a..a816142ba29faddef700304e151716780d431d20:/src/mc/mc_checkpoint.cpp diff --git a/src/mc/mc_checkpoint.cpp b/src/mc/mc_checkpoint.cpp index 7f4a8218e1..4360d0648b 100644 --- a/src/mc/mc_checkpoint.cpp +++ b/src/mc/mc_checkpoint.cpp @@ -63,7 +63,7 @@ static void MC_region_restore(mc_mem_region_t region) break; case simgrid::mc::StorageType::Flat: - mc_model_checker->process().write_bytes(region->flat_data().data(), + mc_model_checker->process().write_bytes(region->flat_data(), region->size(), region->permanent_address()); break; @@ -83,8 +83,10 @@ static void MC_region_restore(mc_mem_region_t region) namespace simgrid { namespace mc { +#ifdef HAVE_SMPI simgrid::mc::RegionSnapshot privatized_region( - RegionType region_type, void *start_addr, void* permanent_addr, size_t size + RegionType region_type, void *start_addr, void* permanent_addr, + std::size_t size, const simgrid::mc::RegionSnapshot* ref_region ) { size_t process_count = MC_smpi_process_count(); @@ -101,17 +103,20 @@ simgrid::mc::RegionSnapshot privatized_region( 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, - privatisation_regions[i].address, size) - ); + for (size_t i = 0; i < process_count; i++) { + const simgrid::mc::RegionSnapshot* ref_privatized_region = nullptr; + if (ref_region && ref_region->storage_type() == StorageType::Privatized) + ref_privatized_region = &ref_region->privatized_data()[i]; + data.push_back(simgrid::mc::region(region_type, start_addr, + privatisation_regions[i].address, size, ref_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); } +#endif } } @@ -121,20 +126,27 @@ extern "C" { static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, simgrid::mc::RegionType type, simgrid::mc::ObjectInformation* object_info, - void *start_addr, void* permanent_addr, size_t size) + 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(!object_info, "Unexpected object info for heap region."); - const bool privatization_aware = object_info && object_info->privatized(); + simgrid::mc::RegionSnapshot const* ref_region = nullptr; + if (mc_model_checker->parent_snapshot_) + ref_region = mc_model_checker->parent_snapshot_->snapshot_regions[index].get(); simgrid::mc::RegionSnapshot region; +#ifdef HAVE_SMPI + const bool privatization_aware = object_info && object_info->privatized(); if (privatization_aware && MC_smpi_process_count()) - region = simgrid::mc::privatized_region(type, start_addr, permanent_addr, size); + region = simgrid::mc::privatized_region( + type, start_addr, permanent_addr, size, ref_region); else - region = simgrid::mc::region(type, start_addr, permanent_addr, size); +#endif + region = simgrid::mc::region(type, start_addr, permanent_addr, size, ref_region); region.object_info(object_info); snapshot->snapshot_regions[index] @@ -185,9 +197,10 @@ static void MC_get_memory_regions(simgrid::mc::Process* process, mc_snapshot_t s * `dl_iterate_phdr` would be more robust but would not work in cross-process. * */ void MC_find_object_address( - std::vector const& maps, simgrid::mc::ObjectInformation* result) + std::vector const& maps, + simgrid::mc::ObjectInformation* result) { - const char* file_name = xbt_strdup(result->file_name.c_str()); + char* file_name = xbt_strdup(result->file_name.c_str()); const char *name = basename(file_name); for (size_t i = 0; i < maps.size(); ++i) { simgrid::mc::VmMap const& reg = maps[i]; @@ -235,6 +248,7 @@ void MC_find_object_address( xbt_assert(result->start_rw); xbt_assert(result->start_exec); + free(file_name); } /************************************* Take Snapshot ************************************/ @@ -249,7 +263,8 @@ void MC_find_object_address( * \param ip Instruction pointer * \return true if the variable is valid * */ -static bool mc_valid_variable(simgrid::mc::Variable* var, simgrid::mc::Frame* scope, +static bool mc_valid_variable(simgrid::mc::Variable* var, + simgrid::mc::Frame* scope, const void *ip) { // The variable is not yet valid: @@ -260,7 +275,8 @@ static bool mc_valid_variable(simgrid::mc::Variable* var, simgrid::mc::Frame* sc } static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, - simgrid::mc::Frame* scope, int process_index, + simgrid::mc::Frame* scope, + int process_index, std::vector& result) { simgrid::mc::Process* process = &mc_model_checker->process(); @@ -293,22 +309,17 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, if (current_variable.address != NULL) { new_var.address = current_variable.address; } else if (!current_variable.location_list.empty()) { - s_mc_location_t location; - mc_dwarf_resolve_locations( - &location, ¤t_variable.location_list, - current_variable.object_info, - &(stack_frame->unw_cursor), - (void *) stack_frame->frame_base, - &mc_model_checker->process(), process_index); - - switch(mc_get_location_type(&location)) { - case MC_LOCATION_TYPE_ADDRESS: - new_var.address = location.memory_location; - break; - case MC_LOCATION_TYPE_REGISTER: - default: + simgrid::dwarf::Location location = + simgrid::dwarf::resolve( + current_variable.location_list, + current_variable.object_info, + &(stack_frame->unw_cursor), + (void *) stack_frame->frame_base, + &mc_model_checker->process(), process_index); + + if (!location.in_memory()) xbt_die("Cannot handle non-address variable"); - } + new_var.address = location.address(); } else { xbt_die("No address"); @@ -373,7 +384,7 @@ static std::vector MC_unwind_stack_frames(mc_unw_context_t s if (frame) { stack_frame.frame_name = frame->name; stack_frame.frame_base = - (unw_word_t) mc_find_frame_base(frame, frame->object_info, &c); + (unw_word_t) frame->frame_base(c); } else { stack_frame.frame_base = 0; stack_frame.frame_name = std::string(); @@ -463,7 +474,7 @@ static std::vector MC_take_snapshot_ignore() static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) { - xbt_assert(snapshot->process); + xbt_assert(snapshot->process()); // Copy the memory: for (auto const& region : mc_model_checker->process().ignored_regions()) { @@ -471,7 +482,7 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) ignored_data.start = (void*)region.addr; ignored_data.data.resize(region.size); // TODO, we should do this once per privatization segment: - snapshot->process->read_bytes( + 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)); @@ -479,7 +490,7 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) // Zero the memory: for(auto const& region : mc_model_checker->process().ignored_regions()) { - snapshot->process->clear_bytes(remote(region.addr), region.size); + snapshot->process()->clear_bytes(remote(region.addr), region.size); } } @@ -487,7 +498,7 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) static void MC_snapshot_ignore_restore(mc_snapshot_t snapshot) { for (auto const& ignored_data : snapshot->ignored_data) - snapshot->process->write_bytes( + snapshot->process()->write_bytes( ignored_data.data.data(), ignored_data.data.size(), remote(ignored_data.start)); } @@ -535,8 +546,10 @@ static std::vector MC_get_current_fds(pid_t pid) } link[res] = '\0'; +#ifdef HAVE_SMPI if(smpi_is_privatisation_file(link)) continue; +#endif // This is (probably) the DIR* we are reading: // TODO, read all the file entries at once and close the DIR.* @@ -575,9 +588,8 @@ mc_snapshot_t MC_take_snapshot(int num_state) simgrid::mc::Process* mc_process = &mc_model_checker->process(); - mc_snapshot_t snapshot = new simgrid::mc::Snapshot(); + mc_snapshot_t snapshot = new simgrid::mc::Snapshot(mc_process); - snapshot->process = mc_process; snapshot->num_state = num_state; smx_process_t process; @@ -589,15 +601,19 @@ mc_snapshot_t MC_take_snapshot(int num_state) if (_sg_mc_snapshot_fds) snapshot->current_fds = MC_get_current_fds(process->pid); + 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 */ MC_get_memory_regions(mc_process, snapshot); + if (use_soft_dirty) + mc_process->reset_soft_dirty(); snapshot->to_ignore = MC_take_snapshot_ignore(); if (_sg_mc_visited > 0 || strcmp(_sg_mc_property_file, "")) { snapshot->stacks = MC_take_snapshot_stacks(&snapshot); - if (_sg_mc_hash && !snapshot->stacks.empty()) { + if (_sg_mc_hash) { snapshot->hash = simgrid::mc::hash(*snapshot); } else { snapshot->hash = 0; @@ -607,6 +623,8 @@ mc_snapshot_t MC_take_snapshot(int num_state) } MC_snapshot_ignore_restore(snapshot); + if (use_soft_dirty) + mc_model_checker->parent_snapshot_ = snapshot; return snapshot; } @@ -657,11 +675,16 @@ void MC_restore_snapshot_fds(mc_snapshot_t snapshot) void MC_restore_snapshot(mc_snapshot_t snapshot) { XBT_DEBUG("Restore snapshot %i", snapshot->num_state); + const bool use_soft_dirty = _sg_mc_sparse_checkpoint && _sg_mc_soft_dirty; MC_restore_snapshot_regions(snapshot); if (_sg_mc_snapshot_fds) MC_restore_snapshot_fds(snapshot); + if (use_soft_dirty) + mc_model_checker->process().reset_soft_dirty(); MC_snapshot_ignore_restore(snapshot); mc_model_checker->process().cache_flags = 0; + if (use_soft_dirty) + mc_model_checker->parent_snapshot_ = snapshot; } mc_snapshot_t simcall_HANDLER_mc_snapshot(smx_simcall_t simcall)