From: Frederic Suter Date: Fri, 26 Feb 2016 11:06:26 +0000 (+0100) Subject: Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid X-Git-Tag: v3_13~647^2~17 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/7f6f97c1c368c82eca073cc851218481d99b009b?hp=77537f25120f01141d7d9b669ad8178330531e00 Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid --- diff --git a/include/simgrid_config.h.in b/include/simgrid_config.h.in index 6628613222..0f4db4c84c 100644 --- a/include/simgrid_config.h.in +++ b/include/simgrid_config.h.in @@ -9,6 +9,8 @@ #ifndef SIMGRID_PUBLIC_CONFIG_H #define SIMGRID_PUBLIC_CONFIG_H +/* This file should only contain public declarations, mainly the definitions of SimGrid modules that were compiled in */ + /** Define the version numbers of the used header files. sg_version() can be used to retrieve the version of the dynamic library. But actually, if these numbers don't match, SimGrid refuses to start (so you shouldn't have to care about sg_version() yourself) */ @@ -36,19 +38,16 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@ + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_TIME_H @HAVE_SYS_TIME_H@ - /* Whether mallocators were enabled in ccmake or not. */ #define MALLOCATOR_COMPILED_IN @MALLOCATOR_IS_WANTED@ /* Define if xbt contexts are based on our threads implementation or not */ #cmakedefine HAVE_THREAD_CONTEXTS @HAVE_THREAD_CONTEXTS@ -/* Jedule output */ -#cmakedefine HAVE_JEDULE @HAVE_JEDULE@ - /* Tracking of latency bound */ #cmakedefine HAVE_LATENCY_BOUND_TRACKING @HAVE_LATENCY_BOUND_TRACKING@ @@ -57,11 +56,12 @@ /* Define to 1 if mmalloc is compiled in. */ #cmakedefine HAVE_MMALLOC @HAVE_MMALLOC@ -/* If Model-Checking support was requested */ -#cmakedefine HAVE_MC @HAVE_MC@ -#cmakedefine SIMGRID_HAVE_LIBSIG @SIMGRID_HAVE_LIBSIG@ +#cmakedefine HAVE_JEDULE @HAVE_JEDULE@ /* Was Jedule compiled in? */ +#cmakedefine HAVE_MC @HAVE_MC@ /* Was the model-checking compiled in? */ +#cmakedefine HAVE_NS3 @HAVE_NS3@ /* Was the NS3 support compiled in? */ +#cmakedefine HAVE_LUA @HAVE_LUA@ /* Was the Lua support compiled in? */ -#cmakedefine HAVE_VASPRINTF @HAVE_VASPRINTF@ +#cmakedefine SIMGRID_HAVE_LIBSIG @SIMGRID_HAVE_LIBSIG@ #endif /* SIMGRID_PUBLIC_CONFIG_H */ diff --git a/src/mc/ModelChecker.cpp b/src/mc/ModelChecker.cpp index 15d5d835fc..1bbf9e6440 100644 --- a/src/mc/ModelChecker.cpp +++ b/src/mc/ModelChecker.cpp @@ -277,7 +277,7 @@ bool ModelChecker::handle_message(char* buffer, ssize_t size) case MC_MESSAGE_ASSERTION_FAILED: MC_report_assertion_error(); - ::exit(SIMGRID_MC_EXIT_SAFETY); + this->exit(SIMGRID_MC_EXIT_SAFETY); break; default: @@ -287,6 +287,15 @@ bool ModelChecker::handle_message(char* buffer, ssize_t size) return true; } +/** Terminate the model-checker aplication */ +void ModelChecker::exit(int status) +{ + // TODO, terminate the model checker politely instead of exiting rudel + if (process().running()) + kill(process().pid(), SIGKILL); + ::exit(status); +} + bool ModelChecker::handle_events() { char buffer[MC_MESSAGE_LENGTH]; @@ -384,7 +393,7 @@ void ModelChecker::handle_waitpid() xbt_die("Could not get exit status"); if (WIFSIGNALED(status)) { MC_report_crash(status); - ::exit(SIMGRID_MC_EXIT_PROGRAM_CRASH); + mc_model_checker->exit(SIMGRID_MC_EXIT_PROGRAM_CRASH); } } diff --git a/src/mc/ModelChecker.hpp b/src/mc/ModelChecker.hpp index 7f770c3c82..cd5021bb3c 100644 --- a/src/mc/ModelChecker.hpp +++ b/src/mc/ModelChecker.hpp @@ -70,6 +70,7 @@ public: { mc_model_checker->wait_client(mc_model_checker->process()); } + void exit(int status); private: void setup_ignore(); bool handle_message(char* buffer, ssize_t size); diff --git a/src/mc/Type.hpp b/src/mc/Type.hpp index 819cf81b6e..f94d944291 100644 --- a/src/mc/Type.hpp +++ b/src/mc/Type.hpp @@ -24,73 +24,75 @@ namespace mc { */ class Member { public: - Member() : inheritance(false), byte_size(0), type_id(0) {} + Member() {} - bool inheritance; + /** Whether this member represent some inherited part of the object */ + bool inheritance = false; + + /** Name of the member (if any) */ std::string name; + + /** DWARF location expression for locating the location of the member */ simgrid::dwarf::DwarfExpression location_expression; - std::size_t byte_size; // Do we really need this? - unsigned type_id; - simgrid::mc::Type* type; + std::size_t byte_size = 0; // Do we really need this? + + unsigned type_id = 0; + simgrid::mc::Type* type = nullptr; + + /** Whether the member is at a fixed offset from the base address */ bool has_offset_location() const { + // Recognize the expression `DW_OP_plus_uconst(offset)`: return location_expression.size() == 1 && location_expression[0].atom == DW_OP_plus_uconst; } - // TODO, check if this shortcut is really necessary + /** Get the offset of the member + * + * This is only valid is the member is at a fixed offset from the base. + * This is often the case (for C types, C++ type without virtual + * inheritance). + * + * If the location is more complex, the location expression has + * to be evaluated (which might need accessing the memory). + */ int offset() const { xbt_assert(this->has_offset_location()); return this->location_expression[0].number; } + /** Set the location of the member as a fixed offset */ void offset(int new_offset) { + // Set the expression to be `DW_OP_plus_uconst(offset)`: Dwarf_Op op; op.atom = DW_OP_plus_uconst; op.number = new_offset; this->location_expression = { op }; } + }; /** A type in the model-checked program */ class Type { public: - Type(); - Type(Type const& type) = default; - Type& operator=(Type const&) = default; - Type(Type&& type) = default; - Type& operator=(Type&&) = default; + Type() {} /** The DWARF TAG of the type (e.g. DW_TAG_array_type) */ - int type; - unsigned id; /* Offset in the section (in hexadecimal form) */ + int type = 0; + unsigned id = 0; /* Offset in the section (in hexadecimal form) */ std::string name; /* Name of the type */ - int byte_size; /* Size in bytes */ - int element_count; /* Number of elements for array type */ - unsigned type_id; /* DW_AT_type id */ + int byte_size = 0; /* Size in bytes */ + int element_count = 0; /* Number of elements for array type */ + unsigned type_id = 0; /* DW_AT_type id */ std::vector members; /* if DW_TAG_structure_type, DW_TAG_class_type, DW_TAG_union_type*/ - int is_pointer_type; - simgrid::mc::Type* subtype; // DW_AT_type - simgrid::mc::Type* full_type; // The same (but more complete) type + simgrid::mc::Type* subtype = nullptr; // DW_AT_type + simgrid::mc::Type* full_type = nullptr; // The same (but more complete) type }; -inline -Type::Type() -{ - this->type = 0; - this->id = 0; - this->byte_size = 0; - this->element_count = 0; - this->is_pointer_type = 0; - this->type_id = 0; - this->subtype = nullptr; - this->full_type = nullptr; -} - } } diff --git a/src/mc/Variable.hpp b/src/mc/Variable.hpp index 5ca55ab08c..5b82b6cebd 100644 --- a/src/mc/Variable.hpp +++ b/src/mc/Variable.hpp @@ -20,34 +20,19 @@ namespace mc { /** A variable (global or local) in the model-checked program */ class Variable { public: - Variable(); - - unsigned dwarf_offset; /* Global offset of the field. */ - int global; + Variable() {} + unsigned dwarf_offset = 0; /* Global offset of the field. */ + int global = 0; std::string name; - unsigned type_id; - simgrid::mc::Type* type; - + unsigned type_id = 0; + simgrid::mc::Type* type = nullptr; // Use either of: simgrid::dwarf::LocationList location_list; - void* address; - - size_t start_scope; - simgrid::mc::ObjectInformation* object_info; + void* address = nullptr; + size_t start_scope = 0; + simgrid::mc::ObjectInformation* object_info = nullptr; }; -inline -Variable::Variable() -{ - this->dwarf_offset = 0; - this->global = 0; - this->type = nullptr; - this->type_id = 0; - this->address = nullptr; - this->start_scope = 0; - this->object_info = nullptr; -} - } } diff --git a/src/mc/mc_checkpoint.cpp b/src/mc/mc_checkpoint.cpp index 776842a430..cf124defcd 100644 --- a/src/mc/mc_checkpoint.cpp +++ b/src/mc/mc_checkpoint.cpp @@ -47,6 +47,11 @@ extern "C" { XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc, "Logging specific to mc_checkpoint"); +} + +namespace simgrid { +namespace mc { + /************************************ Free functions **************************************/ /*****************************************************************************************/ @@ -54,7 +59,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc, * * @param reg Target region */ -static void MC_region_restore(mc_mem_region_t region) +static void restore(mc_mem_region_t region) { switch(region->storage_type()) { case simgrid::mc::StorageType::NoData: @@ -73,16 +78,11 @@ static void MC_region_restore(mc_mem_region_t region) case simgrid::mc::StorageType::Privatized: for (auto& p : region->privatized_data()) - MC_region_restore(&p); + restore(&p); break; } } -} - -namespace simgrid { -namespace mc { - #ifdef HAVE_SMPI RegionSnapshot privatized_region( RegionType region_type, void *start_addr, void* permanent_addr, @@ -118,12 +118,8 @@ RegionSnapshot privatized_region( } #endif -} -} - -extern "C" { - -static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, +static +void add_region(int index, mc_snapshot_t snapshot, simgrid::mc::RegionType type, simgrid::mc::ObjectInformation* object_info, void *start_addr, void* permanent_addr, @@ -156,13 +152,13 @@ static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, return; } -static void MC_get_memory_regions(simgrid::mc::Process* process, mc_snapshot_t snapshot) +static void get_memory_regions(simgrid::mc::Process* process, mc_snapshot_t snapshot) { const size_t n = process->object_infos.size(); snapshot->snapshot_regions.resize(n + 1); int i = 0; for (auto const& object_info : process->object_infos) { - MC_snapshot_add_region(i, snapshot, simgrid::mc::RegionType::Data, + 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); @@ -173,7 +169,7 @@ static void MC_get_memory_regions(simgrid::mc::Process* process, mc_snapshot_t s void *start_heap = heap->base; void *end_heap = heap->breakval; - MC_snapshot_add_region(n, snapshot, simgrid::mc::RegionType::Heap, NULL, + add_region(n, snapshot, simgrid::mc::RegionType::Heap, NULL, start_heap, start_heap, (char *) end_heap - (char *) start_heap); snapshot->heap_bytes_used = mmalloc_get_bytes_used_remote( @@ -197,7 +193,7 @@ 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( +void find_object_address( std::vector const& maps, simgrid::mc::ObjectInformation* result) { @@ -264,7 +260,7 @@ 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, +static bool valid_variable(simgrid::mc::Variable* var, simgrid::mc::Frame* scope, const void *ip) { @@ -275,7 +271,7 @@ static bool mc_valid_variable(simgrid::mc::Variable* var, return true; } -static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, +static void fill_local_variables_values(mc_stack_frame_t stack_frame, simgrid::mc::Frame* scope, int process_index, std::vector& result) @@ -288,7 +284,7 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, for(simgrid::mc::Variable& current_variable : scope->variables) { - if (!mc_valid_variable(¤t_variable, scope, (void *) stack_frame->ip)) + if (!valid_variable(¤t_variable, scope, (void *) stack_frame->ip)) continue; int region_type; @@ -330,26 +326,20 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, // Recursive processing of nested scopes: for(simgrid::mc::Frame& nested_scope : scope->scopes) - mc_fill_local_variables_values( + fill_local_variables_values( stack_frame, &nested_scope, process_index, result); } -static std::vector MC_get_local_variables_values( +static std::vector get_local_variables_values( std::vector& stack_frames, int process_index) { std::vector variables; for (s_mc_stack_frame_t& stack_frame : stack_frames) - mc_fill_local_variables_values(&stack_frame, stack_frame.frame, process_index, variables); + fill_local_variables_values(&stack_frame, stack_frame.frame, process_index, variables); return std::move(variables); } -static void MC_stack_frame_free_voipd(void *s) -{ - mc_stack_frame_t stack_frame = *(mc_stack_frame_t *) s; - delete(stack_frame); -} - -static std::vector MC_unwind_stack_frames(mc_unw_context_t stack_context) +static std::vector unwind_stack_frames(mc_unw_context_t stack_context) { simgrid::mc::Process* process = &mc_model_checker->process(); std::vector result; @@ -413,7 +403,7 @@ static std::vector MC_unwind_stack_frames(mc_unw_context_t s return std::move(result); }; -static std::vector MC_take_snapshot_stacks(mc_snapshot_t * snapshot) +static std::vector take_snapshot_stacks(mc_snapshot_t * snapshot) { std::vector res; @@ -429,8 +419,8 @@ static std::vector MC_take_snapshot_stacks(mc_snapshot_t &context) < 0) { xbt_die("Could not initialise the libunwind context."); } - st.stack_frames = MC_unwind_stack_frames(&st.context); - st.local_variables = MC_get_local_variables_values(st.stack_frames, stack.process_index); + st.stack_frames = unwind_stack_frames(&st.context); + st.local_variables = get_local_variables_values(st.stack_frames, stack.process_index); st.process_index = stack.process_index; unw_word_t sp = st.stack_frames[0].sp; @@ -446,7 +436,7 @@ static std::vector MC_take_snapshot_stacks(mc_snapshot_t } -static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) +static void snapshot_handle_ignore(mc_snapshot_t snapshot) { xbt_assert(snapshot->process()); @@ -469,7 +459,7 @@ static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot) } -static void MC_snapshot_ignore_restore(mc_snapshot_t snapshot) +static void snapshot_ignore_restore(mc_snapshot_t snapshot) { for (auto const& ignored_data : snapshot->ignored_data) snapshot->process()->write_bytes( @@ -477,7 +467,7 @@ static void MC_snapshot_ignore_restore(mc_snapshot_t snapshot) remote(ignored_data.start)); } -static std::vector MC_get_current_fds(pid_t pid) +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]; @@ -556,7 +546,7 @@ static std::vector MC_get_current_fds(pid_t pid) return std::move(fds); } -mc_snapshot_t MC_take_snapshot(int num_state) +mc_snapshot_t take_snapshot(int num_state) { XBT_DEBUG("Taking snapshot %i", num_state); @@ -570,15 +560,15 @@ mc_snapshot_t MC_take_snapshot(int num_state) MC_EACH_SIMIX_PROCESS(process, snapshot->enabled_processes.insert(process->pid)); - MC_snapshot_handle_ignore(snapshot); + snapshot_handle_ignore(snapshot); if (_sg_mc_snapshot_fds) - snapshot->current_fds = MC_get_current_fds(process->pid); + snapshot->current_fds = 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); + get_memory_regions(mc_process, snapshot); if (use_soft_dirty) mc_process->reset_soft_dirty(); @@ -586,7 +576,7 @@ mc_snapshot_t MC_take_snapshot(int num_state) if (_sg_mc_visited > 0 || strcmp(_sg_mc_property_file, "")) { snapshot->stacks = - MC_take_snapshot_stacks(&snapshot); + take_snapshot_stacks(&snapshot); if (_sg_mc_hash) { snapshot->hash = simgrid::mc::hash(*snapshot); } else { @@ -596,19 +586,19 @@ mc_snapshot_t MC_take_snapshot(int num_state) snapshot->hash = 0; } - MC_snapshot_ignore_restore(snapshot); + snapshot_ignore_restore(snapshot); if (use_soft_dirty) mc_model_checker->parent_snapshot_ = snapshot; return snapshot; } static inline -void MC_restore_snapshot_regions(mc_snapshot_t snapshot) +void restore_snapshot_regions(mc_snapshot_t snapshot) { for(std::unique_ptr const& region : snapshot->snapshot_regions) { // For privatized, variables we decided it was not necessary to take the snapshot: if (region) - MC_region_restore(region.get()); + restore(region.get()); } #ifdef HAVE_SMPI @@ -624,7 +614,7 @@ void MC_restore_snapshot_regions(mc_snapshot_t snapshot) } static inline -void MC_restore_snapshot_fds(mc_snapshot_t snapshot) +void restore_snapshot_fds(mc_snapshot_t snapshot) { if (mc_mode == MC_MODE_SERVER) xbt_die("FD snapshot not implemented in client/server mode."); @@ -644,24 +634,26 @@ void MC_restore_snapshot_fds(mc_snapshot_t snapshot) } } -void MC_restore_snapshot(mc_snapshot_t snapshot) +void 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); + restore_snapshot_regions(snapshot); if (_sg_mc_snapshot_fds) - MC_restore_snapshot_fds(snapshot); + restore_snapshot_fds(snapshot); if (use_soft_dirty) mc_model_checker->process().reset_soft_dirty(); - MC_snapshot_ignore_restore(snapshot); + 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) -{ - return MC_take_snapshot(1); +} } +extern "C" +mc_snapshot_t simcall_HANDLER_mc_snapshot(smx_simcall_t simcall) +{ + return simgrid::mc::take_snapshot(1); } diff --git a/src/mc/mc_comm_determinism.cpp b/src/mc/mc_comm_determinism.cpp index 9525f92664..22b442b9ad 100644 --- a/src/mc/mc_comm_determinism.cpp +++ b/src/mc/mc_comm_determinism.cpp @@ -145,7 +145,7 @@ static void deterministic_comm_pattern(int process, mc_comm_pattern_t comm, int xbt_free(initial_global_state->send_diff); initial_global_state->send_diff = NULL; MC_print_statistics(mc_stats); - exit(SIMGRID_MC_EXIT_NON_DETERMINISM); + mc_model_checker->exit(SIMGRID_MC_EXIT_NON_DETERMINISM); }else if(_sg_mc_comms_determinism && (!initial_global_state->send_deterministic && !initial_global_state->recv_deterministic)) { XBT_INFO("****************************************************"); XBT_INFO("***** Non-deterministic communications pattern *****"); @@ -157,7 +157,7 @@ static void deterministic_comm_pattern(int process, mc_comm_pattern_t comm, int xbt_free(initial_global_state->recv_diff); initial_global_state->recv_diff = NULL; MC_print_statistics(mc_stats); - exit(SIMGRID_MC_EXIT_NON_DETERMINISM); + mc_model_checker->exit(SIMGRID_MC_EXIT_NON_DETERMINISM); } } } @@ -483,7 +483,7 @@ int MC_modelcheck_comm_determinism(void) MC_pre_modelcheck_comm_determinism(); initial_global_state = xbt_new0(s_mc_global_t, 1); - initial_global_state->snapshot = MC_take_snapshot(0); + initial_global_state->snapshot = simgrid::mc::take_snapshot(0); initial_global_state->initial_communications_pattern_done = 0; initial_global_state->recv_deterministic = 1; initial_global_state->send_deterministic = 1; diff --git a/src/mc/mc_dwarf.cpp b/src/mc/mc_dwarf.cpp index c0cac6fe0d..740506a59a 100644 --- a/src/mc/mc_dwarf.cpp +++ b/src/mc/mc_dwarf.cpp @@ -666,7 +666,6 @@ static simgrid::mc::Type MC_dwarf_die_to_type( case DW_TAG_pointer_type: case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: - type.is_pointer_type = 1; break; case DW_TAG_structure_type: @@ -1150,7 +1149,7 @@ std::shared_ptr MC_find_object_info( std::shared_ptr result = std::make_shared(); result->file_name = name; - MC_find_object_address(maps, result.get()); + simgrid::mc::find_object_address(maps, result.get()); MC_dwarf_get_variables(result.get()); MC_post_process_variables(result.get()); MC_post_process_types(result.get()); diff --git a/src/mc/mc_global.cpp b/src/mc/mc_global.cpp index 76a2af2cfa..868329caea 100644 --- a/src/mc/mc_global.cpp +++ b/src/mc/mc_global.cpp @@ -202,7 +202,7 @@ void MC_replay(xbt_fifo_t stack) start_item = xbt_fifo_get_first_item(stack); state = (mc_state_t)xbt_fifo_get_item_content(start_item); if(state->system_state){ - MC_restore_snapshot(state->system_state); + simgrid::mc::restore_snapshot(state->system_state); if(_sg_mc_comms_determinism || _sg_mc_send_determinism) MC_restore_communications_pattern(state); return; @@ -211,7 +211,7 @@ void MC_replay(xbt_fifo_t stack) /* Restore the initial state */ - MC_restore_snapshot(initial_global_state->snapshot); + simgrid::mc::restore_snapshot(initial_global_state->snapshot); /* At the moment of taking the snapshot the raw heap was set, so restoring * it will set it back again, we have to unset it to continue */ @@ -290,13 +290,13 @@ void MC_replay_liveness(xbt_fifo_t stack) item = xbt_fifo_get_first_item(stack); pair = (mc_pair_t) xbt_fifo_get_item_content(item); if(pair->graph_state->system_state){ - MC_restore_snapshot(pair->graph_state->system_state); + simgrid::mc::restore_snapshot(pair->graph_state->system_state); return; } } /* Restore the initial state */ - MC_restore_snapshot(initial_global_state->snapshot); + simgrid::mc::restore_snapshot(initial_global_state->snapshot); /* Traverse the stack from the initial state and re-execute the transitions */ for (item = xbt_fifo_get_last_item(stack); diff --git a/src/mc/mc_liveness.cpp b/src/mc/mc_liveness.cpp index 2bdc1a7105..bb3fadc375 100644 --- a/src/mc/mc_liveness.cpp +++ b/src/mc/mc_liveness.cpp @@ -180,7 +180,7 @@ static void MC_pre_modelcheck_liveness(void) if(_sg_mc_visited > 0) visited_pairs = xbt_dynar_new(sizeof(mc_visited_pair_t), NULL); - initial_global_state->snapshot = MC_take_snapshot(0); + initial_global_state->snapshot = simgrid::mc::take_snapshot(0); initial_global_state->prev_pair = 0; unsigned int cursor = 0; diff --git a/src/mc/mc_private.h b/src/mc/mc_private.h index 17982ed2c0..a5ded6a4a1 100644 --- a/src/mc/mc_private.h +++ b/src/mc/mc_private.h @@ -103,9 +103,15 @@ XBT_PRIVATE void MC_report_crash(int status); #ifdef __cplusplus -XBT_PRIVATE void MC_find_object_address( +namespace simgrid { +namespace mc { + +XBT_PRIVATE void find_object_address( std::vector const& maps, simgrid::mc::ObjectInformation* result); +} +} + #endif SG_END_DECL() diff --git a/src/mc/mc_safety.cpp b/src/mc/mc_safety.cpp index 1642b3add9..160fea3c88 100644 --- a/src/mc/mc_safety.cpp +++ b/src/mc/mc_safety.cpp @@ -286,5 +286,5 @@ static void MC_modelcheck_safety_init(void) /* Save the initial state */ initial_global_state = xbt_new0(s_mc_global_t, 1); - initial_global_state->snapshot = MC_take_snapshot(0); + initial_global_state->snapshot = simgrid::mc::take_snapshot(0); } diff --git a/src/mc/mc_snapshot.h b/src/mc/mc_snapshot.h index 8960b450a2..47bfc14d51 100644 --- a/src/mc/mc_snapshot.h +++ b/src/mc/mc_snapshot.h @@ -177,8 +177,22 @@ mc_mem_region_t mc_get_region_hinted(void* addr, mc_snapshot_t snapshot, int pro static const void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot); -XBT_PRIVATE mc_snapshot_t MC_take_snapshot(int num_state); -XBT_PRIVATE void MC_restore_snapshot(mc_snapshot_t); +} + +#ifdef __cplusplus + +namespace simgrid { +namespace mc { + +XBT_PRIVATE mc_snapshot_t take_snapshot(int num_state); +XBT_PRIVATE void restore_snapshot(mc_snapshot_t); + +} +} + +#endif + +extern "C" { XBT_PRIVATE void mc_restore_page_snapshot_region( simgrid::mc::Process* process, diff --git a/src/mc/mc_state.cpp b/src/mc/mc_state.cpp index e0e61217b1..3720ff795d 100644 --- a/src/mc/mc_state.cpp +++ b/src/mc/mc_state.cpp @@ -37,7 +37,7 @@ mc_state_t MC_state_new() state->incomplete_comm_pattern = NULL; /* Stateful model checking */ if((_sg_mc_checkpoint > 0 && (mc_stats->expanded_states % _sg_mc_checkpoint == 0)) || _sg_mc_termination){ - state->system_state = MC_take_snapshot(state->num); + state->system_state = simgrid::mc::take_snapshot(state->num); if(_sg_mc_comms_determinism || _sg_mc_send_determinism){ MC_state_copy_incomplete_communications_pattern(state); MC_state_copy_index_communications_pattern(state); diff --git a/src/mc/mc_visited.cpp b/src/mc/mc_visited.cpp index 459db40418..7634c31925 100644 --- a/src/mc/mc_visited.cpp +++ b/src/mc/mc_visited.cpp @@ -64,7 +64,7 @@ static mc_visited_state_t visited_state_new() new_state->nb_processes = xbt_dynar_length( mc_model_checker->process().smx_process_infos); - new_state->system_state = MC_take_snapshot(mc_stats->expanded_states); + new_state->system_state = simgrid::mc::take_snapshot(mc_stats->expanded_states); new_state->num = mc_stats->expanded_states; new_state->other_num = -1; return new_state; @@ -77,7 +77,7 @@ mc_visited_pair_t MC_visited_pair_new(int pair_num, xbt_automaton_state_t automa pair = xbt_new0(s_mc_visited_pair_t, 1); pair->graph_state = graph_state; if(pair->graph_state->system_state == NULL) - pair->graph_state->system_state = MC_take_snapshot(pair_num); + pair->graph_state->system_state = simgrid::mc::take_snapshot(pair_num); pair->heap_bytes_used = mmalloc_get_bytes_used_remote( process->get_heap()->heaplimit, process->get_malloc_info()); diff --git a/src/mc/simgrid_mc.cpp b/src/mc/simgrid_mc.cpp index e0f61709de..f6e998d825 100644 --- a/src/mc/simgrid_mc.cpp +++ b/src/mc/simgrid_mc.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include #include @@ -39,7 +41,30 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_main, mc, "Entry point for simgrid-mc"); -static int do_child(int socket, char** argv) +/** Execute some code in a forked process */ +template +static inline +pid_t do_fork(F f) +{ + pid_t pid = fork(); + if (pid < 0) + throw new std::system_error(errno, std::generic_category()); + if (pid != 0) + return pid; + + // Child-process: + try { + f(); + std::exit(EXIT_SUCCESS); + } + catch(...) { + // The callback should catch exceptions: + abort(); + } +} + +static +int exec_model_checked(int socket, char** argv) { XBT_DEBUG("Inside the child process PID=%i", (int) getpid()); @@ -47,36 +72,25 @@ static int do_child(int socket, char** argv) // Make sure we do not outlive our parent: sigset_t mask; sigemptyset (&mask); - if (sigprocmask(SIG_SETMASK, &mask, nullptr) < 0) { - std::perror ("sigprocmask"); - return SIMGRID_MC_EXIT_ERROR; - } - - if (prctl(PR_SET_PDEATHSIG, SIGHUP) != 0) { - std::perror("simgrid-mc"); - return SIMGRID_MC_EXIT_ERROR; - } + if (sigprocmask(SIG_SETMASK, &mask, nullptr) < 0) + throw new std::system_error(errno, std::generic_category(), "sigprocmask"); + if (prctl(PR_SET_PDEATHSIG, SIGHUP) != 0) + throw new std::system_error(errno, std::generic_category(), "PR_SET_PDEATHSIG"); #endif int res; // Remove CLOEXEC in order to pass the socket to the exec-ed program: int fdflags = fcntl(socket, F_GETFD, 0); - if (fdflags == -1) { - std::perror("simgrid-mc"); - return SIMGRID_MC_EXIT_ERROR; - } - if (fcntl(socket, F_SETFD, fdflags & ~FD_CLOEXEC) == -1) { - std::perror("simgrid-mc"); - return SIMGRID_MC_EXIT_ERROR; - } - - XBT_DEBUG("CLOEXEC removed on socket %i", socket); + if (fdflags == -1) + throw new std::system_error(errno, std::generic_category(), "F_GETFD"); + if (fcntl(socket, F_SETFD, fdflags & ~FD_CLOEXEC) == -1) + throw new std::system_error(errno, std::generic_category(), "Remove FD_CLOEXEC"); // Set environment: setenv(MC_ENV_VARIABLE, "1", 1); - // Disable lazy relocation in the model-ched process. + // Disable lazy relocation in the model-checked process. // We don't want the model-checked process to modify its .got.plt during // snapshot. setenv("LC_BIND_NOW", "1", 1); @@ -84,22 +98,74 @@ static int do_child(int socket, char** argv) char buffer[64]; res = std::snprintf(buffer, sizeof(buffer), "%i", socket); if ((size_t) res >= sizeof(buffer) || res == -1) - return SIMGRID_MC_EXIT_ERROR; + std::abort(); setenv(MC_ENV_SOCKET_FD, buffer, 1); execvp(argv[1], argv+1); - XBT_ERROR("Could not execute the child process"); - return SIMGRID_MC_EXIT_ERROR; + + XBT_ERROR("Could not run the model-checked program"); + // This is the value used by system() and popen() in this case: + return 127; } -static int do_parent(int socket, pid_t child) +static +std::pair create_model_checked(char** argv) +{ + // Create a AF_LOCAL socketpair used for exchanging messages + // bewteen the model-checker process (ourselves) and the model-checked + // process: + int res; + int sockets[2]; + res = socketpair(AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0, sockets); + if (res == -1) + throw new std::system_error(errno, std::generic_category(), "socketpair"); + + pid_t pid = do_fork([&] { + close(sockets[1]); + int res = exec_model_checked(sockets[0], argv); + XBT_DEBUG("Error in the child process creation"); + exit(res); + }); + + // Parent (model-checker): + close(sockets[0]); + return std::make_pair(pid, sockets[1]); +} + +static +char** argvdup(int argc, char** argv) +{ + char** argv_copy = xbt_new(char*, argc+1); + std::memcpy(argv_copy, argv, sizeof(char*) * argc); + argv_copy[argc] = NULL; + return argv_copy; +} + +int main(int argc, char** argv) { - XBT_DEBUG("Inside the parent process"); - if (mc_model_checker) - xbt_die("MC server already present"); try { + if (argc < 2) + xbt_die("Missing arguments.\n"); + + _sg_do_model_check = 1; + + // The initialisation function can touch argv. + // We need to keep the original parameters in order to pass them to the + // model-checked process so we make a copy of them: + int argc_copy = argc; + char** argv_copy = argvdup(argc, argv); + xbt_log_init(&argc_copy, argv_copy); + sg_config_init(&argc_copy, argv_copy); + + int sock; + pid_t model_checked_pid; + std::tie(model_checked_pid, sock) = create_model_checked(argv); + XBT_DEBUG("Inside the parent process"); + if (mc_model_checker) + xbt_die("MC server already present"); + mc_mode = MC_MODE_SERVER; - std::unique_ptr process(new simgrid::mc::Process(child, socket)); + std::unique_ptr process(new simgrid::mc::Process(model_checked_pid, sock)); process->privatized(sg_cfg_get_boolean("smpi/privatize_global_variables")); mc_model_checker = new simgrid::mc::ModelChecker(std::move(process)); mc_model_checker->start(); @@ -117,55 +183,8 @@ static int do_parent(int socket, pid_t child) XBT_ERROR("Exception: %s", e.what()); return SIMGRID_MC_EXIT_ERROR; } -} - -static char** argvdup(int argc, char** argv) -{ - char** argv_copy = xbt_new(char*, argc+1); - std::memcpy(argv_copy, argv, sizeof(char*) * argc); - argv_copy[argc] = NULL; - return argv_copy; -} - -int main(int argc, char** argv) -{ - _sg_do_model_check = 1; - - // We need to keep the original parameters in order to pass them to the - // model-checked process: - int argc_copy = argc; - char** argv_copy = argvdup(argc, argv); - xbt_log_init(&argc_copy, argv_copy); - sg_config_init(&argc_copy, argv_copy); - - if (argc < 2) - xbt_die("Missing arguments.\n"); - - // Create a AF_LOCAL socketpair: - int res; - - int sockets[2]; - res = socketpair(AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0, sockets); - if (res == -1) { - perror("simgrid-mc"); - return SIMGRID_MC_EXIT_ERROR; - } - - XBT_DEBUG("Created socketpair"); - - pid_t pid = fork(); - if (pid < 0) { - perror("simgrid-mc"); + catch(...) { + XBT_ERROR("Unknown exception"); return SIMGRID_MC_EXIT_ERROR; - } else if (pid == 0) { - close(sockets[1]); - int res = do_child(sockets[0], argv); - XBT_DEBUG("Error in the child process creation"); - return res; - } else { - close(sockets[0]); - return do_parent(sockets[1], pid); } - - return 0; } diff --git a/src/portable.h b/src/portable.h index 570a599076..487a6f10f3 100644 --- a/src/portable.h +++ b/src/portable.h @@ -10,7 +10,9 @@ #ifndef SIMGRID_PORTABLE_H #define SIMGRID_PORTABLE_H -#include "src/internal_config.h" +#include "simgrid_config.h" /* what was compiled in? */ +#include "src/internal_config.h" /* some information about the environment */ + #include "xbt/base.h" #include "xbt/misc.h" #ifdef _XBT_WIN32 diff --git a/src/simgrid/sg_config.c b/src/simgrid/sg_config.c index f3939f5f10..187e8aea8d 100644 --- a/src/simgrid/sg_config.c +++ b/src/simgrid/sg_config.c @@ -18,6 +18,7 @@ #include "instr/instr_interface.h" #include "simgrid/simix.h" #include "simgrid/sg_config.h" +#include "simgrid_config.h" /* what was compiled in? */ #ifdef HAVE_SMPI #include "smpi/smpi_interface.h" #endif diff --git a/src/surf/surf_interface.cpp b/src/surf/surf_interface.cpp index 4537df7b67..6f02607a9d 100644 --- a/src/surf/surf_interface.cpp +++ b/src/surf/surf_interface.cpp @@ -4,6 +4,7 @@ /* 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 "src/portable.h" #include "surf_private.h" #include "surf_interface.hpp" #include "network_interface.hpp" @@ -16,7 +17,6 @@ #include "virtual_machine.hpp" #include "src/instr/instr_private.h" // TRACE_is_enabled(). FIXME: remove by subscribing tracing to the surf signals - XBT_LOG_NEW_CATEGORY(surf, "All SURF categories"); XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf, "Logging specific to SURF (kernel)"); @@ -266,12 +266,6 @@ int find_model_description(s_surf_model_description_t * table, return -1; } -static XBT_INLINE void routing_asr_prop_free(void *p) -{ - //xbt_dict_t elm = (xbt_dict_t) p; - //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster -} - static XBT_INLINE void surf_storage_free(void *r) { delete static_cast(r); @@ -318,7 +312,7 @@ void surf_init(int *argc, char **argv) sg_host_init(); XBT_DEBUG("Add routing levels"); - ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free); + ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib, NULL); XBT_DEBUG("Add SURF levels"); simgrid::surf::HostImpl::classInit(); diff --git a/src/xbt/log.c b/src/xbt/log.c index 6e0cfed2c3..76ecb58d60 100644 --- a/src/xbt/log.c +++ b/src/xbt/log.c @@ -11,7 +11,7 @@ #include /* snprintf */ #include /* snprintf */ -#include "src/portable.h" /* to get a working stdarg.h */ +#include "src/portable.h" #include "src/xbt_modinter.h" diff --git a/src/xbt/snprintf.c b/src/xbt/snprintf.c index 22a3aa894c..148a59301a 100644 --- a/src/xbt/snprintf.c +++ b/src/xbt/snprintf.c @@ -49,8 +49,8 @@ * http://www.ijs.si/software/snprintf/ */ -#include "xbt/sysdep.h" /* xbt_abort() */ -#include "simgrid_config.h" /* Do we need vasprintf? */ +#include "xbt/sysdep.h" /* xbt_abort() */ +#include "src/internal_config.h" /* Do we need vasprintf? */ #include #if !defined(HAVE_VASPRINTF) diff --git a/tools/cmake/src/internal_config.h.in b/tools/cmake/src/internal_config.h.in index 1f52559239..de04a60007 100644 --- a/tools/cmake/src/internal_config.h.in +++ b/tools/cmake/src/internal_config.h.in @@ -90,12 +90,6 @@ /* We have mmap and objdump to handle privatization */ #cmakedefine HAVE_PRIVATIZATION @HAVE_PRIVATIZATION@ -/* Indicates that we have NS3 support */ -#cmakedefine HAVE_NS3 @HAVE_NS3@ - -/* defines whether Lua bindings must be compiled or not */ -#cmakedefine HAVE_LUA @HAVE_LUA@ - /* Define to 1 if you have the `makecontext' function. */ #cmakedefine HAVE_MAKECONTEXT @HAVE_MAKECONTEXT@