Home | History | Annotate | Download | only in analyzer
      1 ============
      2 Debug Checks
      3 ============
      4 
      5 .. contents::
      6    :local:
      7 
      8 The analyzer contains a number of checkers which can aid in debugging. Enable
      9 them by using the "-analyzer-checker=" flag, followed by the name of the
     10 checker.
     11 
     12 
     13 General Analysis Dumpers
     14 ========================
     15 
     16 These checkers are used to dump the results of various infrastructural analyses
     17 to stderr. Some checkers also have "view" variants, which will display a graph
     18 using 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 
     38 Path Tracking
     39 =============
     40 
     41 These 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 
     53 State Checking
     54 ==============
     55 
     56 These checkers will print out information about the analyzer state in the form
     57 of analysis warnings. They are intended for use with the -verify functionality
     58 in 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
     71 inspects expressions.)
     72 
     73 
     74 ExprInspection 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 
    200 Statistics
    201 ==========
    202 
    203 The debug.Stats checker collects various information about the analysis of each
    204 function, such as how many blocks were reached and if the analyzer timed out.
    205 
    206 There is also an additional -analyzer-stats flag, which enables various
    207 statistics within the analyzer engine. Note the Stats checker (which produces at
    208 least one bug report per function) may actually change the values reported by
    209 -analyzer-stats.
    210