X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/f60c6c67576ca97e84d781811f9076c18f183b11..d29ab72e79378eb7527238f5db164234f1c0cf8b:/src/mc/mc_private.h diff --git a/src/mc/mc_private.h b/src/mc/mc_private.h index 0de75609ec..4d2e916f8d 100644 --- a/src/mc/mc_private.h +++ b/src/mc/mc_private.h @@ -7,126 +7,51 @@ #ifndef MC_PRIVATE_H #define MC_PRIVATE_H +#include + #include "simgrid_config.h" #include +#include +#include #ifndef WIN32 #include #endif #include #include "mc/mc.h" +#include "mc_base.h" #include "mc/datatypes.h" #include "xbt/fifo.h" #include "xbt/config.h" +#include +#include + #include "xbt/function_types.h" #include "xbt/mmalloc.h" #include "../simix/smx_private.h" +#include "../xbt/mmalloc/mmprivate.h" #include "xbt/automaton.h" #include "xbt/hash.h" -#include "msg/msg.h" -#include "msg/datatypes.h" +#include #include "xbt/strbuff.h" #include "xbt/parmap.h" -typedef struct s_dw_frame s_dw_frame_t, *dw_frame_t; +#include "mc_forward.h" +#include "mc_protocol.h" + +SG_BEGIN_DECL() + typedef struct s_mc_function_index_item s_mc_function_index_item_t, *mc_function_index_item_t; -/****************************** Snapshots ***********************************/ - -#define NB_REGIONS 3 /* binary data (data + BSS) (type = 2), libsimgrid data (data + BSS) (type = 1), std_heap (type = 0)*/ - -typedef struct s_mc_mem_region{ - // Real address: - void *start_addr; - // Copy of the datra: - void *data; - // Size of the data region: - size_t size; -} s_mc_mem_region_t, *mc_mem_region_t; - -typedef struct s_mc_snapshot{ - size_t heap_bytes_used; - mc_mem_region_t regions[NB_REGIONS]; - int nb_processes; - mc_mem_region_t* privatization_regions; - int privatization_index; - size_t *stack_sizes; - xbt_dynar_t stacks; - xbt_dynar_t to_ignore; - uint64_t hash; -} s_mc_snapshot_t, *mc_snapshot_t; - -/** Information about a given stack frame - * - */ -typedef struct s_mc_stack_frame { - /** Instruction pointer */ - unw_word_t ip; - /** Stack pointer */ - unw_word_t sp; - unw_word_t frame_base; - dw_frame_t frame; - char* frame_name; - unw_cursor_t unw_cursor; -} s_mc_stack_frame_t, *mc_stack_frame_t; - -typedef struct s_mc_snapshot_stack{ - xbt_dynar_t local_variables; - void *stack_pointer; - void *real_address; - xbt_dynar_t stack_frames; // mc_stack_frame_t -}s_mc_snapshot_stack_t, *mc_snapshot_stack_t; - -typedef struct s_mc_global_t{ - mc_snapshot_t snapshot; - int raw_mem_set; - int prev_pair; - char *prev_req; - int initial_communications_pattern_done; - int comm_deterministic; - int send_deterministic; -}s_mc_global_t, *mc_global_t; - -typedef struct s_mc_checkpoint_ignore_region{ - void *addr; - size_t size; -}s_mc_checkpoint_ignore_region_t, *mc_checkpoint_ignore_region_t; - -mc_snapshot_t SIMIX_pre_mc_snapshot(smx_simcall_t simcall); -mc_snapshot_t MC_take_snapshot(int num_state); -void MC_restore_snapshot(mc_snapshot_t); -void MC_free_snapshot(mc_snapshot_t); - -/** \brief Translate a pointer from process address space to snapshot address space - * - * The address space contains snapshot of the main/application memory: - * this function finds the address in a given snaphot for a given - * real/application address. - * - * For read only memory regions and other regions which are not int the - * snapshot, the address is not changed. - * - * \param addr Application address - * \param snapshot The snapshot of interest (if NULL no translation is done) - * \return Translated address in the snapshot address space - * */ -void* mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot); +/********************************* MC Global **********************************/ -/** \brief Translate a pointer from the snapshot address space to the application address space +/** Initialisation of the model-checker * - * This is the inverse of mc_translate_address. - * - * \param addr Address in the snapshot address space - * \param snapsot Snapshot of interest (if NULL no translation is done) - * \return Translated address in the application address space + * @param pid PID of the target process + * @param socket FD for the communication socket **in server mode** (or -1 otherwise) */ -uintptr_t mc_untranslate_address(void* addr, mc_snapshot_t snapshot); - -extern xbt_dynar_t mc_checkpoint_ignore; +void MC_init_pid(pid_t pid, int socket); -/********************************* MC Global **********************************/ - -extern double *mc_time; extern FILE *dot_output; extern const char* colors[13]; extern xbt_parmap_t parmap; @@ -134,69 +59,21 @@ extern xbt_parmap_t parmap; extern int user_max_depth_reached; int MC_deadlock_check(void); -void MC_replay(xbt_fifo_t stack, int start); -void MC_replay_liveness(xbt_fifo_t stack, int all_stack); -void MC_wait_for_requests(void); +void MC_replay(xbt_fifo_t stack); +void MC_replay_liveness(xbt_fifo_t stack); void MC_show_deadlock(smx_simcall_t req); void MC_show_stack_safety(xbt_fifo_t stack); void MC_dump_stack_safety(xbt_fifo_t stack); -void MC_init(void); -int SIMIX_pre_mc_random(smx_simcall_t simcall, int min, int max); - - -/********************************* Requests ***********************************/ - -int MC_request_depend(smx_simcall_t req1, smx_simcall_t req2); -char* MC_request_to_string(smx_simcall_t req, int value); -unsigned int MC_request_testany_fail(smx_simcall_t req); -/*int MC_waitany_is_enabled_by_comm(smx_req_t req, unsigned int comm);*/ -int MC_request_is_visible(smx_simcall_t req); -int MC_request_is_enabled(smx_simcall_t req); -int MC_request_is_enabled_by_idx(smx_simcall_t req, unsigned int idx); -int MC_process_is_enabled(smx_process_t process); -char *MC_request_get_dot_output(smx_simcall_t req, int value); - - -/******************************** States **************************************/ - -/* Possible exploration status of a process in a state */ -typedef enum { - MC_NOT_INTERLEAVE=0, /* Do not interleave (do not execute) */ - MC_INTERLEAVE, /* Interleave the process (one or more request) */ - MC_MORE_INTERLEAVE, /* Interleave twice the process (for mc_random simcall) */ - MC_DONE /* Already interleaved */ -} e_mc_process_state_t; - -/* On every state, each process has an entry of the following type */ -typedef struct mc_procstate{ - e_mc_process_state_t state; /* Exploration control information */ - unsigned int interleave_count; /* Number of times that the process was - interleaved */ -} s_mc_procstate_t, *mc_procstate_t; - -/* An exploration state is composed of: */ -typedef struct mc_state { - unsigned long max_pid; /* Maximum pid at state's creation time */ - mc_procstate_t proc_status; /* State's exploration status by process */ - s_smx_action_t internal_comm; /* To be referenced by the internal_req */ - s_smx_simcall_t internal_req; /* Internal translation of request */ - s_smx_simcall_t executed_req; /* The executed request of the state */ - int req_num; /* The request number (in the case of a - multi-request like waitany ) */ - mc_snapshot_t system_state; /* Snapshot of system state */ - int num; -} s_mc_state_t, *mc_state_t; - -mc_state_t MC_state_new(void); -void MC_state_delete(mc_state_t state); -void MC_state_interleave_process(mc_state_t state, smx_process_t process); -unsigned int MC_state_interleave_size(mc_state_t state); -int MC_state_process_is_done(mc_state_t state, smx_process_t process); -void MC_state_set_executed_request(mc_state_t state, smx_simcall_t req, int value); -smx_simcall_t MC_state_get_executed_request(mc_state_t state, int *value); -smx_simcall_t MC_state_get_internal_request(mc_state_t state); -smx_simcall_t MC_state_get_request(mc_state_t state, int *value); -void MC_state_remove_interleave_process(mc_state_t state, smx_process_t process); +void MC_show_non_termination(void); + +/** Stack (of `mc_state_t`) representing the current position of the + * the MC in the exploration graph + * + * It is managed by its head (`xbt_fifo_shift` and `xbt_fifo_unshift`). + */ +extern xbt_fifo_t mc_stack; + +int get_search_interval(xbt_dynar_t list, void *ref, int *min, int *max); /****************************** Statistics ************************************/ @@ -212,66 +89,7 @@ typedef struct mc_stats { extern mc_stats_t mc_stats; -void MC_print_statistics(mc_stats_t); - - -/********************************** MEMORY ******************************/ -/* The possible memory modes for the modelchecker are standard and raw. */ -/* Normally the system should operate in std, for switching to raw mode */ -/* you must wrap the code between MC_SET_RAW_MODE and MC_UNSET_RAW_MODE */ - -extern void *std_heap; -extern void *raw_heap; - - -/* FIXME: Horrible hack! because the mmalloc library doesn't provide yet of */ -/* an API to query about the status of a heap, we simply call mmstats and */ -/* because I now how does structure looks like, then I redefine it here */ - -/* struct mstats { */ -/* size_t bytes_total; /\* Total size of the heap. *\/ */ -/* size_t chunks_used; /\* Chunks allocated by the user. *\/ */ -/* size_t bytes_used; /\* Byte total of user-allocated chunks. *\/ */ -/* size_t chunks_free; /\* Chunks in the free list. *\/ */ -/* size_t bytes_free; /\* Byte total of chunks in the free list. *\/ */ -/* }; */ - -#define MC_SET_RAW_MEM mmalloc_set_current_heap(raw_heap) -#define MC_UNSET_RAW_MEM mmalloc_set_current_heap(std_heap) - - -/******************************* MEMORY MAPPINGS ***************************/ -/* These functions and data structures implements a binary interface for */ -/* the proc maps ascii interface */ - -/* Each field is defined as documented in proc's manual page */ -typedef struct s_map_region { - - void *start_addr; /* Start address of the map */ - void *end_addr; /* End address of the map */ - int prot; /* Memory protection */ - int flags; /* Additional memory flags */ - void *offset; /* Offset in the file/whatever */ - char dev_major; /* Major of the device */ - char dev_minor; /* Minor of the device */ - unsigned long inode; /* Inode in the device */ - char *pathname; /* Path name of the mapped file */ - -} s_map_region_t; - -typedef struct s_memory_map { - - s_map_region_t *regions; /* Pointer to an array of regions */ - int mapsize; /* Number of regions in the memory */ - -} s_memory_map_t, *memory_map_t; - - -void MC_init_memory_map_info(void); -memory_map_t MC_get_memory_map(void); -void MC_free_memory_map(memory_map_t map); - -extern char *libsimgrid_path; +void MC_print_statistics(mc_stats_t stats); /********************************** Snapshot comparison **********************************/ @@ -279,8 +97,7 @@ typedef struct s_mc_comparison_times{ double nb_processes_comparison_time; double bytes_used_comparison_time; double stacks_sizes_comparison_time; - double binary_global_variables_comparison_time; - double libsimgrid_global_variables_comparison_time; + double global_variables_comparison_time; double heap_comparison_time; double stacks_comparison_time; }s_mc_comparison_times_t, *mc_comparison_times_t; @@ -289,255 +106,14 @@ extern __thread mc_comparison_times_t mc_comp_times; extern __thread double mc_snapshot_comparison_time; int snapshot_compare(void *state1, void *state2); -int SIMIX_pre_mc_compare_snapshots(smx_simcall_t simcall, mc_snapshot_t s1, mc_snapshot_t s2); void print_comparison_times(void); //#define MC_DEBUG 1 #define MC_VERBOSE 1 -/********************************** DPOR for safety property **************************************/ - -typedef enum { - e_mc_reduce_unset, - e_mc_reduce_none, - e_mc_reduce_dpor -} e_mc_reduce_t; - -extern e_mc_reduce_t mc_reduce_kind; -extern mc_global_t initial_state_safety; -extern xbt_fifo_t mc_stack_safety; -extern xbt_dict_t first_enabled_state; - -void MC_dpor_init(void); -void MC_dpor(void); - -typedef struct s_mc_visited_state{ - mc_snapshot_t system_state; - size_t heap_bytes_used; - int nb_processes; - int num; - int other_num; // dot_output for -}s_mc_visited_state_t, *mc_visited_state_t; - - -/********************************** Double-DFS for liveness property **************************************/ - -extern xbt_fifo_t mc_stack_liveness; -extern mc_global_t initial_state_liveness; -extern xbt_automaton_t _mc_property_automaton; -extern int compare; - -typedef struct s_mc_pair{ - int num; - int search_cycle; - mc_state_t graph_state; /* System state included */ - xbt_automaton_state_t automaton_state; - xbt_dynar_t atomic_propositions; - int requests; -}s_mc_pair_t, *mc_pair_t; - -typedef struct s_mc_visited_pair{ - int num; - int other_num; /* Dot output for */ - int acceptance_pair; - mc_state_t graph_state; /* System state included */ - xbt_automaton_state_t automaton_state; - xbt_dynar_t atomic_propositions; - size_t heap_bytes_used; - int nb_processes; - int acceptance_removed; - int visited_removed; -}s_mc_visited_pair_t, *mc_visited_pair_t; - -mc_pair_t MC_pair_new(void); -void MC_pair_delete(mc_pair_t); -void mc_pair_free_voidp(void *p); -mc_visited_pair_t MC_visited_pair_new(int pair_num, xbt_automaton_state_t automaton_state, xbt_dynar_t atomic_propositions); -void MC_visited_pair_delete(mc_visited_pair_t p); - -void MC_ddfs_init(void); -void MC_ddfs(void); -void MC_show_stack_liveness(xbt_fifo_t stack); -void MC_dump_stack_liveness(xbt_fifo_t stack); - - /********************************** Variables with DWARF **********************************/ -#define MC_OBJECT_INFO_EXECUTABLE 1 - -struct s_mc_object_info { - size_t flags; - char* file_name; - char *start_exec, *end_exec; // Executable segment - char *start_rw, *end_rw; // Read-write segment - char *start_ro, *end_ro; // read-only segment - xbt_dict_t subprograms; // xbt_dict_t - xbt_dynar_t global_variables; // xbt_dynar_t - xbt_dict_t types; // xbt_dict_t - xbt_dict_t full_types_by_name; // xbt_dict_t (full defined type only) - - // Here we sort the minimal information for an efficient (and cache-efficient) - // lookup of a function given an instruction pointer. - // The entries are sorted by low_pc and a binary search can be used to look them up. - xbt_dynar_t functions_index; -}; - -mc_object_info_t MC_new_object_info(void); -mc_object_info_t MC_find_object_info(memory_map_t maps, char* name, int executable); -void MC_free_object_info(mc_object_info_t* p); - -void MC_dwarf_get_variables(mc_object_info_t info); -void MC_dwarf_get_variables_libdw(mc_object_info_t info); -const char* MC_dwarf_attrname(int attr); -const char* MC_dwarf_tagname(int tag); - -dw_frame_t MC_find_function_by_ip(void* ip); -mc_object_info_t MC_ip_find_object_info(void* ip); - -extern mc_object_info_t mc_libsimgrid_info; -extern mc_object_info_t mc_binary_info; -extern mc_object_info_t mc_object_infos[2]; -extern size_t mc_object_infos_size; - void MC_find_object_address(memory_map_t maps, mc_object_info_t result); -void MC_post_process_types(mc_object_info_t info); - -// ***** Expressions - -/** \brief a DWARF expression with optional validity contraints */ -typedef struct s_mc_expression { - size_t size; - Dwarf_Op* ops; - // Optional validity: - void* lowpc, *highpc; -} s_mc_expression_t, *mc_expression_t; - -/** A location list (list of location expressions) */ -typedef struct s_mc_location_list { - size_t size; - mc_expression_t locations; -} s_mc_location_list_t, *mc_location_list_t; - -uintptr_t mc_dwarf_resolve_location(mc_expression_t expression, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot); -uintptr_t mc_dwarf_resolve_locations(mc_location_list_t locations, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot); - -void mc_dwarf_expression_clear(mc_expression_t expression); -void mc_dwarf_expression_init(mc_expression_t expression, size_t len, Dwarf_Op* ops); - -void mc_dwarf_location_list_clear(mc_location_list_t list); - -void mc_dwarf_location_list_init_from_expression(mc_location_list_t target, size_t len, Dwarf_Op* ops); -void mc_dwarf_location_list_init(mc_location_list_t target, mc_object_info_t info, Dwarf_Die* die, Dwarf_Attribute* attr); - -// ***** Variables and functions - -struct s_dw_type{ - e_dw_type_type type; - Dwarf_Off id; /* Offset in the section (in hexadecimal form) */ - char *name; /* Name of the type */ - int byte_size; /* Size in bytes */ - int element_count; /* Number of elements for array type */ - char *dw_type_id; /* DW_AT_type id */ - xbt_dynar_t members; /* if DW_TAG_structure_type, DW_TAG_class_type, DW_TAG_union_type*/ - int is_pointer_type; - - // Location (for members) is either of: - struct s_mc_expression location; - int offset; - - dw_type_t subtype; // DW_AT_type - dw_type_t full_type; // The same (but more complete) type -}; - -void* mc_member_resolve(const void* base, dw_type_t type, dw_type_t member, mc_snapshot_t snapshot); -void* mc_member_snapshot_resolve(const void* base, dw_type_t type, dw_type_t member, mc_snapshot_t snapshot); - -typedef struct s_dw_variable{ - Dwarf_Off dwarf_offset; /* Global offset of the field. */ - int global; - char *name; - char *type_origin; - dw_type_t type; - - // Use either of: - s_mc_location_list_t locations; - void* address; - - size_t start_scope; - mc_object_info_t object_info; - -}s_dw_variable_t, *dw_variable_t; - -struct s_dw_frame{ - int tag; - char *name; - void *low_pc; - void *high_pc; - s_mc_location_list_t frame_base; - xbt_dynar_t /* */ variables; /* Cannot use dict, there may be several variables with the same name (in different lexical blocks)*/ - unsigned long int id; /* DWARF offset of the subprogram */ - xbt_dynar_t /* */ scopes; - Dwarf_Off abstract_origin_id; - mc_object_info_t object_info; -}; - -struct s_mc_function_index_item { - void* low_pc, *high_pc; - dw_frame_t function; -}; - -void mc_frame_free(dw_frame_t freme); - -void dw_type_free(dw_type_t t); -void dw_variable_free(dw_variable_t v); -void dw_variable_free_voidp(void *t); - -void MC_dwarf_register_global_variable(mc_object_info_t info, dw_variable_t variable); -void MC_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable); -void MC_dwarf_register_non_global_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable); -void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable); - -/** Find the DWARF offset for this ELF object - * - * An offset is applied to address found in DWARF: - * - *
    - *
  • for an executable obejct, addresses are virtual address - * (there is no offset) i.e. \f$\text{virtual address} = \{dwarf address}\f$;
  • - *
  • for a shared object, the addreses are offset from the begining - * of the shared object (the base address of the mapped shared - * object must be used as offset - * i.e. \f$\text{virtual address} = \text{shared object base address} - * + \text{dwarf address}\f$.
  • - * - */ -void* MC_object_base_address(mc_object_info_t info); - -/********************************** DWARF **********************************/ - -#define MC_EXPRESSION_STACK_SIZE 64 - -#define MC_EXPRESSION_OK 0 -#define MC_EXPRESSION_E_UNSUPPORTED_OPERATION 1 -#define MC_EXPRESSION_E_STACK_OVERFLOW 2 -#define MC_EXPRESSION_E_STACK_UNDERFLOW 3 -#define MC_EXPRESSION_E_MISSING_STACK_CONTEXT 4 -#define MC_EXPRESSION_E_MISSING_FRAME_BASE 5 -#define MC_EXPRESSION_E_NO_BASE_ADDRESS 6 - -typedef struct s_mc_expression_state { - uintptr_t stack[MC_EXPRESSION_STACK_SIZE]; - size_t stack_size; - - unw_cursor_t* cursor; - void* frame_base; - mc_snapshot_t snapshot; - mc_object_info_t object_info; -} s_mc_expression_state_t, *mc_expression_state_t; - -int mc_dwarf_execute_expression(size_t n, const Dwarf_Op* ops, mc_expression_state_t state); - -void* mc_find_frame_base(dw_frame_t frame, mc_object_info_t object_info, unw_cursor_t* unw_cursor); /********************************** Miscellaneous **********************************/ @@ -550,32 +126,11 @@ typedef struct s_local_variable{ int region; }s_local_variable_t, *local_variable_t; -/********************************* Communications pattern ***************************/ - -typedef struct s_mc_comm_pattern{ - int num; - smx_action_t comm; - e_smx_comm_type_t type; - int completed; - unsigned long src_proc; - unsigned long dst_proc; - const char *src_host; - const char *dst_host; - char *rdv; - size_t data_size; - void *data; - int matched_comm; -}s_mc_comm_pattern_t, *mc_comm_pattern_t; - -extern xbt_dynar_t communications_pattern; - -void get_comm_pattern(xbt_dynar_t communications_pattern, smx_simcall_t request, int call); - /* *********** Sets *********** */ typedef struct s_mc_address_set *mc_address_set_t; -mc_address_set_t mc_address_set_new(); +mc_address_set_t mc_address_set_new(void); void mc_address_set_free(mc_address_set_t* p); void mc_address_add(mc_address_set_t p, const void* value); bool mc_address_test(mc_address_set_t p, const void* value); @@ -589,5 +144,17 @@ bool mc_address_test(mc_address_set_t p, const void* value); * */ uint64_t mc_hash_processes_state(int num_state, xbt_dynar_t stacks); -#endif +/** @brief Dump the stacks of the application processes + * + * This functions is currently not used but it is quite convenient + * to call from the debugger. + * + * Does not work when an application thread is running. + */ +void MC_dump_stacks(FILE* file); + +void MC_report_assertion_error(void); +SG_END_DECL() + +#endif