1============
2Debug Checks
3============
4
5.. contents::
6   :local:
7
8The analyzer contains a number of checkers which can aid in debugging. Enable
9them by using the "-analyzer-checker=" flag, followed by the name of the
10checker.
11
12
13General Analysis Dumpers
14========================
15
16These checkers are used to dump the results of various infrastructural analyses
17to stderr. Some checkers also have "view" variants, which will display a graph
18using a 'dot' format viewer (such as Graphviz on macOS) 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
41Path Tracking
42=============
43
44These 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
56State Checking
57==============
58
59These checkers will print out information about the analyzer state in the form
60of analysis warnings. They are intended for use with the -verify functionality
61in 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
74inspects expressions.)
75
76
77ExprInspection 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
278Statistics
279==========
280
281The debug.Stats checker collects various information about the analysis of each
282function, such as how many blocks were reached and if the analyzer timed out.
283
284There is also an additional -analyzer-stats flag, which enables various
285statistics within the analyzer engine. Note the Stats checker (which produces at
286least one bug report per function) may actually change the values reported by
287-analyzer-stats.
288
289Output 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