Logo AND Algorithmique Numérique Distribuée

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