Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Remove MCer_ignore_global_variable
[simgrid.git] / src / mc / mcer_ignore.cpp
1 /* Copyright (c) 2008-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <xbt/base.h>
8
9 #include "src/internal_config.h"
10 #include "mc_object_info.h"
11 #include "src/mc/mc_private.h"
12 #include "src/smpi/private.h"
13 #include "src/mc/mc_snapshot.h"
14 #include "src/mc/mc_ignore.h"
15 #include "src/mc/mc_protocol.h"
16 #include "src/mc/mc_client.h"
17
18 #include "src/mc/Frame.hpp"
19 #include "src/mc/Variable.hpp"
20 #include "src/mc/ObjectInformation.hpp"
21
22 extern "C" {
23
24 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mcer_ignore, mc,
25                                 "Logging specific to MC ignore mechanism");
26
27 // ***** Ignore heap chunks
28
29 extern XBT_PRIVATE xbt_dynar_t mc_heap_comparison_ignore;
30
31 static void heap_ignore_region_free(mc_heap_ignore_region_t r)
32 {
33   xbt_free(r);
34 }
35
36 static void heap_ignore_region_free_voidp(void *r)
37 {
38   heap_ignore_region_free((mc_heap_ignore_region_t) * (void **) r);
39 }
40
41
42 XBT_PRIVATE void MC_heap_region_ignore_insert(mc_heap_ignore_region_t region)
43 {
44   if (mc_heap_comparison_ignore == NULL) {
45     mc_heap_comparison_ignore =
46         xbt_dynar_new(sizeof(mc_heap_ignore_region_t),
47                       heap_ignore_region_free_voidp);
48     xbt_dynar_push(mc_heap_comparison_ignore, &region);
49     return;
50   }
51
52   unsigned int cursor = 0;
53   mc_heap_ignore_region_t current_region = NULL;
54   int start = 0;
55   int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
56
57   // Find the position where we want to insert the mc_heap_ignore_region_t:
58   while (start <= end) {
59     cursor = (start + end) / 2;
60     current_region =
61         (mc_heap_ignore_region_t) xbt_dynar_get_as(mc_heap_comparison_ignore,
62                                                    cursor,
63                                                    mc_heap_ignore_region_t);
64     if (current_region->address == region->address) {
65       heap_ignore_region_free(region);
66       return;
67     } else if (current_region->address < region->address) {
68       start = cursor + 1;
69     } else {
70       end = cursor - 1;
71     }
72   }
73
74   // Insert it mc_heap_ignore_region_t:
75   if (current_region->address < region->address)
76     xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor + 1, &region);
77   else
78     xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, &region);
79 }
80
81 XBT_PRIVATE void MC_heap_region_ignore_remove(void *address, size_t size)
82 {
83   unsigned int cursor = 0;
84   int start = 0;
85   int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
86   mc_heap_ignore_region_t region;
87   int ignore_found = 0;
88
89   while (start <= end) {
90     cursor = (start + end) / 2;
91     region =
92         (mc_heap_ignore_region_t) xbt_dynar_get_as(mc_heap_comparison_ignore,
93                                                    cursor,
94                                                    mc_heap_ignore_region_t);
95     if (region->address == address) {
96       ignore_found = 1;
97       break;
98     } else if (region->address < address) {
99       start = cursor + 1;
100     } else {
101       if ((char *) region->address <= ((char *) address + size)) {
102         ignore_found = 1;
103         break;
104       } else {
105         end = cursor - 1;
106       }
107     }
108   }
109
110   if (ignore_found == 1) {
111     xbt_dynar_remove_at(mc_heap_comparison_ignore, cursor, NULL);
112     MC_remove_ignore_heap(address, size);
113   }
114 }
115
116 // ***** Ignore local variables
117
118 static void mc_ignore_local_variable_in_scope(const char *var_name,
119                                               const char *subprogram_name,
120                                               simgrid::mc::Frame* subprogram,
121                                               simgrid::mc::Frame* scope);
122 static void MC_ignore_local_variable_in_object(const char *var_name,
123                                                const char *subprogram_name,
124                                                simgrid::mc::ObjectInformation* info);
125
126 void MC_ignore_local_variable(const char *var_name, const char *frame_name)
127 {
128   simgrid::mc::Process* process = &mc_model_checker->process();
129   if (strcmp(frame_name, "*") == 0)
130     frame_name = NULL;
131
132   for (std::shared_ptr<simgrid::mc::ObjectInformation> const& info : process->object_infos)
133     MC_ignore_local_variable_in_object(var_name, frame_name, info.get());
134 }
135
136 static void MC_ignore_local_variable_in_object(const char *var_name,
137                                                const char *subprogram_name,
138                                                simgrid::mc::ObjectInformation* info)
139 {
140   for (auto& entry : info->subprograms)
141     mc_ignore_local_variable_in_scope(
142       var_name, subprogram_name, &entry.second, &entry.second);
143 }
144
145 /** \brief Ignore a local variable in a scope
146  *
147  *  Ignore all instances of variables with a given name in
148  *  any (possibly inlined) subprogram with a given namespaced
149  *  name.
150  *
151  *  \param var_name        Name of the local variable (or parameter to ignore)
152  *  \param subprogram_name Name of the subprogram fo ignore (NULL for any)
153  *  \param subprogram      (possibly inlined) Subprogram of the scope
154  *  \param scope           Current scope
155  */
156 static void mc_ignore_local_variable_in_scope(const char *var_name,
157                                               const char *subprogram_name,
158                                               simgrid::mc::Frame* subprogram,
159                                               simgrid::mc::Frame* scope)
160 {
161   // Processing of direct variables:
162
163   // If the current subprogram matches the given name:
164   if (subprogram_name == nullptr ||
165       (!subprogram->name.empty()
166         && subprogram->name == subprogram_name)) {
167
168     // Try to find the variable and remove it:
169     int start = 0;
170     int end = scope->variables.size() - 1;
171
172     // Dichotomic search:
173     while (start <= end) {
174       int cursor = (start + end) / 2;
175       simgrid::mc::Variable* current_var = &scope->variables[cursor];
176
177       int compare = current_var->name.compare(var_name);
178       if (compare == 0) {
179         // Variable found, remove it:
180         scope->variables.erase(scope->variables.begin() + cursor);
181
182         // and start again:
183         start = 0;
184         end = scope->variables.size() - 1;
185       } else if (compare < 0) {
186         start = cursor + 1;
187       } else {
188         end = cursor - 1;
189       }
190     }
191
192   }
193   // And recursive processing in nested scopes:
194   for (simgrid::mc::Frame& nested_scope : scope->scopes) {
195     // The new scope may be an inlined subroutine, in this case we want to use its
196     // namespaced name in recursive calls:
197     simgrid::mc::Frame* nested_subprogram =
198         nested_scope.tag ==
199         DW_TAG_inlined_subroutine ? &nested_scope : subprogram;
200
201     mc_ignore_local_variable_in_scope(var_name, subprogram_name,
202                                       nested_subprogram, &nested_scope);
203   }
204 }
205
206 extern XBT_PRIVATE xbt_dynar_t stacks_areas;
207
208 XBT_PRIVATE void MC_stack_area_add(stack_region_t stack_area)
209 {
210   if (stacks_areas == NULL)
211     stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
212   xbt_dynar_push(stacks_areas, &stack_area);
213 }
214
215 }