Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
b74447e64541d5c979d5bf87840085461fa66a19
[simgrid.git] / src / mc / mc_global.c
1 /* Copyright (c) 2008-2012 Da SimGrid Team. All rights reserved.            */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <sys/wait.h>
9 #include <sys/time.h>
10
11 #include "simgrid/sg_config.h"
12 #include "../surf/surf_private.h"
13 #include "../simix/smx_private.h"
14 #include "../xbt/mmalloc/mmprivate.h"
15 #include "xbt/fifo.h"
16 #include "mc_private.h"
17 #include "xbt/automaton.h"
18 #include "xbt/dict.h"
19
20 XBT_LOG_NEW_CATEGORY(mc, "All MC categories");
21 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_global, mc,
22                                 "Logging specific to MC (global)");
23
24 /* Configuration support */
25 e_mc_reduce_t mc_reduce_kind=e_mc_reduce_unset;
26
27 int _sg_do_model_check = 0;
28 int _sg_mc_checkpoint=0;
29 char* _sg_mc_property_file=NULL;
30 int _sg_mc_timeout=0;
31 int _sg_mc_max_depth=1000;
32 int _sg_mc_visited=0;
33 char *_sg_mc_dot_output_file = NULL;
34
35 extern int _sg_init_status;
36 void _mc_cfg_cb_reduce(const char *name, int pos) {
37   if (_sg_init_status && !_sg_do_model_check) {
38     xbt_die("You are specifying a reduction strategy 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.");
39   }
40   char *val= xbt_cfg_get_string(_sg_cfg_set, name);
41   if (!strcasecmp(val,"none")) {
42     mc_reduce_kind = e_mc_reduce_none;
43   } else if (!strcasecmp(val,"dpor")) {
44     mc_reduce_kind = e_mc_reduce_dpor;
45   } else {
46     xbt_die("configuration option %s can only take 'none' or 'dpor' as a value",name);
47   }
48 }
49
50 void _mc_cfg_cb_checkpoint(const char *name, int pos) {
51   if (_sg_init_status && !_sg_do_model_check) {
52     xbt_die("You are specifying a checkpointing value 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.");
53   }
54   _sg_mc_checkpoint = xbt_cfg_get_int(_sg_cfg_set, name);
55 }
56 void _mc_cfg_cb_property(const char *name, int pos) {
57   if (_sg_init_status && !_sg_do_model_check) {
58     xbt_die("You are specifying a property 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.");
59   }
60   _sg_mc_property_file= xbt_cfg_get_string(_sg_cfg_set, name);
61 }
62
63 void _mc_cfg_cb_timeout(const char *name, int pos) {
64   if (_sg_init_status && !_sg_do_model_check) {
65     xbt_die("You are specifying a value to enable/disable timeout for wait requests 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.");
66   }
67   _sg_mc_timeout= xbt_cfg_get_int(_sg_cfg_set, name);
68 }
69
70 void _mc_cfg_cb_max_depth(const char *name, int pos) {
71   if (_sg_init_status && !_sg_do_model_check) {
72     xbt_die("You are specifying a max depth value 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.");
73   }
74   _sg_mc_max_depth= xbt_cfg_get_int(_sg_cfg_set, name);
75 }
76
77 void _mc_cfg_cb_visited(const char *name, int pos) {
78   if (_sg_init_status && !_sg_do_model_check) {
79     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.");
80   }
81   _sg_mc_visited= xbt_cfg_get_int(_sg_cfg_set, name);
82 }
83
84 void _mc_cfg_cb_dot_output(const char *name, int pos) {
85   if (_sg_init_status && !_sg_do_model_check) {
86     xbt_die("You are specifying a file name for a dot output of graph state 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.");
87   }
88   _sg_mc_dot_output_file= xbt_cfg_get_string(_sg_cfg_set, name);
89 }
90
91 /* MC global data structures */
92
93 mc_state_t mc_current_state = NULL;
94 char mc_replay_mode = FALSE;
95 double *mc_time = NULL;
96 mc_comparison_times_t mc_comp_times = NULL;
97 double mc_snapshot_comparison_time;
98
99 /* Safety */
100
101 xbt_fifo_t mc_stack_safety = NULL;
102 mc_stats_t mc_stats = NULL;
103 mc_global_t initial_state_safety = NULL;
104
105 /* Liveness */
106
107 mc_stats_pair_t mc_stats_pair = NULL;
108 xbt_fifo_t mc_stack_liveness = NULL;
109 mc_global_t initial_state_liveness = NULL;
110 int compare;
111
112 /* Local */
113 xbt_dict_t mc_local_variables = NULL;
114 /* Global */
115 xbt_dynar_t mc_global_variables = NULL;
116
117 /* Ignore mechanism */
118 xbt_dynar_t mc_stack_comparison_ignore;
119 xbt_dynar_t mc_data_bss_comparison_ignore;
120 extern xbt_dynar_t mc_heap_comparison_ignore;
121 extern xbt_dynar_t stacks_areas;
122
123 FILE *dot_output = NULL;
124 const char* colors[10];
125
126 xbt_automaton_t _mc_property_automaton = NULL;
127
128 /* Static functions */
129
130 static void MC_assert_pair(int prop);
131 static dw_location_t get_location(xbt_dict_t location_list, char *expr);
132 static dw_frame_t get_frame_by_offset(xbt_dict_t all_variables, unsigned long int offset);
133 static size_t data_bss_ignore_size(void *address);
134 static void MC_get_global_variables(char *elf_file);
135
136 void MC_do_the_modelcheck_for_real() {
137
138   MC_SET_RAW_MEM;
139   mc_comp_times = xbt_new0(s_mc_comparison_times_t, 1);
140   MC_UNSET_RAW_MEM;
141   
142   if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0'))
143     MC_init_dot_output();
144
145   if (!_sg_mc_property_file || _sg_mc_property_file[0]=='\0') {
146     if (mc_reduce_kind==e_mc_reduce_unset)
147       mc_reduce_kind=e_mc_reduce_dpor;
148
149     XBT_INFO("Check a safety property");
150     MC_modelcheck_safety();
151
152   } else  {
153
154     if (mc_reduce_kind==e_mc_reduce_unset)
155       mc_reduce_kind=e_mc_reduce_none;
156
157     XBT_INFO("Check the liveness property %s",_sg_mc_property_file);
158     MC_automaton_load(_sg_mc_property_file);
159     MC_modelcheck_liveness();
160   }
161 }
162
163
164 void MC_compare(void){
165   compare = 1;
166 }
167
168 void MC_init(){
169
170   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
171   
172   mc_time = xbt_new0(double, simix_process_maxpid);
173
174   /* mc_time refers to clock for each process -> ignore it for heap comparison */
175   int i;
176   for(i = 0; i<simix_process_maxpid; i++)
177     MC_ignore_heap(&(mc_time[i]), sizeof(double));
178   
179   compare = 0;
180
181   /* Initialize the data structures that must be persistent across every
182      iteration of the model-checker (in RAW memory) */
183
184   MC_SET_RAW_MEM;
185
186   MC_init_memory_map_info();
187   
188   mc_local_variables = xbt_dict_new_homogeneous(NULL);
189
190   /* Get local variables in binary for state equality detection */
191   xbt_dict_t binary_location_list = MC_get_location_list(xbt_binary_name);
192   MC_get_local_variables(xbt_binary_name, binary_location_list, &mc_local_variables);
193
194   /* Get local variables in libsimgrid for state equality detection */
195   xbt_dict_t libsimgrid_location_list = MC_get_location_list(libsimgrid_path);
196   MC_get_local_variables(libsimgrid_path, libsimgrid_location_list, &mc_local_variables);
197
198   xbt_dict_free(&libsimgrid_location_list);
199   xbt_dict_free(&binary_location_list);
200   
201   /* Get .plt section (start and end addresses) for data libsimgrid and data program comparison */
202   get_libsimgrid_plt_section();
203   get_binary_plt_section();
204
205   /* Get global variables */
206   MC_get_global_variables(xbt_binary_name);
207   MC_get_global_variables(libsimgrid_path);
208
209   MC_UNSET_RAW_MEM;
210
211    /* Ignore some variables from xbt/ex.h used by exception e for stacks comparison */
212   MC_ignore_stack("e", "*");
213   MC_ignore_stack("__ex_cleanup", "*");
214   MC_ignore_stack("__ex_mctx_en", "*");
215   MC_ignore_stack("__ex_mctx_me", "*");
216   MC_ignore_stack("__xbt_ex_ctx_ptr", "*");
217   MC_ignore_stack("_log_ev", "*");
218   MC_ignore_stack("_throw_ctx", "*");
219   MC_ignore_stack("ctx", "*");
220
221   MC_ignore_stack("next_context", "smx_ctx_sysv_suspend_serial");
222   MC_ignore_stack("i", "smx_ctx_sysv_suspend_serial");
223
224   MC_ignore_data_bss(&mc_comp_times, sizeof(mc_comp_times));
225   MC_ignore_data_bss(&mc_snapshot_comparison_time, sizeof(mc_snapshot_comparison_time)); 
226
227   if(raw_mem_set)
228     MC_SET_RAW_MEM;
229
230 }
231
232 void MC_init_dot_output(){
233
234   colors[0] = "blue";
235   colors[1] = "red";
236   colors[2] = "green";
237   colors[3] = "pink";
238   colors[4] = "brown";
239   colors[5] = "purple";
240   colors[6] = "yellow";
241   colors[7] = "orange";
242   
243   dot_output = fopen(_sg_mc_dot_output_file, "w");
244   
245   if(dot_output == NULL){
246     perror("Error open dot output file");
247     xbt_abort();
248   }
249
250   fprintf(dot_output, "digraph graphname{\n fixedsize=true; rankdir=TB; ranksep=.20; edge [fontsize=12]; node [fontsize=10, shape=circle,width=.5 ]; graph [resolution=20, fontsize=10];\n");
251
252 }
253
254 void MC_modelcheck_safety(void)
255 {
256   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
257
258   /* Check if MC is already initialized */
259   if (initial_state_safety)
260     return;
261
262   mc_time = xbt_new0(double, simix_process_maxpid);
263
264   /* Initialize the data structures that must be persistent across every
265      iteration of the model-checker (in RAW memory) */
266   
267   MC_SET_RAW_MEM;
268
269   /* Initialize statistics */
270   mc_stats = xbt_new0(s_mc_stats_t, 1);
271   mc_stats->state_size = 1;
272
273   /* Create exploration stack */
274   mc_stack_safety = xbt_fifo_new();
275
276   MC_UNSET_RAW_MEM;
277
278   if(_sg_mc_visited > 0){
279     MC_init();
280   }else{
281     MC_SET_RAW_MEM;
282     MC_init_memory_map_info();
283     get_libsimgrid_plt_section();
284     get_binary_plt_section();
285     MC_UNSET_RAW_MEM;
286   }
287
288   MC_dpor_init();
289
290   MC_SET_RAW_MEM;
291   /* Save the initial state */
292   initial_state_safety = xbt_new0(s_mc_global_t, 1);
293   initial_state_safety->snapshot = MC_take_snapshot();
294   MC_UNSET_RAW_MEM;
295
296   MC_dpor();
297
298   if(raw_mem_set)
299     MC_SET_RAW_MEM;
300
301   MC_exit();
302 }
303
304 void MC_modelcheck_liveness(){
305
306   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
307
308   MC_init();
309  
310   MC_SET_RAW_MEM;
311   
312   /* Initialize statistics */
313   mc_stats_pair = xbt_new0(s_mc_stats_pair_t, 1);
314
315   /* Create exploration stack */
316   mc_stack_liveness = xbt_fifo_new();
317
318   initial_state_liveness = xbt_new0(s_mc_global_t, 1);
319
320   MC_UNSET_RAW_MEM;
321
322   MC_ddfs_init();
323
324   /* We're done */
325   MC_print_statistics_pairs(mc_stats_pair);
326   xbt_free(mc_time);
327
328   if(raw_mem_set)
329     MC_SET_RAW_MEM;
330
331 }
332
333
334 void MC_exit(void)
335 {
336   MC_SET_RAW_MEM;
337   if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0')){
338     fprintf(dot_output, "}\n");
339     fclose(dot_output);
340   }
341   MC_UNSET_RAW_MEM;
342
343   xbt_free(mc_time);
344   MC_memory_exit();
345   xbt_abort();
346 }
347
348 int SIMIX_pre_mc_random(smx_simcall_t simcall){
349
350   return simcall->mc_value;
351 }
352
353
354 int MC_random(void)
355 {
356   /*FIXME: return mc_current_state->executed_transition->random.value;*/
357   return simcall_mc_random();
358 }
359
360 /**
361  * \brief Schedules all the process that are ready to run
362  */
363 void MC_wait_for_requests(void)
364 {
365   smx_process_t process;
366   smx_simcall_t req;
367   unsigned int iter;
368
369   while (!xbt_dynar_is_empty(simix_global->process_to_run)) {
370     SIMIX_process_runall();
371     xbt_dynar_foreach(simix_global->process_that_ran, iter, process) {
372       req = &process->simcall;
373       if (req->call != SIMCALL_NONE && !MC_request_is_visible(req))
374         SIMIX_simcall_pre(req, 0);
375     }
376   }
377 }
378
379 int MC_deadlock_check()
380 {
381   int deadlock = FALSE;
382   smx_process_t process;
383   if(xbt_swag_size(simix_global->process_list)){
384     deadlock = TRUE;
385     xbt_swag_foreach(process, simix_global->process_list){
386       if(process->simcall.call != SIMCALL_NONE
387          && MC_request_is_enabled(&process->simcall)){
388         deadlock = FALSE;
389         break;
390       }
391     }
392   }
393   return deadlock;
394 }
395
396 /**
397  * \brief Re-executes from the state at position start all the transitions indicated by
398  *        a given model-checker stack.
399  * \param stack The stack with the transitions to execute.
400  * \param start Start index to begin the re-execution.
401  */
402 void MC_replay(xbt_fifo_t stack, int start)
403 {
404   int raw_mem = (mmalloc_get_current_heap() == raw_heap);
405
406   int value, i = 1;
407   char *req_str;
408   smx_simcall_t req = NULL, saved_req = NULL;
409   xbt_fifo_item_t item, start_item;
410   mc_state_t state;
411
412   XBT_DEBUG("**** Begin Replay ****");
413
414   if(start == -1){
415     /* Restore the initial state */
416     MC_restore_snapshot(initial_state_safety->snapshot);
417     /* At the moment of taking the snapshot the raw heap was set, so restoring
418      * it will set it back again, we have to unset it to continue  */
419     MC_UNSET_RAW_MEM;
420   }
421
422   start_item = xbt_fifo_get_last_item(stack);
423   if(start != -1){
424     while (i != start){
425       start_item = xbt_fifo_get_prev_item(start_item);
426       i++;
427     }
428   }
429
430   /* Traverse the stack from the state at position start and re-execute the transitions */
431   for (item = start_item;
432        item != xbt_fifo_get_first_item(stack);
433        item = xbt_fifo_get_prev_item(item)) {
434
435     state = (mc_state_t) xbt_fifo_get_item_content(item);
436     saved_req = MC_state_get_executed_request(state, &value);
437    
438     if(saved_req){
439       /* because we got a copy of the executed request, we have to fetch the  
440          real one, pointed by the request field of the issuer process */
441       req = &saved_req->issuer->simcall;
442
443       /* Debug information */
444       if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)){
445         req_str = MC_request_to_string(req, value);
446         XBT_DEBUG("Replay: %s (%p)", req_str, state);
447         xbt_free(req_str);
448       }
449     }
450          
451     SIMIX_simcall_pre(req, value);
452     MC_wait_for_requests();
453          
454     /* Update statistics */
455     mc_stats->visited_states++;
456     mc_stats->executed_transitions++;
457   }
458   XBT_DEBUG("**** End Replay ****");
459
460   if(raw_mem)
461     MC_SET_RAW_MEM;
462   else
463     MC_UNSET_RAW_MEM;
464   
465
466 }
467
468 void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
469 {
470
471   initial_state_liveness->raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
472
473   int value;
474   char *req_str;
475   smx_simcall_t req = NULL, saved_req = NULL;
476   xbt_fifo_item_t item;
477   mc_state_t state;
478   mc_pair_stateless_t pair;
479   int depth = 1;
480
481   XBT_DEBUG("**** Begin Replay ****");
482
483   /* Restore the initial state */
484   MC_restore_snapshot(initial_state_liveness->snapshot);
485
486   /* At the moment of taking the snapshot the raw heap was set, so restoring
487    * it will set it back again, we have to unset it to continue  */
488   if(!initial_state_liveness->raw_mem_set)
489     MC_UNSET_RAW_MEM;
490
491   if(all_stack){
492
493     item = xbt_fifo_get_last_item(stack);
494
495     while(depth <= xbt_fifo_size(stack)){
496
497       pair = (mc_pair_stateless_t) xbt_fifo_get_item_content(item);
498       state = (mc_state_t) pair->graph_state;
499
500       if(pair->requests > 0){
501    
502         saved_req = MC_state_get_executed_request(state, &value);
503         //XBT_DEBUG("SavedReq->call %u", saved_req->call);
504       
505         if(saved_req != NULL){
506           /* because we got a copy of the executed request, we have to fetch the  
507              real one, pointed by the request field of the issuer process */
508           req = &saved_req->issuer->simcall;
509           //XBT_DEBUG("Req->call %u", req->call);
510   
511           /* Debug information */
512           if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)){
513             req_str = MC_request_to_string(req, value);
514             XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth, req_str, state);
515             xbt_free(req_str);
516           }
517   
518         }
519  
520         SIMIX_simcall_pre(req, value);
521         MC_wait_for_requests();
522       }
523
524       depth++;
525     
526       /* Update statistics */
527       mc_stats_pair->visited_pairs++;
528
529       item = xbt_fifo_get_prev_item(item);
530     }
531
532   }else{
533
534     /* Traverse the stack from the initial state and re-execute the transitions */
535     for (item = xbt_fifo_get_last_item(stack);
536          item != xbt_fifo_get_first_item(stack);
537          item = xbt_fifo_get_prev_item(item)) {
538
539       pair = (mc_pair_stateless_t) xbt_fifo_get_item_content(item);
540       state = (mc_state_t) pair->graph_state;
541
542       if(pair->requests > 0){
543    
544         saved_req = MC_state_get_executed_request(state, &value);
545         //XBT_DEBUG("SavedReq->call %u", saved_req->call);
546       
547         if(saved_req != NULL){
548           /* because we got a copy of the executed request, we have to fetch the  
549              real one, pointed by the request field of the issuer process */
550           req = &saved_req->issuer->simcall;
551           //XBT_DEBUG("Req->call %u", req->call);
552   
553           /* Debug information */
554           if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)){
555             req_str = MC_request_to_string(req, value);
556             XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth, req_str, state);
557             xbt_free(req_str);
558           }
559   
560         }
561  
562         SIMIX_simcall_pre(req, value);
563         MC_wait_for_requests();
564       }
565
566       depth++;
567     
568       /* Update statistics */
569       mc_stats_pair->visited_pairs++;
570     }
571   }  
572
573   XBT_DEBUG("**** End Replay ****");
574
575   if(initial_state_liveness->raw_mem_set)
576     MC_SET_RAW_MEM;
577   else
578     MC_UNSET_RAW_MEM;
579   
580 }
581
582 /**
583  * \brief Dumps the contents of a model-checker's stack and shows the actual
584  *        execution trace
585  * \param stack The stack to dump
586  */
587 void MC_dump_stack_safety(xbt_fifo_t stack)
588 {
589   
590   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
591
592   MC_show_stack_safety(stack);
593
594   if(!_sg_mc_checkpoint){
595
596     mc_state_t state;
597
598     MC_SET_RAW_MEM;
599     while ((state = (mc_state_t) xbt_fifo_pop(stack)) != NULL)
600       MC_state_delete(state);
601     MC_UNSET_RAW_MEM;
602
603   }
604
605   if(raw_mem_set)
606     MC_SET_RAW_MEM;
607   else
608     MC_UNSET_RAW_MEM;
609   
610 }
611
612
613 void MC_show_stack_safety(xbt_fifo_t stack)
614 {
615   int value;
616   mc_state_t state;
617   xbt_fifo_item_t item;
618   smx_simcall_t req;
619   char *req_str = NULL;
620   
621   for (item = xbt_fifo_get_last_item(stack);
622        (item ? (state = (mc_state_t) (xbt_fifo_get_item_content(item)))
623         : (NULL)); item = xbt_fifo_get_prev_item(item)) {
624     req = MC_state_get_executed_request(state, &value);
625     if(req){
626       req_str = MC_request_to_string(req, value);
627       XBT_INFO("%s", req_str);
628       xbt_free(req_str);
629     }
630   }
631 }
632
633 void MC_show_deadlock(smx_simcall_t req)
634 {
635   /*char *req_str = NULL;*/
636   XBT_INFO("**************************");
637   XBT_INFO("*** DEAD-LOCK DETECTED ***");
638   XBT_INFO("**************************");
639   XBT_INFO("Locked request:");
640   /*req_str = MC_request_to_string(req);
641     XBT_INFO("%s", req_str);
642     xbt_free(req_str);*/
643   XBT_INFO("Counter-example execution trace:");
644   MC_dump_stack_safety(mc_stack_safety);
645 }
646
647
648 void MC_show_stack_liveness(xbt_fifo_t stack){
649   int value;
650   mc_pair_stateless_t pair;
651   xbt_fifo_item_t item;
652   smx_simcall_t req;
653   char *req_str = NULL;
654   
655   for (item = xbt_fifo_get_last_item(stack);
656        (item ? (pair = (mc_pair_stateless_t) (xbt_fifo_get_item_content(item)))
657         : (NULL)); item = xbt_fifo_get_prev_item(item)) {
658     req = MC_state_get_executed_request(pair->graph_state, &value);
659     if(req){
660       if(pair->requests>0){
661         req_str = MC_request_to_string(req, value);
662         XBT_INFO("%s", req_str);
663         xbt_free(req_str);
664       }else{
665         XBT_INFO("End of system requests but evolution in Büchi automaton");
666       }
667     }
668   }
669 }
670
671 void MC_dump_stack_liveness(xbt_fifo_t stack){
672
673   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
674
675   mc_pair_stateless_t pair;
676
677   MC_SET_RAW_MEM;
678   while ((pair = (mc_pair_stateless_t) xbt_fifo_pop(stack)) != NULL)
679     pair_stateless_free(pair);
680   MC_UNSET_RAW_MEM;
681
682   if(raw_mem_set)
683     MC_SET_RAW_MEM;
684
685 }
686
687
688 void MC_print_statistics(mc_stats_t stats)
689 {
690   //XBT_INFO("State space size ~= %lu", stats->state_size);
691   XBT_INFO("Expanded states = %lu", stats->expanded_states);
692   XBT_INFO("Visited states = %lu", stats->visited_states);
693   XBT_INFO("Executed transitions = %lu", stats->executed_transitions);
694   XBT_INFO("Expanded / Visited = %lf",
695            (double) stats->visited_states / stats->expanded_states);
696   /*XBT_INFO("Exploration coverage = %lf",
697     (double)stats->expanded_states / stats->state_size); */
698 }
699
700 void MC_print_statistics_pairs(mc_stats_pair_t stats)
701 {
702   XBT_INFO("Expanded pairs = %lu", stats->expanded_pairs);
703   XBT_INFO("Visited pairs = %lu", stats->visited_pairs);
704   //XBT_INFO("Executed transitions = %lu", stats->executed_transitions);
705   XBT_INFO("Expanded / Visited = %lf",
706            (double) stats->visited_pairs / stats->expanded_pairs);
707
708   if(mmalloc_get_current_heap() == raw_heap)
709     MC_UNSET_RAW_MEM;
710 }
711
712 void MC_assert(int prop)
713 {
714   if (MC_is_active() && !prop){
715     XBT_INFO("**************************");
716     XBT_INFO("*** PROPERTY NOT VALID ***");
717     XBT_INFO("**************************");
718     XBT_INFO("Counter-example execution trace:");
719     MC_dump_stack_safety(mc_stack_safety);
720     MC_print_statistics(mc_stats);
721     xbt_abort();
722   }
723 }
724
725 static void MC_assert_pair(int prop){
726   if (MC_is_active() && !prop) {
727     XBT_INFO("**************************");
728     XBT_INFO("*** PROPERTY NOT VALID ***");
729     XBT_INFO("**************************");
730     //XBT_INFO("Counter-example execution trace:");
731     MC_show_stack_liveness(mc_stack_liveness);
732     //MC_dump_snapshot_stack(mc_snapshot_stack);
733     MC_print_statistics_pairs(mc_stats_pair);
734     xbt_abort();
735   }
736 }
737
738 void MC_process_clock_add(smx_process_t process, double amount)
739 {
740   mc_time[process->pid] += amount;
741 }
742
743 double MC_process_clock_get(smx_process_t process)
744 {
745   if(mc_time){
746     if(process != NULL)
747       return mc_time[process->pid];
748     else 
749       return -1;
750   }else{
751     return 0;
752   }
753 }
754
755 void MC_automaton_load(const char *file){
756
757   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
758
759   MC_SET_RAW_MEM;
760
761   if (_mc_property_automaton == NULL)
762     _mc_property_automaton = xbt_automaton_new();
763   
764   xbt_automaton_load(_mc_property_automaton,file);
765
766   MC_UNSET_RAW_MEM;
767
768   if(raw_mem_set)
769     MC_SET_RAW_MEM;
770
771 }
772
773 void MC_automaton_new_propositional_symbol(const char* id, void* fct) {
774
775   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
776
777   MC_SET_RAW_MEM;
778
779   if (_mc_property_automaton == NULL)
780     _mc_property_automaton = xbt_automaton_new();
781
782   xbt_new_propositional_symbol(_mc_property_automaton,id,fct);
783
784   MC_UNSET_RAW_MEM;
785
786   if(raw_mem_set)
787     MC_SET_RAW_MEM;
788   
789 }
790
791 /************ MC_ignore ***********/ 
792
793 void heap_ignore_region_free(mc_heap_ignore_region_t r){
794   xbt_free(r);
795 }
796
797 void heap_ignore_region_free_voidp(void *r){
798   heap_ignore_region_free((mc_heap_ignore_region_t) * (void **) r);
799 }
800
801 void MC_ignore_heap(void *address, size_t size){
802
803   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
804
805   MC_SET_RAW_MEM;
806
807   mc_heap_ignore_region_t region = NULL;
808   region = xbt_new0(s_mc_heap_ignore_region_t, 1);
809   region->address = address;
810   region->size = size;
811   
812   region->block = ((char*)address - (char*)((xbt_mheap_t)std_heap)->heapbase) / BLOCKSIZE + 1;
813   
814   if(((xbt_mheap_t)std_heap)->heapinfo[region->block].type == 0){
815     region->fragment = -1;
816     ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_block.ignore = 1;
817   }else{
818     region->fragment = ((uintptr_t) (ADDR2UINT (address) % (BLOCKSIZE))) >> ((xbt_mheap_t)std_heap)->heapinfo[region->block].type;
819     ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_frag.ignore[region->fragment] = 1;
820   }
821   
822   if(mc_heap_comparison_ignore == NULL){
823     mc_heap_comparison_ignore = xbt_dynar_new(sizeof(mc_heap_ignore_region_t), heap_ignore_region_free_voidp);
824     xbt_dynar_push(mc_heap_comparison_ignore, &region);
825     if(!raw_mem_set)
826       MC_UNSET_RAW_MEM;
827     return;
828   }
829
830   unsigned int cursor = 0;
831   mc_heap_ignore_region_t current_region;
832   int start = 0;
833   int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
834   
835   while(start <= end){
836     cursor = (start + end) / 2;
837     current_region = (mc_heap_ignore_region_t)xbt_dynar_get_as(mc_heap_comparison_ignore, cursor, mc_heap_ignore_region_t);
838     if(current_region->address == address){
839       heap_ignore_region_free(region);
840       if(!raw_mem_set)
841         MC_UNSET_RAW_MEM;
842       return;
843     }
844     if(current_region->address < address)
845       start = cursor + 1;
846     if(current_region->address > address)
847       end = cursor - 1;   
848   }
849
850   if(current_region->address < address)
851     xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor + 1, &region);
852   else
853     xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, &region);
854
855   MC_UNSET_RAW_MEM;
856
857   if(raw_mem_set)
858     MC_SET_RAW_MEM;
859 }
860
861 void MC_remove_ignore_heap(void *address, size_t size){
862
863   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
864
865   MC_SET_RAW_MEM;
866   
867   unsigned int cursor = 0;
868   int start = 0;
869   int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
870   mc_heap_ignore_region_t region;
871   int ignore_found = 0;
872
873   while(start <= end){
874     cursor = (start + end) / 2;
875     region = (mc_heap_ignore_region_t)xbt_dynar_get_as(mc_heap_comparison_ignore, cursor, mc_heap_ignore_region_t);
876     if(region->address == address){
877       ignore_found = 1;
878       break;
879     }
880     if(region->address < address)
881       start = cursor + 1;
882     if(region->address > address){
883       if((char * )region->address <= ((char *)address + size)){
884         ignore_found = 1;
885         break;
886       }else
887         end = cursor - 1;   
888     }
889   }
890   
891   if(ignore_found == 1){
892     xbt_dynar_remove_at(mc_heap_comparison_ignore, cursor, NULL);
893     MC_remove_ignore_heap(address, size);
894   }
895
896   MC_UNSET_RAW_MEM;
897   
898   if(raw_mem_set)
899     MC_SET_RAW_MEM;
900
901 }
902
903 void MC_ignore_data_bss(void *address, size_t size){
904
905   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
906
907   MC_SET_RAW_MEM;
908   
909   if(mc_data_bss_comparison_ignore == NULL)
910     mc_data_bss_comparison_ignore = xbt_dynar_new(sizeof(mc_data_bss_ignore_variable_t), NULL);
911
912   mc_data_bss_ignore_variable_t var = NULL;
913   var = xbt_new0(s_mc_data_bss_ignore_variable_t, 1);
914   var->address = address;
915   var->size = size;
916
917   if(xbt_dynar_is_empty(mc_data_bss_comparison_ignore)){
918
919     xbt_dynar_insert_at(mc_data_bss_comparison_ignore, 0, &var);
920
921   }else{
922     
923     unsigned int cursor = 0;
924     int start = 0;
925     int end = xbt_dynar_length(mc_data_bss_comparison_ignore) - 1;
926     mc_data_bss_ignore_variable_t current_var = NULL;
927
928     while(start <= end){
929       cursor = (start + end) / 2;
930       current_var = (mc_data_bss_ignore_variable_t)xbt_dynar_get_as(mc_data_bss_comparison_ignore, cursor, mc_data_bss_ignore_variable_t);
931       if(current_var->address == address){
932         MC_UNSET_RAW_MEM;
933         if(raw_mem_set)
934           MC_SET_RAW_MEM;
935         return;
936       }
937       if(current_var->address < address)
938         start = cursor + 1;
939       if(current_var->address > address)
940         end = cursor - 1;
941     }
942
943     if(current_var->address < address)
944       xbt_dynar_insert_at(mc_data_bss_comparison_ignore, cursor + 1, &var);
945     else
946       xbt_dynar_insert_at(mc_data_bss_comparison_ignore, cursor, &var);
947
948   }
949
950   /* Remove variable from mc_global_variables */
951
952   if(mc_global_variables != NULL){
953
954     unsigned int cursor = 0;
955     int start = 0;
956     int end = xbt_dynar_length(mc_global_variables) - 1;
957     global_variable_t current_var;
958     int var_found;
959
960     while(start <= end){
961       cursor = (start + end) / 2;
962       current_var = (global_variable_t)xbt_dynar_get_as(mc_global_variables, cursor, global_variable_t);
963       if(current_var->address == var->address){
964         var_found = 1;
965         break;
966       }
967       if(current_var->address < address)
968         start = cursor + 1;
969       if(current_var->address > address)
970         end = cursor - 1;
971     }
972
973     if(var_found)
974       xbt_dynar_remove_at(mc_global_variables, cursor, NULL);
975     
976   }
977
978   MC_UNSET_RAW_MEM;
979
980   if(raw_mem_set)
981     MC_SET_RAW_MEM;
982 }
983
984 static size_t data_bss_ignore_size(void *address){
985   unsigned int cursor = 0;
986   int start = 0;
987   int end = xbt_dynar_length(mc_data_bss_comparison_ignore) - 1;
988   mc_data_bss_ignore_variable_t var;
989
990   while(start <= end){
991     cursor = (start + end) / 2;
992     var = (mc_data_bss_ignore_variable_t)xbt_dynar_get_as(mc_data_bss_comparison_ignore, cursor, mc_data_bss_ignore_variable_t);
993     if(var->address == address)
994       return var->size;
995     if(var->address < address){
996       if((void *)((char *)var->address + var->size) > address)
997         return (char *)var->address + var->size - (char*)address;
998       else
999         start = cursor + 1;
1000     }
1001     if(var->address > address)
1002       end = cursor - 1;   
1003   }
1004
1005   return 0;
1006 }
1007
1008
1009
1010 void MC_ignore_stack(const char *var_name, const char *frame_name){
1011   
1012   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
1013
1014   MC_SET_RAW_MEM;
1015
1016   if(mc_stack_comparison_ignore == NULL)
1017     mc_stack_comparison_ignore = xbt_dynar_new(sizeof(mc_stack_ignore_variable_t), NULL);
1018
1019   if(xbt_dynar_is_empty(mc_stack_comparison_ignore)){
1020
1021     mc_stack_ignore_variable_t var = NULL;
1022     var = xbt_new0(s_mc_stack_ignore_variable_t, 1);
1023     var->var_name = strdup(var_name);
1024     var->frame = strdup(frame_name);
1025
1026     xbt_dynar_insert_at(mc_stack_comparison_ignore, 0, &var);
1027
1028   }else{
1029     
1030     unsigned int cursor = 0;
1031     int start = 0;
1032     int end = xbt_dynar_length(mc_stack_comparison_ignore) - 1;
1033     mc_stack_ignore_variable_t current_var = NULL;
1034
1035     while(start <= end){
1036       cursor = (start + end) / 2;
1037       current_var = (mc_stack_ignore_variable_t)xbt_dynar_get_as(mc_stack_comparison_ignore, cursor, mc_stack_ignore_variable_t);
1038       if(strcmp(current_var->frame, frame_name) == 0){
1039         if(strcmp(current_var->var_name, var_name) == 0){
1040           MC_UNSET_RAW_MEM;
1041           if(raw_mem_set)
1042             MC_SET_RAW_MEM;
1043           return;
1044         }
1045         if(strcmp(current_var->var_name, var_name) < 0)
1046           start = cursor + 1;
1047         if(strcmp(current_var->var_name, var_name) > 0)
1048           end = cursor - 1;
1049       }
1050       if(strcmp(current_var->frame, frame_name) < 0)
1051         start = cursor + 1;
1052       if(strcmp(current_var->frame, frame_name) > 0)
1053         end = cursor - 1;
1054     }
1055
1056     mc_stack_ignore_variable_t var = NULL;
1057     var = xbt_new0(s_mc_stack_ignore_variable_t, 1);
1058     var->var_name = strdup(var_name);
1059     var->frame = strdup(frame_name);
1060
1061     if(strcmp(current_var->frame, frame_name) < 0)
1062       xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor + 1, &var);
1063     else
1064       xbt_dynar_insert_at(mc_stack_comparison_ignore, cursor, &var);
1065
1066   }
1067
1068  /* Remove variable from mc_local_variables */
1069
1070   if(mc_local_variables != NULL){
1071
1072     if(strcmp(frame_name, "*") != 0){
1073       dw_frame_t frame = xbt_dict_get_or_null(mc_local_variables, frame_name);
1074       if(frame != NULL)
1075         xbt_dict_remove(frame->variables, var_name);
1076     }
1077
1078   }
1079
1080   MC_UNSET_RAW_MEM;
1081   
1082   if(raw_mem_set)
1083     MC_SET_RAW_MEM;
1084
1085 }
1086
1087 void MC_new_stack_area(void *stack, char *name, void* context, size_t size){
1088
1089   int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
1090
1091   MC_SET_RAW_MEM;
1092   if(stacks_areas == NULL)
1093     stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
1094   
1095   stack_region_t region = NULL;
1096   region = xbt_new0(s_stack_region_t, 1);
1097   region->address = stack;
1098   region->process_name = strdup(name);
1099   region->context = context;
1100   region->size = size;
1101   region->block = ((char*)stack - (char*)((xbt_mheap_t)std_heap)->heapbase) / BLOCKSIZE + 1;
1102   xbt_dynar_push(stacks_areas, &region);
1103   
1104   MC_UNSET_RAW_MEM;
1105
1106   if(raw_mem_set)
1107     MC_SET_RAW_MEM;
1108 }
1109
1110 /************ DWARF ***********/
1111
1112 xbt_dict_t MC_get_location_list(const char *elf_file){
1113
1114   char *command = bprintf("objdump -Wo %s", elf_file);
1115
1116   FILE *fp = popen(command, "r");
1117
1118   if(fp == NULL){
1119     perror("popen for objdump failed");
1120     xbt_abort();
1121   }
1122
1123   int debug = 0; /*Detect if the program has been compiled with -g */
1124
1125   xbt_dict_t location_list = xbt_dict_new_homogeneous(NULL);
1126   char *line = NULL, *loc_expr = NULL;
1127   ssize_t read;
1128   size_t n = 0;
1129   int cursor_remove;
1130   xbt_dynar_t split = NULL;
1131
1132   while ((read = xbt_getline(&line, &n, fp)) != -1) {
1133
1134     /* Wipeout the new line character */
1135     line[read - 1] = '\0';
1136
1137     xbt_str_trim(line, NULL);
1138     
1139     if(n == 0)
1140       continue;
1141
1142     if(strlen(line) == 0)
1143       continue;
1144
1145     if(debug == 0){
1146
1147       if(strncmp(line, elf_file, strlen(elf_file)) == 0)
1148         continue;
1149       
1150       if(strncmp(line, "Contents", 8) == 0)
1151         continue;
1152
1153       if(strncmp(line, "Offset", 6) == 0){
1154         debug = 1;
1155         continue;
1156       }
1157     }
1158
1159     if(debug == 0){
1160       XBT_INFO("Your program must be compiled with -g");
1161       xbt_abort();
1162     }
1163
1164     xbt_dynar_t loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL);
1165
1166     xbt_str_strip_spaces(line);
1167     split = xbt_str_split(line, " ");
1168
1169     while(read != -1 && strcmp("<End", (char *)xbt_dynar_get_as(split, 1, char *)) != 0){
1170       
1171       dw_location_entry_t new_entry = xbt_new0(s_dw_location_entry_t, 1);
1172       new_entry->lowpc = strtoul((char *)xbt_dynar_get_as(split, 1, char *), NULL, 16);
1173       new_entry->highpc = strtoul((char *)xbt_dynar_get_as(split, 2, char *), NULL, 16);
1174       
1175       cursor_remove =0;
1176       while(cursor_remove < 3){
1177         xbt_dynar_remove_at(split, 0, NULL);
1178         cursor_remove++;
1179       }
1180
1181       loc_expr = xbt_str_join(split, " ");
1182       xbt_str_ltrim(loc_expr, "(");
1183       xbt_str_rtrim(loc_expr, ")");
1184       new_entry->location = get_location(NULL, loc_expr);
1185
1186       xbt_dynar_push(loclist, &new_entry);
1187
1188       xbt_dynar_free(&split);
1189       free(loc_expr);
1190
1191       read = xbt_getline(&line, &n, fp);
1192       if(read != -1){
1193         line[read - 1] = '\0';
1194         xbt_str_strip_spaces(line);
1195         split = xbt_str_split(line, " ");
1196       }
1197
1198     }
1199
1200
1201     char *key = bprintf("%d", (int)strtoul((char *)xbt_dynar_get_as(split, 0, char *), NULL, 16));
1202     xbt_dict_set(location_list, key, loclist, NULL);
1203     xbt_free(key);
1204     
1205     xbt_dynar_free(&split);
1206
1207   }
1208
1209   xbt_free(line);
1210   xbt_free(command);
1211   pclose(fp);
1212
1213   return location_list;
1214 }
1215
1216 static dw_frame_t get_frame_by_offset(xbt_dict_t all_variables, unsigned long int offset){
1217
1218   xbt_dict_cursor_t cursor = NULL;
1219   char *name;
1220   dw_frame_t res;
1221
1222   xbt_dict_foreach(all_variables, cursor, name, res) {
1223     if(offset >= res->start && offset < res->end){
1224       xbt_dict_cursor_free(&cursor);
1225       return res;
1226     }
1227   }
1228
1229   xbt_dict_cursor_free(&cursor);
1230   return NULL;
1231   
1232 }
1233
1234 void MC_get_local_variables(const char *elf_file, xbt_dict_t location_list, xbt_dict_t *all_variables){
1235
1236   char *command = bprintf("objdump -Wi %s", elf_file);
1237   
1238   FILE *fp = popen(command, "r");
1239
1240   if(fp == NULL)
1241     perror("popen for objdump failed");
1242
1243   char *line = NULL, *origin, *abstract_origin, *current_frame = NULL;
1244   ssize_t read =0;
1245   size_t n = 0;
1246   int valid_variable = 1;
1247   char *node_type = NULL, *location_type = NULL, *variable_name = NULL, *loc_expr = NULL;
1248   xbt_dynar_t split = NULL, split2 = NULL;
1249
1250   xbt_dict_t variables_origin = xbt_dict_new_homogeneous(NULL);
1251   xbt_dict_t subprograms_origin = xbt_dict_new_homogeneous(NULL);
1252   char *subprogram_name = NULL, *subprogram_start = NULL, *subprogram_end = NULL;
1253   int new_frame = 0, new_variable = 0;
1254   dw_frame_t variable_frame, subroutine_frame = NULL;
1255
1256   read = xbt_getline(&line, &n, fp);
1257
1258   while (read != -1) {
1259
1260     if(n == 0){
1261       read = xbt_getline(&line, &n, fp);
1262       continue;
1263     }
1264  
1265     /* Wipeout the new line character */
1266     line[read - 1] = '\0';
1267    
1268     if(strlen(line) == 0){
1269       read = xbt_getline(&line, &n, fp);
1270       continue;
1271     }
1272
1273     xbt_str_ltrim(line, NULL);
1274     xbt_str_strip_spaces(line);
1275     
1276     if(line[0] != '<'){
1277       read = xbt_getline(&line, &n, fp);
1278       continue;
1279     }
1280     
1281     xbt_dynar_free(&split);
1282     split = xbt_str_split(line, " ");
1283
1284     /* Get node type */
1285     node_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *);
1286
1287     if(strcmp(node_type, "(DW_TAG_subprogram)") == 0){ /* New frame */
1288
1289       dw_frame_t frame = NULL;
1290
1291       strtok(xbt_dynar_get_as(split, 0, char *), "<");
1292       subprogram_start = strdup(strtok(NULL, "<"));
1293       xbt_str_rtrim(subprogram_start, ">:");
1294
1295       read = xbt_getline(&line, &n, fp);
1296    
1297       while(read != -1){
1298
1299         if(n == 0){
1300           read = xbt_getline(&line, &n, fp);
1301           continue;
1302         }
1303
1304         /* Wipeout the new line character */
1305         line[read - 1] = '\0';
1306         
1307         if(strlen(line) == 0){
1308           read = xbt_getline(&line, &n, fp);
1309           continue;
1310         }
1311       
1312         xbt_dynar_free(&split);
1313         xbt_str_rtrim(line, NULL);
1314         xbt_str_strip_spaces(line);
1315         split = xbt_str_split(line, " ");
1316           
1317         node_type = xbt_dynar_get_as(split, 1, char *);
1318
1319         if(strncmp(node_type, "DW_AT_", 6) != 0)
1320           break;
1321
1322         if(strcmp(node_type, "DW_AT_sibling") == 0){
1323
1324           subprogram_end = strdup(xbt_dynar_get_as(split, 3, char*));
1325           xbt_str_ltrim(subprogram_end, "<0x");
1326           xbt_str_rtrim(subprogram_end, ">");
1327           
1328         }else if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){ /* Frame already in dict */
1329           
1330           new_frame = 0;
1331           abstract_origin = strdup(xbt_dynar_get_as(split, 2, char*));
1332           xbt_str_ltrim(abstract_origin, "<0x");
1333           xbt_str_rtrim(abstract_origin, ">");
1334           subprogram_name = (char *)xbt_dict_get_or_null(subprograms_origin, abstract_origin);
1335           frame = xbt_dict_get_or_null(*all_variables, subprogram_name); 
1336           xbt_free(abstract_origin);
1337
1338         }else if(strcmp(node_type, "DW_AT_name") == 0){
1339
1340           new_frame = 1;
1341           xbt_free(current_frame);
1342           frame = xbt_new0(s_dw_frame_t, 1);
1343           frame->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *)); 
1344           frame->variables = xbt_dict_new_homogeneous(NULL);
1345           frame->frame_base = xbt_new0(s_dw_location_t, 1); 
1346           current_frame = strdup(frame->name);
1347
1348           xbt_dict_set(subprograms_origin, subprogram_start, frame->name, NULL);
1349         
1350         }else if(strcmp(node_type, "DW_AT_frame_base") == 0){
1351
1352           location_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *);
1353
1354           if(strcmp(location_type, "list)") == 0){ /* Search location in location list */
1355
1356             frame->frame_base = get_location(location_list, xbt_dynar_get_as(split, 3, char *));
1357              
1358           }else{
1359                 
1360             xbt_str_strip_spaces(line);
1361             split2 = xbt_str_split(line, "(");
1362             xbt_dynar_remove_at(split2, 0, NULL);
1363             loc_expr = xbt_str_join(split2, " ");
1364             xbt_str_rtrim(loc_expr, ")");
1365             frame->frame_base = get_location(NULL, loc_expr);
1366             xbt_dynar_free(&split2);
1367             xbt_free(loc_expr);
1368
1369           }
1370  
1371         }else if(strcmp(node_type, "DW_AT_low_pc") == 0){
1372           
1373           if(frame != NULL)
1374             frame->low_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
1375
1376         }else if(strcmp(node_type, "DW_AT_high_pc") == 0){
1377
1378           if(frame != NULL)
1379             frame->high_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
1380
1381         }else if(strcmp(node_type, "DW_AT_MIPS_linkage_name:") == 0){
1382
1383           xbt_free(frame->name);
1384           xbt_free(current_frame);
1385           frame->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *));   
1386           current_frame = strdup(frame->name);
1387           xbt_dict_set(subprograms_origin, subprogram_start, frame->name, NULL);
1388
1389         }
1390
1391         read = xbt_getline(&line, &n, fp);
1392
1393       }
1394  
1395       if(new_frame == 1){
1396         frame->start = strtoul(subprogram_start, NULL, 16);
1397         if(subprogram_end != NULL)
1398           frame->end = strtoul(subprogram_end, NULL, 16);
1399         xbt_dict_set(*all_variables, frame->name, frame, NULL);
1400       }
1401
1402       xbt_free(subprogram_start);
1403       xbt_free(subprogram_end);
1404       subprogram_end = NULL;
1405         
1406
1407     }else if(strcmp(node_type, "(DW_TAG_variable)") == 0){ /* New variable */
1408
1409       dw_local_variable_t var = NULL;
1410       
1411       strtok(xbt_dynar_get_as(split, 0, char *), "<");
1412       origin = strdup(strtok(NULL, "<"));
1413       xbt_str_rtrim(origin, ">:");
1414       
1415       read = xbt_getline(&line, &n, fp);
1416       
1417       while(read != -1){
1418
1419         if(n == 0){
1420           read = xbt_getline(&line, &n, fp);
1421           continue;
1422         }
1423
1424         /* Wipeout the new line character */
1425         line[read - 1] = '\0'; 
1426
1427         if(strlen(line) == 0){
1428           read = xbt_getline(&line, &n, fp);
1429           continue;
1430         }
1431        
1432         xbt_dynar_free(&split);
1433         xbt_str_rtrim(line, NULL);
1434         xbt_str_strip_spaces(line);
1435         split = xbt_str_split(line, " ");
1436   
1437         node_type = xbt_dynar_get_as(split, 1, char *);
1438
1439         if(strncmp(node_type, "DW_AT_", 6) != 0)
1440           break;
1441
1442         if(strcmp(node_type, "DW_AT_name") == 0){
1443
1444           new_variable = 1;
1445           var = xbt_new0(s_dw_local_variable_t, 1);
1446           var->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *));
1447
1448           xbt_dict_set(variables_origin, origin, var->name, NULL);
1449          
1450         }else if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){
1451
1452           new_variable = 0;
1453           abstract_origin = xbt_dynar_get_as(split, 2, char *);
1454           xbt_str_ltrim(abstract_origin, "<0x");
1455           xbt_str_rtrim(abstract_origin, ">");
1456           
1457           variable_name = (char *)xbt_dict_get_or_null(variables_origin, abstract_origin);
1458           variable_frame = get_frame_by_offset(*all_variables, strtoul(abstract_origin, NULL, 16));
1459           var = xbt_dict_get_or_null(variable_frame->variables, variable_name);   
1460
1461         }else if(strcmp(node_type, "DW_AT_location") == 0){
1462
1463           if(valid_variable == 1 && var != NULL){
1464
1465             var->location = xbt_new0(s_dw_location_t, 1);
1466
1467             location_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *);
1468
1469             if(strcmp(location_type, "list)") == 0){ /* Search location in location list */
1470
1471               var->location = get_location(location_list, xbt_dynar_get_as(split, 3, char *));
1472              
1473             }else{
1474                 
1475               xbt_str_strip_spaces(line);
1476               split2 = xbt_str_split(line, "(");
1477               xbt_dynar_remove_at(split2, 0, NULL);
1478               loc_expr = xbt_str_join(split2, " ");
1479               xbt_str_rtrim(loc_expr, ")");
1480               var->location = get_location(NULL, loc_expr);
1481               xbt_dynar_free(&split2);
1482               xbt_free(loc_expr);
1483
1484             }
1485
1486           }
1487            
1488         }else if(strcmp(node_type, "DW_AT_external") == 0){
1489
1490           valid_variable = 0;
1491         
1492         }
1493
1494         read = xbt_getline(&line, &n, fp);
1495  
1496       }
1497
1498       if(new_variable == 1 && valid_variable == 1){
1499         
1500         variable_frame = xbt_dict_get_or_null(*all_variables, current_frame);
1501         xbt_dict_set(variable_frame->variables, var->name, var, NULL);
1502       }
1503
1504       valid_variable = 1;
1505       new_variable = 0;
1506
1507     }else if(strcmp(node_type, "(DW_TAG_inlined_subroutine)") == 0){
1508
1509       strtok(xbt_dynar_get_as(split, 0, char *), "<");
1510       origin = strdup(strtok(NULL, "<"));
1511       xbt_str_rtrim(origin, ">:");
1512
1513       read = xbt_getline(&line, &n, fp);
1514
1515       while(read != -1){
1516
1517         /* Wipeout the new line character */
1518         line[read - 1] = '\0'; 
1519
1520         if(n == 0){
1521           read = xbt_getline(&line, &n, fp);
1522           continue;
1523         }
1524
1525         if(strlen(line) == 0){
1526           read = xbt_getline(&line, &n, fp);
1527           continue;
1528         }
1529
1530         xbt_dynar_free(&split);
1531         xbt_str_rtrim(line, NULL);
1532         xbt_str_strip_spaces(line);
1533         split = xbt_str_split(line, " ");
1534         
1535         if(strncmp(xbt_dynar_get_as(split, 1, char *), "DW_AT_", 6) != 0)
1536           break;
1537           
1538         node_type = xbt_dynar_get_as(split, 1, char *);
1539
1540         if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){
1541
1542           origin = xbt_dynar_get_as(split, 2, char *);
1543           xbt_str_ltrim(origin, "<0x");
1544           xbt_str_rtrim(origin, ">");
1545           
1546           subprogram_name = (char *)xbt_dict_get_or_null(subprograms_origin, origin);
1547           subroutine_frame = xbt_dict_get_or_null(*all_variables, subprogram_name);
1548         
1549         }else if(strcmp(node_type, "DW_AT_low_pc") == 0){
1550
1551           subroutine_frame->low_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
1552
1553         }else if(strcmp(node_type, "DW_AT_high_pc") == 0){
1554
1555           subroutine_frame->high_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
1556         }
1557
1558         read = xbt_getline(&line, &n, fp);
1559       
1560       }
1561
1562     }else{
1563
1564       read = xbt_getline(&line, &n, fp);
1565
1566     }
1567
1568   }
1569   
1570   xbt_dynar_free(&split);
1571   xbt_free(line);
1572   xbt_free(command);
1573   pclose(fp);
1574   
1575 }
1576
1577 static dw_location_t get_location(xbt_dict_t location_list, char *expr){
1578
1579   dw_location_t loc = xbt_new0(s_dw_location_t, 1);
1580
1581   if(location_list != NULL){
1582     
1583     char *key = bprintf("%d", (int)strtoul(expr, NULL, 16));
1584     loc->type = e_dw_loclist;
1585     loc->location.loclist =  (xbt_dynar_t)xbt_dict_get_or_null(location_list, key);
1586     if(loc->location.loclist == NULL)
1587       XBT_INFO("Key not found in loclist");
1588     xbt_free(key);
1589     return loc;
1590
1591   }else{
1592
1593     int cursor = 0;
1594     char *tok = NULL, *tok2 = NULL; 
1595     
1596     xbt_dynar_t tokens1 = xbt_str_split(expr, ";");
1597     xbt_dynar_t tokens2;
1598
1599     loc->type = e_dw_compose;
1600     loc->location.compose = xbt_dynar_new(sizeof(dw_location_t), NULL);
1601
1602     while(cursor < xbt_dynar_length(tokens1)){
1603
1604       tok = xbt_dynar_get_as(tokens1, cursor, char*);
1605       tokens2 = xbt_str_split(tok, " ");
1606       tok2 = xbt_dynar_get_as(tokens2, 0, char*);
1607       
1608       if(strncmp(tok2, "DW_OP_reg", 9) == 0){
1609         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1610         new_element->type = e_dw_register;
1611         new_element->location.reg = atoi(strtok(tok2, "DW_OP_reg"));
1612         xbt_dynar_push(loc->location.compose, &new_element);     
1613       }else if(strcmp(tok2, "DW_OP_fbreg:") == 0){
1614         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1615         new_element->type = e_dw_fbregister_op;
1616         new_element->location.fbreg_op = atoi(xbt_dynar_get_as(tokens2, xbt_dynar_length(tokens2) - 1, char*));
1617         xbt_dynar_push(loc->location.compose, &new_element);
1618       }else if(strncmp(tok2, "DW_OP_breg", 10) == 0){
1619         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1620         new_element->type = e_dw_bregister_op;
1621         new_element->location.breg_op.reg = atoi(strtok(tok2, "DW_OP_breg"));
1622         new_element->location.breg_op.offset = atoi(xbt_dynar_get_as(tokens2, xbt_dynar_length(tokens2) - 1, char*));
1623         xbt_dynar_push(loc->location.compose, &new_element);
1624       }else if(strncmp(tok2, "DW_OP_lit", 9) == 0){
1625         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1626         new_element->type = e_dw_lit;
1627         new_element->location.lit = atoi(strtok(tok2, "DW_OP_lit"));
1628         xbt_dynar_push(loc->location.compose, &new_element);
1629       }else if(strcmp(tok2, "DW_OP_piece:") == 0){
1630         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1631         new_element->type = e_dw_piece;
1632         new_element->location.piece = atoi(xbt_dynar_get_as(tokens2, xbt_dynar_length(tokens2) - 1, char*));
1633         /*if(strlen(xbt_dynar_get_as(tokens2, 1, char*)) > 1)
1634           new_element->location.piece = atoi(xbt_dynar_get_as(tokens2, 1, char*));
1635         else
1636         new_element->location.piece = xbt_dynar_get_as(tokens2, 1, char*)[0] - '0';*/
1637         xbt_dynar_push(loc->location.compose, &new_element);
1638       }else if(strcmp(tok2, "DW_OP_plus_uconst:") == 0){
1639         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1640         new_element->type = e_dw_plus_uconst;
1641         new_element->location.plus_uconst = atoi(xbt_dynar_get_as(tokens2, xbt_dynar_length(tokens2) - 1, char *));
1642         xbt_dynar_push(loc->location.compose, &new_element);
1643       }else if(strcmp(tok, "DW_OP_abs") == 0 || 
1644                strcmp(tok, "DW_OP_and") == 0 ||
1645                strcmp(tok, "DW_OP_div") == 0 ||
1646                strcmp(tok, "DW_OP_minus") == 0 ||
1647                strcmp(tok, "DW_OP_mod") == 0 ||
1648                strcmp(tok, "DW_OP_mul") == 0 ||
1649                strcmp(tok, "DW_OP_neg") == 0 ||
1650                strcmp(tok, "DW_OP_not") == 0 ||
1651                strcmp(tok, "DW_OP_or") == 0 ||
1652                strcmp(tok, "DW_OP_plus") == 0){               
1653         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1654         new_element->type = e_dw_arithmetic;
1655         new_element->location.arithmetic = strdup(strtok(tok2, "DW_OP_"));
1656         xbt_dynar_push(loc->location.compose, &new_element);
1657       }else if(strcmp(tok, "DW_OP_stack_value") == 0){
1658       }else if(strcmp(tok2, "DW_OP_deref_size:") == 0){
1659         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1660         new_element->type = e_dw_deref;
1661         new_element->location.deref_size = (unsigned int short) atoi(xbt_dynar_get_as(tokens2, xbt_dynar_length(tokens2) - 1, char*));
1662         /*if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
1663           new_element->location.deref_size = atoi(xbt_dynar_get_as(tokens, cursor, char*));
1664         else
1665         new_element->location.deref_size = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';*/
1666         xbt_dynar_push(loc->location.compose, &new_element);
1667       }else if(strcmp(tok, "DW_OP_deref") == 0){
1668         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1669         new_element->type = e_dw_deref;
1670         new_element->location.deref_size = sizeof(void *);
1671         xbt_dynar_push(loc->location.compose, &new_element);
1672       }else if(strcmp(tok2, "DW_OP_constu:") == 0){
1673         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1674         new_element->type = e_dw_uconstant;
1675         new_element->location.uconstant.bytes = 1;
1676         new_element->location.uconstant.value = (unsigned long int)(atoi(xbt_dynar_get_as(tokens2, xbt_dynar_length(tokens2) - 1, char*)));
1677         /*if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
1678           new_element->location.uconstant.value = (unsigned long int)(atoi(xbt_dynar_get_as(tokens, cursor, char*)));
1679         else
1680         new_element->location.uconstant.value = (unsigned long int)(xbt_dynar_get_as(tokens, cursor, char*)[0] - '0');*/
1681         xbt_dynar_push(loc->location.compose, &new_element);
1682       }else if(strcmp(tok2, "DW_OP_consts:") == 0){
1683         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1684         new_element->type = e_dw_sconstant;
1685         new_element->location.sconstant.bytes = 1;
1686         new_element->location.sconstant.value = (long int)(atoi(xbt_dynar_get_as(tokens2, xbt_dynar_length(tokens2) - 1, char*)));
1687         xbt_dynar_push(loc->location.compose, &new_element);
1688       }else if(strcmp(tok2, "DW_OP_const1u:") == 0 ||
1689                strcmp(tok2, "DW_OP_const2u:") == 0 ||
1690                strcmp(tok2, "DW_OP_const4u:") == 0 ||
1691                strcmp(tok2, "DW_OP_const8u:") == 0){
1692         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1693         new_element->type = e_dw_uconstant;
1694         new_element->location.uconstant.bytes = tok2[11] - '0';
1695         new_element->location.uconstant.value = (unsigned long int)(atoi(xbt_dynar_get_as(tokens2, xbt_dynar_length(tokens2) - 1, char*)));
1696         /*if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
1697           new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, cursor, char*));
1698         else
1699         new_element->location.constant.value = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';*/
1700         xbt_dynar_push(loc->location.compose, &new_element);
1701       }else if(strcmp(tok, "DW_OP_const1s") == 0 ||
1702                strcmp(tok, "DW_OP_const2s") == 0 ||
1703                strcmp(tok, "DW_OP_const4s") == 0 ||
1704                strcmp(tok, "DW_OP_const8s") == 0){
1705         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1706         new_element->type = e_dw_sconstant;
1707         new_element->location.sconstant.bytes = tok2[11] - '0';
1708         new_element->location.sconstant.value = (long int)(atoi(xbt_dynar_get_as(tokens2, xbt_dynar_length(tokens2) - 1, char*)));
1709         xbt_dynar_push(loc->location.compose, &new_element);
1710       }else{
1711         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1712         new_element->type = e_dw_unsupported;
1713         xbt_dynar_push(loc->location.compose, &new_element);
1714       }
1715
1716       cursor++;
1717       xbt_dynar_free(&tokens2);
1718
1719     }
1720     
1721     xbt_dynar_free(&tokens1);
1722
1723     return loc;
1724     
1725   }
1726
1727 }
1728
1729
1730 void print_local_variables(xbt_dict_t list){
1731   
1732   dw_location_entry_t entry;
1733   dw_location_t location_entry;
1734   unsigned int cursor3 = 0, cursor4 = 0;
1735   xbt_dict_cursor_t cursor = 0, cursor2 = 0;
1736
1737   char *frame_name, *variable_name;
1738   dw_frame_t current_frame;
1739   dw_local_variable_t current_variable;
1740
1741   xbt_dict_foreach(list, cursor, frame_name, current_frame){ 
1742     fprintf(stderr, "Frame name : %s\n", current_frame->name);
1743     fprintf(stderr, "Location type : %d\n", current_frame->frame_base->type);
1744     xbt_dict_foreach((xbt_dict_t)current_frame->variables, cursor2, variable_name, current_variable){
1745       fprintf(stderr, "Name : %s\n", current_variable->name);
1746       if(current_variable->location == NULL)
1747         continue;
1748       fprintf(stderr, "Location type : %d\n", current_variable->location->type);
1749       switch(current_variable->location->type){
1750       case e_dw_loclist :
1751         xbt_dynar_foreach(current_variable->location->location.loclist, cursor3, entry){
1752           fprintf(stderr, "Lowpc : %lx, Highpc : %lx,", entry->lowpc, entry->highpc);
1753           switch(entry->location->type){
1754           case e_dw_register :
1755             fprintf(stderr, " Location : in register %d\n", entry->location->location.reg);
1756             break;
1757           case e_dw_bregister_op:
1758             fprintf(stderr, " Location : Add %d to the value in register %d\n", entry->location->location.breg_op.offset, entry->location->location.breg_op.reg);
1759             break;
1760           case e_dw_lit:
1761             fprintf(stderr, "Value already kwnown : %d\n", entry->location->location.lit);
1762             break;
1763           case e_dw_fbregister_op:
1764             fprintf(stderr, " Location : %d bytes from logical frame pointer\n", entry->location->location.fbreg_op);
1765             break;
1766           case e_dw_compose:
1767             fprintf(stderr, " Location :\n");
1768             xbt_dynar_foreach(entry->location->location.compose, cursor4, location_entry){
1769               switch(location_entry->type){
1770               case e_dw_register :
1771                 fprintf(stderr, " %d) in register %d\n", cursor4 + 1, location_entry->location.reg);
1772                 break;
1773               case e_dw_bregister_op:
1774                 fprintf(stderr, " %d) add %d to the value in register %d\n", cursor4 + 1, location_entry->location.breg_op.offset, location_entry->location.breg_op.reg);
1775                 break;
1776               case e_dw_lit:
1777                 fprintf(stderr, "%d) Value already kwnown : %d\n", cursor4 + 1, location_entry->location.lit);
1778                 break;
1779               case e_dw_fbregister_op:
1780                 fprintf(stderr, " %d) %d bytes from logical frame pointer\n", cursor4 + 1, location_entry->location.fbreg_op);
1781                 break;
1782               case e_dw_deref:
1783                 fprintf(stderr, " %d) Pop the stack entry and treats it as an address (size of data %d)\n", cursor4 + 1, location_entry->location.deref_size);
1784                 break;
1785               case e_dw_arithmetic :
1786                 fprintf(stderr, "%d) arithmetic operation : %s\n", cursor4 + 1, location_entry->location.arithmetic);
1787                 break;
1788               case e_dw_piece:
1789                 fprintf(stderr, "%d) The %d byte(s) previous value\n", cursor4 + 1, location_entry->location.piece);
1790                 break;
1791               case e_dw_uconstant :
1792                 fprintf(stderr, "%d) Unsigned constant %lu\n", cursor4 + 1, location_entry->location.uconstant.value);
1793                 break;
1794               case e_dw_sconstant :
1795                 fprintf(stderr, "%d) Signed constant %lu\n", cursor4 + 1, location_entry->location.sconstant.value);
1796                 break;
1797               default :
1798                 fprintf(stderr, "%d) Location type not supported\n", cursor4 + 1);
1799                 break;
1800               }
1801             }
1802             break;
1803           default:
1804             fprintf(stderr, "Location type not supported\n");
1805             break;
1806           }
1807         }
1808         break;
1809       case e_dw_compose:
1810         cursor4 = 0;
1811         fprintf(stderr, "Location :\n");
1812         xbt_dynar_foreach(current_variable->location->location.compose, cursor4, location_entry){
1813           switch(location_entry->type){
1814           case e_dw_register :
1815             fprintf(stderr, " %d) in register %d\n", cursor4 + 1, location_entry->location.reg);
1816             break;
1817           case e_dw_bregister_op:
1818             fprintf(stderr, " %d) add %d to the value in register %d\n", cursor4 + 1, location_entry->location.breg_op.offset, location_entry->location.breg_op.reg);
1819             break;
1820           case e_dw_lit:
1821             fprintf(stderr, "%d) Value already kwnown : %d\n", cursor4 + 1, location_entry->location.lit);
1822             break;
1823           case e_dw_fbregister_op:
1824             fprintf(stderr, " %d) %d bytes from logical frame pointer\n", cursor4 + 1, location_entry->location.fbreg_op);
1825             break;
1826           case e_dw_deref:
1827             fprintf(stderr, " %d) Pop the stack entry and treats it as an address (size of data %d)\n", cursor4 + 1, location_entry->location.deref_size);
1828             break;
1829           case e_dw_arithmetic :
1830             fprintf(stderr, "%d) arithmetic operation : %s\n", cursor4 + 1, location_entry->location.arithmetic);
1831             break;
1832           case e_dw_piece:
1833             fprintf(stderr, "%d) The %d byte(s) previous value\n", cursor4 + 1, location_entry->location.piece);
1834             break;
1835           case e_dw_uconstant :
1836             fprintf(stderr, "%d) Unsigned constant %lu\n", cursor4 + 1, location_entry->location.uconstant.value);
1837             break;
1838           case e_dw_sconstant :
1839             fprintf(stderr, "%d) Signed constant %lu\n", cursor4 + 1, location_entry->location.sconstant.value);
1840             break;
1841           default :
1842             fprintf(stderr, "%d) Location type not supported\n", cursor4 + 1);
1843             break;
1844           }
1845         }
1846         break;
1847       default :
1848         fprintf(stderr, "Location type not supported\n");
1849         break;
1850       }
1851     }
1852   }
1853
1854 }
1855
1856 static void MC_get_global_variables(char *elf_file){
1857
1858   FILE *fp;
1859
1860   char *command = bprintf("objdump -t -j .data -j .bss %s", elf_file);
1861
1862   fp = popen(command, "r");
1863
1864   if(fp == NULL){
1865     perror("popen failed");
1866     xbt_abort();
1867   }
1868
1869   if(mc_global_variables == NULL)
1870     mc_global_variables = xbt_dynar_new(sizeof(global_variable_t), global_variable_free_voidp);
1871
1872   char *line = NULL;
1873   ssize_t read;
1874   size_t n = 0;
1875
1876   xbt_dynar_t line_tokens = NULL;
1877   unsigned long offset;
1878
1879   int type = strcmp(elf_file, xbt_binary_name); /* 0 = binary, other = libsimgrid */
1880
1881   while ((read = xbt_getline(&line, &n, fp)) != -1){
1882
1883     if(n == 0)
1884       continue;
1885
1886      /* Wipeout the new line character */
1887     line[read - 1] = '\0';
1888
1889     xbt_str_strip_spaces(line);
1890     xbt_str_ltrim(line, NULL);
1891
1892     line_tokens = xbt_str_split(line, NULL);
1893
1894     if(xbt_dynar_length(line_tokens) <= 4 || strcmp(xbt_dynar_get_as(line_tokens, 0, char *), "SYMBOL") == 0)
1895       continue;
1896
1897     if((strncmp(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 1, char*), "__gcov", 6) == 0)
1898        || (strncmp(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 1, char*), "gcov", 4) == 0)
1899        || (strcmp(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 1, char*), ".data") == 0)
1900        || (strcmp(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 1, char*), ".bss") == 0)
1901        || (strncmp(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 1, char*), "stderr", 6) == 0)
1902        || ((size_t)strtoul(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 2, char*), NULL, 16) == 0))
1903       continue;
1904
1905     global_variable_t var = xbt_new0(s_global_variable_t, 1);
1906
1907     if(type == 0){
1908       var->address = (void *)strtoul(xbt_dynar_get_as(line_tokens, 0, char*), NULL, 16);
1909     }else{
1910       offset = strtoul(xbt_dynar_get_as(line_tokens, 0, char*), NULL, 16);
1911       var->address = (char *)start_text_libsimgrid+offset;
1912     }
1913
1914     var->size = (size_t)strtoul(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 2, char*), NULL, 16);
1915     var->name = strdup(xbt_dynar_get_as(line_tokens, xbt_dynar_length(line_tokens) - 1, char*));
1916
1917     if(data_bss_ignore_size(var->address) > 0){
1918       global_variable_free(var);
1919     }else{
1920       if(xbt_dynar_is_empty(mc_global_variables)){
1921         xbt_dynar_push(mc_global_variables, &var);
1922       }else{
1923         unsigned int cursor = 0;
1924         int start = 0;
1925         int end = xbt_dynar_length(mc_global_variables) - 1;
1926         global_variable_t current_var = NULL;
1927       
1928         while(start <= end){
1929           cursor = (start + end) / 2;
1930           current_var = (global_variable_t)xbt_dynar_get_as(mc_global_variables, cursor, global_variable_t);
1931           if(current_var->address == var->address)
1932             break;
1933           if(current_var->address < var->address)
1934             start = cursor + 1;
1935           if(current_var->address > var->address)
1936             end = cursor - 1;
1937         }
1938  
1939         if(current_var->address < var->address)
1940           xbt_dynar_insert_at(mc_global_variables, cursor + 1, &var);
1941         else
1942           xbt_dynar_insert_at(mc_global_variables, cursor, &var);
1943       }
1944     }
1945
1946     xbt_dynar_free(&line_tokens);
1947
1948   }
1949
1950   xbt_free(command);
1951   xbt_free(line);
1952   pclose(fp);
1953
1954 }
1955
1956 void global_variable_free(global_variable_t v){
1957   xbt_free(v->name);
1958   xbt_free(v);
1959 }
1960
1961 void global_variable_free_voidp(void *v){
1962   global_variable_free((global_variable_t) * (void **) v);
1963 }