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