• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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
38Path Tracking
39=============
40
41These 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
53State Checking
54==============
55
56These checkers will print out information about the analyzer state in the form
57of analysis warnings. They are intended for use with the -verify functionality
58in 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
71inspects expressions.)
72
73
74ExprInspection 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_warnOnDeadSymbol(int);
142
143  Subscribe for a delayed warning when the symbol that represents the value of
144  the argument is garbage-collected by the analyzer.
145
146  When calling 'clang_analyzer_warnOnDeadSymbol(x)', if value of 'x' is a
147  symbol, then this symbol is marked by the ExprInspection checker. Then,
148  during each garbage collection run, the checker sees if the marked symbol is
149  being collected and issues the 'SYMBOL DEAD' warning if it does.
150  This way you know where exactly, up to the line of code, the symbol dies.
151
152  It is unlikely that you call this function after the symbol is already dead,
153  because the very reference to it as the function argument prevents it from
154  dying. However, if the argument is not a symbol but a concrete value,
155  no warning would be issued.
156
157  Example usage::
158
159    do {
160      int x = generate_some_integer();
161      clang_analyzer_warnOnDeadSymbol(x);
162    } while(0);  // expected-warning{{SYMBOL DEAD}}
163
164
165- void clang_analyzer_explain(a single argument of any type);
166
167  This function explains the value of its argument in a human-readable manner
168  in the warning message. You can make as many overrides of its prototype
169  in the test code as necessary to explain various integral, pointer,
170  or even record-type values.
171
172  Example usage::
173
174    void clang_analyzer_explain(int);
175    void clang_analyzer_explain(void *);
176
177    void foo(int param, void *ptr) {
178      clang_analyzer_explain(param); // expected-warning{{argument 'param'}}
179      if (!ptr)
180        clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}
181    }
182
183- size_t clang_analyzer_getExtent(void *);
184
185  This function returns the value that represents the extent of a memory region
186  pointed to by the argument. This value is often difficult to obtain otherwise,
187  because no valid code that produces this value. However, it may be useful
188  for testing purposes, to see how well does the analyzer model region extents.
189
190  Example usage::
191
192    void foo() {
193      int x, *y;
194      size_t xs = clang_analyzer_getExtent(&x);
195      clang_analyzer_explain(xs); // expected-warning{{'4'}}
196      size_t ys = clang_analyzer_getExtent(&y);
197      clang_analyzer_explain(ys); // expected-warning{{'8'}}
198    }
199
200Statistics
201==========
202
203The debug.Stats checker collects various information about the analysis of each
204function, such as how many blocks were reached and if the analyzer timed out.
205
206There is also an additional -analyzer-stats flag, which enables various
207statistics within the analyzer engine. Note the Stats checker (which produces at
208least one bug report per function) may actually change the values reported by
209-analyzer-stats.
210