Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : rename cfg flag for state comparison reduction with storage of visite...
[simgrid.git] / src / mc / mc_global.c
index b382d7a..72c537a 100644 (file)
@@ -71,11 +71,11 @@ void _mc_cfg_cb_max_depth(const char *name, int pos) {
   xbt_cfg_set_int(_surf_cfg_set,"model-check",1);
 }
 
-void _mc_cfg_cb_stateful(const char *name, int pos) {
+void _mc_cfg_cb_visited(const char *name, int pos) {
   if (_surf_init_status && !_surf_do_model_check) {
-    xbt_die("You are trying to change stateful mode after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die("You are specifying a number of stored visited states after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  _surf_mc_stateful= xbt_cfg_get_int(_surf_cfg_set, name);
+  _surf_mc_visited= xbt_cfg_get_int(_surf_cfg_set, name);
   xbt_cfg_set_int(_surf_cfg_set,"model-check",1);
 }
 
@@ -85,13 +85,12 @@ void _mc_cfg_cb_stateful(const char *name, int pos) {
 mc_state_t mc_current_state = NULL;
 char mc_replay_mode = FALSE;
 double *mc_time = NULL;
-mc_snapshot_t initial_snapshot = NULL;
-int raw_mem_set;
 
 /* Safety */
 
 xbt_fifo_t mc_stack_safety = NULL;
 mc_stats_t mc_stats = NULL;
+mc_global_t initial_state_safety = NULL;
 
 /* Liveness */
 
@@ -116,6 +115,7 @@ xbt_automaton_t _mc_property_automaton = NULL;
 static void MC_assert_pair(int prop);
 static dw_location_t get_location(xbt_dict_t location_list, char *expr);
 static dw_frame_t get_frame_by_offset(xbt_dict_t all_variables, unsigned long int offset);
+static void ignore_coverage_variables(char *executable, int region_type);
 
 void MC_do_the_modelcheck_for_real() {
   if (!_surf_mc_property_file || _surf_mc_property_file[0]=='\0') {
@@ -123,7 +123,7 @@ void MC_do_the_modelcheck_for_real() {
       mc_reduce_kind=e_mc_reduce_dpor;
 
     XBT_INFO("Check a safety property");
-    MC_modelcheck();
+    MC_modelcheck_safety();
 
   } else  {
 
@@ -136,62 +136,14 @@ void MC_do_the_modelcheck_for_real() {
   }
 }
 
-/**
- *  \brief Initialize the model-checker data structures
- */
-void MC_init_safety(void)
-{
-
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  /* Check if MC is already initialized */
-  if (initial_snapshot)
-    return;
-
-  mc_time = xbt_new0(double, simix_process_maxpid);
-
-  /* Initialize the data structures that must be persistent across every
-     iteration of the model-checker (in RAW memory) */
-  
-  MC_SET_RAW_MEM;
-
-  /* Initialize statistics */
-  mc_stats = xbt_new0(s_mc_stats_t, 1);
-  mc_stats->state_size = 1;
-
-  /* Create exploration stack */
-  mc_stack_safety = xbt_fifo_new();
-
-  MC_UNSET_RAW_MEM;
-
-  MC_dpor_init();
-
-  MC_SET_RAW_MEM;
-  /* Save the initial state */
-  initial_snapshot = xbt_new0(s_mc_snapshot_t, 1);
-  MC_take_snapshot(initial_snapshot);
-  MC_UNSET_RAW_MEM;
-
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
-  
-}
 
 void MC_compare(void){
   compare = 1;
 }
 
+void MC_init(){
 
-void MC_modelcheck(void)
-{
-  MC_init_safety();
-  MC_dpor();
-  MC_exit();
-}
-
-void MC_init_liveness(){
-
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
   
   mc_time = xbt_new0(double, simix_process_maxpid);
 
@@ -219,37 +171,97 @@ void MC_init_liveness(){
   xbt_dict_t libsimgrid_location_list = MC_get_location_list(ls_path);
   MC_get_local_variables(ls_path, libsimgrid_location_list, &mc_local_variables);
 
-  initial_state_liveness = xbt_new0(s_mc_global_t, 1);
-
-  MC_UNSET_RAW_MEM;
-
   MC_init_memory_map_info();
 
   /* Get .plt section (start and end addresses) for data libsimgrid and data program comparison */
   get_libsimgrid_plt_section();
   get_binary_plt_section();
 
+  ignore_coverage_variables(libsimgrid_path, 1);
+  ignore_coverage_variables(xbt_binary_name, 2);
+
+  MC_UNSET_RAW_MEM;
+
+   /* Ignore some variables from xbt/ex.h used by exception e for stacks comparison */
+  MC_ignore_stack("e", "*");
+  MC_ignore_stack("__ex_cleanup", "*");
+  MC_ignore_stack("__ex_mctx_en", "*");
+  MC_ignore_stack("__ex_mctx_me", "*");
+  MC_ignore_stack("_log_ev", "*");
+  MC_ignore_stack("_throw_ctx", "*");
+  MC_ignore_stack("ctx", "*");
+
+
   if(raw_mem_set)
     MC_SET_RAW_MEM;
 
 }
 
+void MC_modelcheck_safety(void)
+{
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+
+  /* Check if MC is already initialized */
+  if (initial_state_safety)
+    return;
+
+  mc_time = xbt_new0(double, simix_process_maxpid);
+
+  /* Initialize the data structures that must be persistent across every
+     iteration of the model-checker (in RAW memory) */
+  
+  MC_SET_RAW_MEM;
+
+  /* Initialize statistics */
+  mc_stats = xbt_new0(s_mc_stats_t, 1);
+  mc_stats->state_size = 1;
+
+  /* Create exploration stack */
+  mc_stack_safety = xbt_fifo_new();
+
+  MC_UNSET_RAW_MEM;
+
+  if(_surf_mc_visited > 0){
+    MC_init();
+  }else{
+    MC_init_memory_map_info();
+    get_libsimgrid_plt_section();
+    get_binary_plt_section();
+  }
+
+  MC_dpor_init();
+
+  MC_SET_RAW_MEM;
+  /* Save the initial state */
+  initial_state_safety = xbt_new0(s_mc_global_t, 1);
+  initial_state_safety->snapshot = MC_take_snapshot();
+  //MC_take_snapshot(initial_snapshot);
+  MC_UNSET_RAW_MEM;
+
+  if(raw_mem_set)
+    MC_SET_RAW_MEM;
+
+  MC_dpor();
+
+  MC_exit();
+}
+
 void MC_modelcheck_liveness(){
 
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
-  MC_init_liveness();
+  MC_init();
  
   MC_SET_RAW_MEM;
   
   /* Initialize statistics */
   mc_stats_pair = xbt_new0(s_mc_stats_pair_t, 1);
 
-  XBT_DEBUG("Creating stack");
-
   /* Create exploration stack */
   mc_stack_liveness = xbt_fifo_new();
 
+  initial_state_liveness = xbt_new0(s_mc_global_t, 1);
+
   MC_UNSET_RAW_MEM;
 
   MC_ddfs_init();
@@ -258,6 +270,9 @@ void MC_modelcheck_liveness(){
   MC_print_statistics_pairs(mc_stats_pair);
   xbt_free(mc_time);
 
+  if(raw_mem_set)
+    MC_SET_RAW_MEM;
+
 }
 
 
@@ -331,7 +346,7 @@ void MC_replay(xbt_fifo_t stack, int start)
 
   if(start == -1){
     /* Restore the initial state */
-    MC_restore_snapshot(initial_snapshot);
+    MC_restore_snapshot(initial_state_safety->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  */
     MC_UNSET_RAW_MEM;
@@ -386,7 +401,7 @@ void MC_replay(xbt_fifo_t stack, int start)
 void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
 {
 
-  int raw_mem = (mmalloc_get_current_heap() == raw_heap);
+  initial_state_liveness->raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
   int value;
   char *req_str;
@@ -399,11 +414,12 @@ void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
   XBT_DEBUG("**** Begin Replay ****");
 
   /* Restore the initial state */
-  MC_restore_snapshot(initial_state_liveness->initial_snapshot);
+  MC_restore_snapshot(initial_state_liveness->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  */
-  
-  MC_UNSET_RAW_MEM;
+  if(!initial_state_liveness->raw_mem_set)
+    MC_UNSET_RAW_MEM;
 
   if(all_stack){
 
@@ -489,7 +505,7 @@ void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
 
   XBT_DEBUG("**** End Replay ****");
 
-  if(raw_mem)
+  if(initial_state_liveness->raw_mem_set)
     MC_SET_RAW_MEM;
   else
     MC_UNSET_RAW_MEM;
@@ -504,7 +520,7 @@ void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
 void MC_dump_stack_safety(xbt_fifo_t stack)
 {
   
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
   MC_show_stack_safety(stack);
 
@@ -587,7 +603,7 @@ void MC_show_stack_liveness(xbt_fifo_t stack){
 
 void MC_dump_stack_liveness(xbt_fifo_t stack){
 
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
   mc_pair_stateless_t pair;
 
@@ -671,7 +687,7 @@ double MC_process_clock_get(smx_process_t process)
 
 void MC_automaton_load(const char *file){
 
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
   MC_SET_RAW_MEM;
 
@@ -689,7 +705,7 @@ void MC_automaton_load(const char *file){
 
 void MC_automaton_new_propositional_symbol(const char* id, void* fct) {
 
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
   MC_SET_RAW_MEM;
 
@@ -707,9 +723,73 @@ void MC_automaton_new_propositional_symbol(const char* id, void* fct) {
 
 /************ MC_ignore ***********/ 
 
+static void ignore_coverage_variables(char *executable, int region_type){
+
+  FILE *fp;
+
+  char *command = bprintf("objdump --syms %s", executable);
+
+  fp = popen(command, "r");
+
+  if(fp == NULL){
+    perror("popen failed");
+    xbt_abort();
+  }
+
+  char *line = NULL;
+  ssize_t read;
+  size_t n = 0;
+
+  xbt_dynar_t line_tokens = NULL;
+  unsigned long int size, offset;
+  void *address;
+
+  while ((read = getline(&line, &n, fp)) != -1){
+
+    if(n == 0)
+      continue;
+
+     /* Wipeout the new line character */
+    line[read - 1] = '\0';
+
+    xbt_str_strip_spaces(line);
+    xbt_str_ltrim(line, NULL);
+
+    line_tokens = xbt_str_split(line, NULL);
+
+    if(xbt_dynar_length(line_tokens) < 3 || strcmp(xbt_dynar_get_as(line_tokens, 0, char *), "SYMBOL") == 0)
+      continue;
+
+    if(((strncmp(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 1, char *), "gcov", 4) == 0)
+        || (strncmp(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 1, char *), "__gcov", 6) == 0))
+       && (((strcmp(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 3, char *), ".bss") == 0) 
+            || (strcmp(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 3, char *), ".data") == 0)))){
+      if(region_type == 1){ /* libsimgrid */
+        offset = strtoul(xbt_dynar_get_as(line_tokens, 0, char*), NULL, 16);
+        size = strtoul(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 2, char *), NULL, 16);
+        //XBT_DEBUG("Add ignore at address %p (size %lu)", (char *)start_text_libsimgrid+offset, size);
+        MC_ignore_data_bss((char *)start_text_libsimgrid+offset, size);
+      }else{ /* binary */
+        address = (void *)strtoul(xbt_dynar_get_as(line_tokens, 0, char*), NULL, 16);
+        size = strtoul(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 2, char *), NULL, 16);
+        //XBT_DEBUG("Add ignore at address %p (size %lu)", address, size);
+        MC_ignore_data_bss(address, size);
+      }
+    }
+
+    xbt_dynar_free(&line_tokens);
+
+  }
+
+  free(command);
+  free(line);
+  pclose(fp);
+
+}
+
 void MC_ignore_heap(void *address, size_t size){
 
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
   MC_SET_RAW_MEM;
   
@@ -750,7 +830,7 @@ void MC_ignore_heap(void *address, size_t size){
 
 void MC_ignore_data_bss(void *address, size_t size){
 
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
   MC_SET_RAW_MEM;
   
@@ -793,7 +873,7 @@ void MC_ignore_data_bss(void *address, size_t size){
     var->address = address;
     var->size = size;
 
-    if(current_var->address > address)
+    if(current_var->address < address)
       xbt_dynar_insert_at(mc_data_bss_comparison_ignore, cursor + 1, &var);
     else
       xbt_dynar_insert_at(mc_data_bss_comparison_ignore, cursor, &var);
@@ -808,7 +888,7 @@ void MC_ignore_data_bss(void *address, size_t size){
 
 void MC_ignore_stack(const char *var_name, const char *frame){
   
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
   MC_SET_RAW_MEM;
 
@@ -873,7 +953,7 @@ void MC_ignore_stack(const char *var_name, const char *frame){
 
 void MC_new_stack_area(void *stack, char *name, void* context, size_t size){
 
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
 
   MC_SET_RAW_MEM;
   if(stacks_areas == NULL)
@@ -901,8 +981,10 @@ xbt_dict_t MC_get_location_list(const char *elf_file){
 
   FILE *fp = popen(command, "r");
 
-  if(fp == NULL)
+  if(fp == NULL){
     perror("popen for objdump failed");
+    xbt_abort();
+  }
 
   int debug = 0; /*Detect if the program has been compiled with -g */
 
@@ -1001,8 +1083,11 @@ char *get_libsimgrid_path(){
   char *command = bprintf("ldd %s", xbt_binary_name);
   
   FILE *fp = popen(command, "r");
-  if(fp == NULL)
+
+  if(fp == NULL){
     perror("popen for ldd failed");
+    xbt_abort();
+  }
 
   char *line;
   ssize_t read;