1 | ============ |
2 | Debug Checks |
3 | ============ |
4 | |
5 | .. contents:: |
6 | :local: |
7 | |
8 | The analyzer contains a number of checkers which can aid in debugging. Enable |
9 | them by using the "-analyzer-checker=" flag, followed by the name of the |
10 | checker. |
11 | |
12 | |
13 | General Analysis Dumpers |
14 | ======================== |
15 | |
16 | These checkers are used to dump the results of various infrastructural analyses |
17 | to stderr. Some checkers also have "view" variants, which will display a graph |
18 | using a 'dot' format viewer (such as Graphviz on OS X) instead. |
19 | |
20 | - debug.DumpCallGraph, debug.ViewCallGraph: Show the call graph generated for |
21 | the current translation unit. This is used to determine the order in which to |
22 | analyze functions when inlining is enabled. |
23 | |
24 | - debug.DumpCFG, debug.ViewCFG: Show the CFG generated for each top-level |
25 | function being analyzed. |
26 | |
27 | - debug.DumpDominators: Shows the dominance tree for the CFG of each top-level |
28 | function. |
29 | |
30 | - debug.DumpLiveVars: Show the results of live variable analysis for each |
31 | top-level function being analyzed. |
32 | |
33 | - debug.DumpLiveStmts: Show the results of live statement analysis for each |
34 | top-level function being analyzed. |
35 | |
36 | - debug.ViewExplodedGraph: Show the Exploded Graphs generated for the |
37 | analysis of different functions in the input translation unit. When there |
38 | are several functions analyzed, display one graph per function. Beware |
39 | that these graphs may grow very large, even for small functions. |
40 | |
41 | Path Tracking |
42 | ============= |
43 | |
44 | These checkers print information about the path taken by the analyzer engine. |
45 | |
46 | - debug.DumpCalls: Prints out every function or method call encountered during a |
47 | path traversal. This is indented to show the call stack, but does NOT do any |
48 | special handling of branches, meaning different paths could end up |
49 | interleaved. |
50 | |
51 | - debug.DumpTraversal: Prints the name of each branch statement encountered |
52 | during a path traversal ("IfStmt", "WhileStmt", etc). Currently used to check |
53 | whether the analysis engine is doing BFS or DFS. |
54 | |
55 | |
56 | State Checking |
57 | ============== |
58 | |
59 | These checkers will print out information about the analyzer state in the form |
60 | of analysis warnings. They are intended for use with the -verify functionality |
61 | in regression tests. |
62 | |
63 | - debug.TaintTest: Prints out the word "tainted" for every expression that |
64 | carries taint. At the time of this writing, taint was only introduced by the |
65 | checks under experimental.security.taint.TaintPropagation; this checker may |
66 | eventually move to the security.taint package. |
67 | |
68 | - debug.ExprInspection: Responds to certain function calls, which are modeled |
69 | after builtins. These function calls should affect the program state other |
70 | than the evaluation of their arguments; to use them, you will need to declare |
71 | them within your test file. The available functions are described below. |
72 | |
73 | (FIXME: debug.ExprInspection should probably be renamed, since it no longer only |
74 | inspects expressions.) |
75 | |
76 | |
77 | ExprInspection checks |
78 | --------------------- |
79 | |
80 | - ``void clang_analyzer_eval(bool);`` |
81 | |
82 | Prints TRUE if the argument is known to have a non-zero value, FALSE if the |
83 | argument is known to have a zero or null value, and UNKNOWN if the argument |
84 | isn't sufficiently constrained on this path. You can use this to test other |
85 | values by using expressions like "x == 5". Note that this functionality is |
86 | currently DISABLED in inlined functions, since different calls to the same |
87 | inlined function could provide different information, making it difficult to |
88 | write proper -verify directives. |
89 | |
90 | In C, the argument can be typed as 'int' or as '_Bool'. |
91 | |
92 | Example usage:: |
93 | |
94 | clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} |
95 | if (!x) return; |
96 | clang_analyzer_eval(x); // expected-warning{{TRUE}} |
97 | |
98 | |
99 | - ``void clang_analyzer_checkInlined(bool);`` |
100 | |
101 | If a call occurs within an inlined function, prints TRUE or FALSE according to |
102 | the value of its argument. If a call occurs outside an inlined function, |
103 | nothing is printed. |
104 | |
105 | The intended use of this checker is to assert that a function is inlined at |
106 | least once (by passing 'true' and expecting a warning), or to assert that a |
107 | function is never inlined (by passing 'false' and expecting no warning). The |
108 | argument is technically unnecessary but is intended to clarify intent. |
109 | |
110 | You might wonder why we can't print TRUE if a function is ever inlined and |
111 | FALSE if it is not. The problem is that any inlined function could conceivably |
112 | also be analyzed as a top-level function (in which case both TRUE and FALSE |
113 | would be printed), depending on the value of the -analyzer-inlining option. |
114 | |
115 | In C, the argument can be typed as 'int' or as '_Bool'. |
116 | |
117 | Example usage:: |
118 | |
119 | int inlined() { |
120 | clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} |
121 | return 42; |
122 | } |
123 | |
124 | void topLevel() { |
125 | clang_analyzer_checkInlined(false); // no-warning (not inlined) |
126 | int value = inlined(); |
127 | // This assertion will not be valid if the previous call was not inlined. |
128 | clang_analyzer_eval(value == 42); // expected-warning{{TRUE}} |
129 | } |
130 | |
131 | - ``void clang_analyzer_warnIfReached();`` |
132 | |
133 | Generate a warning if this line of code gets reached by the analyzer. |
134 | |
135 | Example usage:: |
136 | |
137 | if (true) { |
138 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
139 | } |
140 | else { |
141 | clang_analyzer_warnIfReached(); // no-warning |
142 | } |
143 | |
144 | - ``void clang_analyzer_numTimesReached();`` |
145 | |
146 | Same as above, but include the number of times this call expression |
147 | gets reached by the analyzer during the current analysis. |
148 | |
149 | Example usage:: |
150 | |
151 | for (int x = 0; x < 3; ++x) { |
152 | clang_analyzer_numTimesReached(); // expected-warning{{3}} |
153 | } |
154 | |
155 | - ``void clang_analyzer_warnOnDeadSymbol(int);`` |
156 | |
157 | Subscribe for a delayed warning when the symbol that represents the value of |
158 | the argument is garbage-collected by the analyzer. |
159 | |
160 | When calling 'clang_analyzer_warnOnDeadSymbol(x)', if value of 'x' is a |
161 | symbol, then this symbol is marked by the ExprInspection checker. Then, |
162 | during each garbage collection run, the checker sees if the marked symbol is |
163 | being collected and issues the 'SYMBOL DEAD' warning if it does. |
164 | This way you know where exactly, up to the line of code, the symbol dies. |
165 | |
166 | It is unlikely that you call this function after the symbol is already dead, |
167 | because the very reference to it as the function argument prevents it from |
168 | dying. However, if the argument is not a symbol but a concrete value, |
169 | no warning would be issued. |
170 | |
171 | Example usage:: |
172 | |
173 | do { |
174 | int x = generate_some_integer(); |
175 | clang_analyzer_warnOnDeadSymbol(x); |
176 | } while(0); // expected-warning{{SYMBOL DEAD}} |
177 | |
178 | |
179 | - ``void clang_analyzer_explain(a single argument of any type);`` |
180 | |
181 | This function explains the value of its argument in a human-readable manner |
182 | in the warning message. You can make as many overrides of its prototype |
183 | in the test code as necessary to explain various integral, pointer, |
184 | or even record-type values. To simplify usage in C code (where overloading |
185 | the function declaration is not allowed), you may append an arbitrary suffix |
186 | to the function name, without affecting functionality. |
187 | |
188 | Example usage:: |
189 | |
190 | void clang_analyzer_explain(int); |
191 | void clang_analyzer_explain(void *); |
192 | |
193 | // Useful in C code |
194 | void clang_analyzer_explain_int(int); |
195 | |
196 | void foo(int param, void *ptr) { |
197 | clang_analyzer_explain(param); // expected-warning{{argument 'param'}} |
198 | clang_analyzer_explain_int(param); // expected-warning{{argument 'param'}} |
199 | if (!ptr) |
200 | clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}} |
201 | } |
202 | |
203 | - ``void clang_analyzer_dump( /* a single argument of any type */);`` |
204 | |
205 | Similar to clang_analyzer_explain, but produces a raw dump of the value, |
206 | same as SVal::dump(). |
207 | |
208 | Example usage:: |
209 | |
210 | void clang_analyzer_dump(int); |
211 | void foo(int x) { |
212 | clang_analyzer_dump(x); // expected-warning{{reg_$0<x>}} |
213 | } |
214 | |
215 | - ``size_t clang_analyzer_getExtent(void *);`` |
216 | |
217 | This function returns the value that represents the extent of a memory region |
218 | pointed to by the argument. This value is often difficult to obtain otherwise, |
219 | because no valid code that produces this value. However, it may be useful |
220 | for testing purposes, to see how well does the analyzer model region extents. |
221 | |
222 | Example usage:: |
223 | |
224 | void foo() { |
225 | int x, *y; |
226 | size_t xs = clang_analyzer_getExtent(&x); |
227 | clang_analyzer_explain(xs); // expected-warning{{'4'}} |
228 | size_t ys = clang_analyzer_getExtent(&y); |
229 | clang_analyzer_explain(ys); // expected-warning{{'8'}} |
230 | } |
231 | |
232 | - ``void clang_analyzer_printState();`` |
233 | |
234 | Dumps the current ProgramState to the stderr. Quickly lookup the program state |
235 | at any execution point without ViewExplodedGraph or re-compiling the program. |
236 | This is not very useful for writing tests (apart from testing how ProgramState |
237 | gets printed), but useful for debugging tests. Also, this method doesn't |
238 | produce a warning, so it gets printed on the console before all other |
239 | ExprInspection warnings. |
240 | |
241 | Example usage:: |
242 | |
243 | void foo() { |
244 | int x = 1; |
245 | clang_analyzer_printState(); // Read the stderr! |
246 | } |
247 | |
248 | - ``void clang_analyzer_hashDump(int);`` |
249 | |
250 | The analyzer can generate a hash to identify reports. To debug what information |
251 | is used to calculate this hash it is possible to dump the hashed string as a |
252 | warning of an arbitrary expression using the function above. |
253 | |
254 | Example usage:: |
255 | |
256 | void foo() { |
257 | int x = 1; |
258 | clang_analyzer_hashDump(x); // expected-warning{{hashed string for x}} |
259 | } |
260 | |
261 | - ``void clang_analyzer_denote(int, const char *);`` |
262 | |
263 | Denotes symbols with strings. A subsequent call to clang_analyzer_express() |
264 | will expresses another symbol in terms of these string. Useful for testing |
265 | relationships between different symbols. |
266 | |
267 | Example usage:: |
268 | |
269 | void foo(int x) { |
270 | clang_analyzer_denote(x, "$x"); |
271 | clang_analyzer_express(x + 1); // expected-warning{{$x + 1}} |
272 | } |
273 | |
274 | - ``void clang_analyzer_express(int);`` |
275 | |
276 | See clang_analyzer_denote(). |
277 | |
278 | Statistics |
279 | ========== |
280 | |
281 | The debug.Stats checker collects various information about the analysis of each |
282 | function, such as how many blocks were reached and if the analyzer timed out. |
283 | |
284 | There is also an additional -analyzer-stats flag, which enables various |
285 | statistics within the analyzer engine. Note the Stats checker (which produces at |
286 | least one bug report per function) may actually change the values reported by |
287 | -analyzer-stats. |
288 | |
289 | Output testing checkers |
290 | ======================= |
291 | |
292 | - debug.ReportStmts reports a warning at **every** statement, making it a very |
293 | useful tool for testing thoroughly bug report construction and output |
294 | emission. |
295 | |