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