brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.4 KiB · b3b9089 Raw
368 lines · plain
1============2Debug Checks3============4 5.. contents::6   :local:7 8The analyzer contains a number of checkers which can aid in debugging. Enable9them by using the "-analyzer-checker=" flag, followed by the name of the10checker.11 12These checkers are especially useful when analyzing a specific function, using13the `-analyze-function` flag. The flag accepts the function name for C code,14like `-analyze-function=myfunction`.15For C++ code, due to overloading, the function name must include the16parameter list, like `-analyze-function="myfunction(int, _Bool)"`.17 18Note that `bool` must be spelled as `_Bool` in the parameter list.19Refer to the output of `-analyzer-display-progress` to find the fully qualified20function name.21 22There are cases when this name can still collide. For example with template23function instances with non-deducible (aka. explicit) template parameters.24In such cases, prefer passing a USR instead of a function name can resolve this25ambiguity, like this: `-analyze-function="c:@S@Window@F@overloaded#I#"`.26 27Use the `clang-extdef-mapping` tool to find the USR for different functions.28 29General Analysis Dumpers30========================31 32These checkers are used to dump the results of various infrastructural analyses33to stderr. Some checkers also have "view" variants, which will display a graph34using a 'dot' format viewer (such as Graphviz on macOS) instead.35 36- debug.DumpCallGraph, debug.ViewCallGraph: Show the call graph generated for37  the current translation unit. This is used to determine the order in which to38  analyze functions when inlining is enabled.39 40- debug.DumpCFG, debug.ViewCFG: Show the CFG generated for each top-level41  function being analyzed.42 43- debug.DumpDominators: Shows the dominance tree for the CFG of each top-level44  function.45 46- debug.DumpLiveVars: Show the results of live variable analysis for each47  top-level function being analyzed.48 49- debug.DumpLiveExprs: Show the results of live expression analysis for each50  top-level function being analyzed.51 52- debug.ViewExplodedGraph: Show the Exploded Graphs generated for the53  analysis of different functions in the input translation unit. When there54  are several functions analyzed, display one graph per function. Beware55  that these graphs may grow very large, even for small functions.56 57Path Tracking58=============59 60These checkers print information about the path taken by the analyzer engine.61 62- debug.DumpCalls: Prints out every function or method call encountered during a63  path traversal. This is indented to show the call stack, but does NOT do any64  special handling of branches, meaning different paths could end up65  interleaved.66 67- debug.DumpTraversal: Prints the name of each branch statement encountered68  during a path traversal ("IfStmt", "WhileStmt", etc). Currently used to check69  whether the analysis engine is doing BFS or DFS.70 71 72State Checking73==============74 75These checkers will print out information about the analyzer state in the form76of analysis warnings. They are intended for use with the -verify functionality77in regression tests.78 79- debug.TaintTest: Prints out the word "tainted" for every expression that80  carries taint. At the time of this writing, taint was only introduced by the81  checks under experimental.security.taint.TaintPropagation; this checker may82  eventually move to the security.taint package.83 84- debug.ExprInspection: Responds to certain function calls, which are modeled85  after builtins. These function calls should affect the program state other86  than the evaluation of their arguments; to use them, you will need to declare87  them within your test file. The available functions are described below.88 89(FIXME: debug.ExprInspection should probably be renamed, since it no longer only90inspects expressions.)91 92 93ExprInspection checks94---------------------95 96- ``void clang_analyzer_eval(bool);``97 98  Prints TRUE if the argument is known to have a non-zero value, FALSE if the99  argument is known to have a zero or null value, and UNKNOWN if the argument100  isn't sufficiently constrained on this path.  You can use this to test other101  values by using expressions like "x == 5".  Note that this functionality is102  currently DISABLED in inlined functions, since different calls to the same103  inlined function could provide different information, making it difficult to104  write proper -verify directives.105 106  In C, the argument can be typed as 'int' or as '_Bool'.107 108  Example usage::109 110    clang_analyzer_eval(x); // expected-warning{{UNKNOWN}}111    if (!x) return;112    clang_analyzer_eval(x); // expected-warning{{TRUE}}113 114 115- ``void clang_analyzer_checkInlined(bool);``116 117  If a call occurs within an inlined function, prints TRUE or FALSE according to118  the value of its argument. If a call occurs outside an inlined function,119  nothing is printed.120 121  The intended use of this checker is to assert that a function is inlined at122  least once (by passing 'true' and expecting a warning), or to assert that a123  function is never inlined (by passing 'false' and expecting no warning). The124  argument is technically unnecessary but is intended to clarify intent.125 126  You might wonder why we can't print TRUE if a function is ever inlined and127  FALSE if it is not. The problem is that any inlined function could conceivably128  also be analyzed as a top-level function (in which case both TRUE and FALSE129  would be printed), depending on the value of the -analyzer-inlining option.130 131  In C, the argument can be typed as 'int' or as '_Bool'.132 133  Example usage::134 135    int inlined() {136      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}137      return 42;138    }139 140    void topLevel() {141      clang_analyzer_checkInlined(false); // no-warning (not inlined)142      int value = inlined();143      // This assertion will not be valid if the previous call was not inlined.144      clang_analyzer_eval(value == 42); // expected-warning{{TRUE}}145    }146 147- ``void clang_analyzer_warnIfReached();``148 149  Generate a warning if this line of code gets reached by the analyzer.150 151  Example usage::152 153    if (true) {154      clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}155    }156    else {157      clang_analyzer_warnIfReached();  // no-warning158    }159 160- ``void clang_analyzer_numTimesReached();``161 162  Same as above, but include the number of times this call expression163  gets reached by the analyzer during the current analysis.164 165  Example usage::166 167    for (int x = 0; x < 3; ++x) {168      clang_analyzer_numTimesReached(); // expected-warning{{3}}169    }170 171- ``void clang_analyzer_warnOnDeadSymbol(int);``172 173  Subscribe for a delayed warning when the symbol that represents the value of174  the argument is garbage-collected by the analyzer.175 176  When calling 'clang_analyzer_warnOnDeadSymbol(x)', if value of 'x' is a177  symbol, then this symbol is marked by the ExprInspection checker. Then,178  during each garbage collection run, the checker sees if the marked symbol is179  being collected and issues the 'SYMBOL DEAD' warning if it does.180  This way you know where exactly, up to the line of code, the symbol dies.181 182  It is unlikely that you call this function after the symbol is already dead,183  because the very reference to it as the function argument prevents it from184  dying. However, if the argument is not a symbol but a concrete value,185  no warning would be issued.186 187  Example usage::188 189    do {190      int x = generate_some_integer();191      clang_analyzer_warnOnDeadSymbol(x);192    } while(0);  // expected-warning{{SYMBOL DEAD}}193 194 195- ``void clang_analyzer_explain(a single argument of any type);``196 197  This function explains the value of its argument in a human-readable manner198  in the warning message. You can make as many overrides of its prototype199  in the test code as necessary to explain various integral, pointer,200  or even record-type values. To simplify usage in C code (where overloading201  the function declaration is not allowed), you may append an arbitrary suffix202  to the function name, without affecting functionality.203 204  Example usage::205 206    void clang_analyzer_explain(int);207    void clang_analyzer_explain(void *);208 209    // Useful in C code210    void clang_analyzer_explain_int(int);211 212    void foo(int param, void *ptr) {213      clang_analyzer_explain(param); // expected-warning{{argument 'param'}}214      clang_analyzer_explain_int(param); // expected-warning{{argument 'param'}}215      if (!ptr)216        clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}217    }218 219- ``void clang_analyzer_dump( /* a single argument of any type */);``220 221  Similar to clang_analyzer_explain, but produces a raw dump of the value,222  same as SVal::dump().223 224  Example usage::225 226    void clang_analyzer_dump(int);227    void foo(int x) {228      clang_analyzer_dump(x); // expected-warning{{reg_$0<x>}}229    }230 231- ``size_t clang_analyzer_getExtent(void *);``232 233  This function returns the value that represents the extent of a memory region234  pointed to by the argument. This value is often difficult to obtain otherwise,235  because no valid code that produces this value. However, it may be useful236  for testing purposes, to see how well does the analyzer model region extents.237 238  Example usage::239 240    void foo() {241      int x, *y;242      size_t xs = clang_analyzer_getExtent(&x);243      clang_analyzer_explain(xs); // expected-warning{{'4'}}244      size_t ys = clang_analyzer_getExtent(&y);245      clang_analyzer_explain(ys); // expected-warning{{'8'}}246    }247 248- ``void clang_analyzer_printState();``249 250  Dumps the current ProgramState to the stderr. Quickly lookup the program state251  at any execution point without ViewExplodedGraph or re-compiling the program.252  This is not very useful for writing tests (apart from testing how ProgramState253  gets printed), but useful for debugging tests. Also, this method doesn't254  produce a warning, so it gets printed on the console before all other255  ExprInspection warnings.256 257  Example usage::258 259    void foo() {260      int x = 1;261      clang_analyzer_printState(); // Read the stderr!262    }263 264- ``void clang_analyzer_hashDump(int);``265 266  The analyzer can generate a hash to identify reports. To debug what information267  is used to calculate this hash it is possible to dump the hashed string as a268  warning of an arbitrary expression using the function above.269 270  Example usage::271 272    void foo() {273      int x = 1;274      clang_analyzer_hashDump(x); // expected-warning{{hashed string for x}}275    }276 277- ``void clang_analyzer_denote(int, const char *);``278 279  Denotes symbols with strings. A subsequent call to clang_analyzer_express()280  will expresses another symbol in terms of these string. Useful for testing281  relationships between different symbols.282 283  Example usage::284 285    void foo(int x) {286      clang_analyzer_denote(x, "$x");287      clang_analyzer_express(x + 1); // expected-warning{{$x + 1}}288    }289 290- ``void clang_analyzer_express(int);``291 292  See clang_analyzer_denote().293 294- ``void clang_analyzer_isTainted(a single argument of any type);``295 296  Queries the analyzer whether the expression used as argument is tainted or not.297  This is useful in tests, where we don't want to issue warning for all tainted298  expressions but only check for certain expressions.299  This would help to reduce the *noise* that the `TaintTest` debug checker would300  introduce and let you focus on the `expected-warning`'s that you really care301  about.302 303  Example usage::304 305    int read_integer() {306      int n;307      clang_analyzer_isTainted(n);     // expected-warning{{NO}}308      scanf("%d", &n);309      clang_analyzer_isTainted(n);     // expected-warning{{YES}}310      clang_analyzer_isTainted(n + 2); // expected-warning{{YES}}311      clang_analyzer_isTainted(n > 0); // expected-warning{{YES}}312      int next_tainted_value = n; // no-warning313      return n;314    }315 316- ``clang_analyzer_dumpExtent(a single argument of any type)``317- ``clang_analyzer_dumpElementCount(a single argument of any type)``318 319  Dumps out the extent and the element count of the argument.320 321  Example usage::322 323    void array() {324      int a[] = {1, 3};325      clang_analyzer_dumpExtent(a);       // expected-warning {{8 S64b}}326      clang_analyzer_dumpElementCount(a); // expected-warning {{2 S64b}}327    }328 329- ``clang_analyzer_value(a single argument of integer or pointer type)``330 331  Prints an associated value for the given argument.332  Supported argument types are integers, enums and pointers.333  The value can be represented either as a range set or as a concrete integer.334  For the rest of the types function prints ``n/a`` (aka not available).335 336  **Note:** This function will print nothing when clang uses Z3 as the337  constraint manager (which is an unsupported and badly broken analysis mode338  that's distinct from the supported and stable "Z3 refutation" aka "Z3339  crosscheck" mode).340 341  Example usage::342 343    void print(char c, unsigned u) {344      clang_analyzer_value(c); // expected-warning {{8s:{ [-128, 127] }}}345      if(u != 42)346         clang_analyzer_value(u); // expected-warning {{32u:{ [0, 41], [43, 4294967295] }}}347      else348         clang_analyzer_value(u); // expected-warning {{32u:42}}349    }350 351Statistics352==========353 354The debug.Stats checker collects various information about the analysis of each355function, such as how many blocks were reached and if the analyzer timed out.356 357There is also an additional -analyzer-stats flag, which enables various358statistics within the analyzer engine. Note the Stats checker (which produces at359least one bug report per function) may actually change the values reported by360-analyzer-stats.361 362Output testing checkers363=======================364 365- debug.ReportStmts reports a warning at **every** statement, making it a very366  useful tool for testing thoroughly bug report construction and output367  emission.368