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