17330f729Sjoerg============ 27330f729SjoergDebug Checks 37330f729Sjoerg============ 47330f729Sjoerg 57330f729Sjoerg.. contents:: 67330f729Sjoerg :local: 77330f729Sjoerg 87330f729SjoergThe analyzer contains a number of checkers which can aid in debugging. Enable 97330f729Sjoergthem by using the "-analyzer-checker=" flag, followed by the name of the 107330f729Sjoergchecker. 117330f729Sjoerg 127330f729Sjoerg 137330f729SjoergGeneral Analysis Dumpers 147330f729Sjoerg======================== 157330f729Sjoerg 167330f729SjoergThese checkers are used to dump the results of various infrastructural analyses 177330f729Sjoergto stderr. Some checkers also have "view" variants, which will display a graph 187330f729Sjoergusing a 'dot' format viewer (such as Graphviz on macOS) instead. 197330f729Sjoerg 207330f729Sjoerg- debug.DumpCallGraph, debug.ViewCallGraph: Show the call graph generated for 217330f729Sjoerg the current translation unit. This is used to determine the order in which to 227330f729Sjoerg analyze functions when inlining is enabled. 237330f729Sjoerg 247330f729Sjoerg- debug.DumpCFG, debug.ViewCFG: Show the CFG generated for each top-level 257330f729Sjoerg function being analyzed. 267330f729Sjoerg 277330f729Sjoerg- debug.DumpDominators: Shows the dominance tree for the CFG of each top-level 287330f729Sjoerg function. 297330f729Sjoerg 307330f729Sjoerg- debug.DumpLiveVars: Show the results of live variable analysis for each 317330f729Sjoerg top-level function being analyzed. 327330f729Sjoerg 33*e038c9c4Sjoerg- debug.DumpLiveExprs: Show the results of live expression analysis for each 347330f729Sjoerg top-level function being analyzed. 357330f729Sjoerg 367330f729Sjoerg- debug.ViewExplodedGraph: Show the Exploded Graphs generated for the 377330f729Sjoerg analysis of different functions in the input translation unit. When there 387330f729Sjoerg are several functions analyzed, display one graph per function. Beware 397330f729Sjoerg that these graphs may grow very large, even for small functions. 407330f729Sjoerg 417330f729SjoergPath Tracking 427330f729Sjoerg============= 437330f729Sjoerg 447330f729SjoergThese checkers print information about the path taken by the analyzer engine. 457330f729Sjoerg 467330f729Sjoerg- debug.DumpCalls: Prints out every function or method call encountered during a 477330f729Sjoerg path traversal. This is indented to show the call stack, but does NOT do any 487330f729Sjoerg special handling of branches, meaning different paths could end up 497330f729Sjoerg interleaved. 507330f729Sjoerg 517330f729Sjoerg- debug.DumpTraversal: Prints the name of each branch statement encountered 527330f729Sjoerg during a path traversal ("IfStmt", "WhileStmt", etc). Currently used to check 537330f729Sjoerg whether the analysis engine is doing BFS or DFS. 547330f729Sjoerg 557330f729Sjoerg 567330f729SjoergState Checking 577330f729Sjoerg============== 587330f729Sjoerg 597330f729SjoergThese checkers will print out information about the analyzer state in the form 607330f729Sjoergof analysis warnings. They are intended for use with the -verify functionality 617330f729Sjoergin regression tests. 627330f729Sjoerg 637330f729Sjoerg- debug.TaintTest: Prints out the word "tainted" for every expression that 647330f729Sjoerg carries taint. At the time of this writing, taint was only introduced by the 657330f729Sjoerg checks under experimental.security.taint.TaintPropagation; this checker may 667330f729Sjoerg eventually move to the security.taint package. 677330f729Sjoerg 687330f729Sjoerg- debug.ExprInspection: Responds to certain function calls, which are modeled 697330f729Sjoerg after builtins. These function calls should affect the program state other 707330f729Sjoerg than the evaluation of their arguments; to use them, you will need to declare 717330f729Sjoerg them within your test file. The available functions are described below. 727330f729Sjoerg 737330f729Sjoerg(FIXME: debug.ExprInspection should probably be renamed, since it no longer only 747330f729Sjoerginspects expressions.) 757330f729Sjoerg 767330f729Sjoerg 777330f729SjoergExprInspection checks 787330f729Sjoerg--------------------- 797330f729Sjoerg 807330f729Sjoerg- ``void clang_analyzer_eval(bool);`` 817330f729Sjoerg 827330f729Sjoerg Prints TRUE if the argument is known to have a non-zero value, FALSE if the 837330f729Sjoerg argument is known to have a zero or null value, and UNKNOWN if the argument 847330f729Sjoerg isn't sufficiently constrained on this path. You can use this to test other 857330f729Sjoerg values by using expressions like "x == 5". Note that this functionality is 867330f729Sjoerg currently DISABLED in inlined functions, since different calls to the same 877330f729Sjoerg inlined function could provide different information, making it difficult to 887330f729Sjoerg write proper -verify directives. 897330f729Sjoerg 907330f729Sjoerg In C, the argument can be typed as 'int' or as '_Bool'. 917330f729Sjoerg 927330f729Sjoerg Example usage:: 937330f729Sjoerg 947330f729Sjoerg clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 957330f729Sjoerg if (!x) return; 967330f729Sjoerg clang_analyzer_eval(x); // expected-warning{{TRUE}} 977330f729Sjoerg 987330f729Sjoerg 997330f729Sjoerg- ``void clang_analyzer_checkInlined(bool);`` 1007330f729Sjoerg 1017330f729Sjoerg If a call occurs within an inlined function, prints TRUE or FALSE according to 1027330f729Sjoerg the value of its argument. If a call occurs outside an inlined function, 1037330f729Sjoerg nothing is printed. 1047330f729Sjoerg 1057330f729Sjoerg The intended use of this checker is to assert that a function is inlined at 1067330f729Sjoerg least once (by passing 'true' and expecting a warning), or to assert that a 1077330f729Sjoerg function is never inlined (by passing 'false' and expecting no warning). The 1087330f729Sjoerg argument is technically unnecessary but is intended to clarify intent. 1097330f729Sjoerg 1107330f729Sjoerg You might wonder why we can't print TRUE if a function is ever inlined and 1117330f729Sjoerg FALSE if it is not. The problem is that any inlined function could conceivably 1127330f729Sjoerg also be analyzed as a top-level function (in which case both TRUE and FALSE 1137330f729Sjoerg would be printed), depending on the value of the -analyzer-inlining option. 1147330f729Sjoerg 1157330f729Sjoerg In C, the argument can be typed as 'int' or as '_Bool'. 1167330f729Sjoerg 1177330f729Sjoerg Example usage:: 1187330f729Sjoerg 1197330f729Sjoerg int inlined() { 1207330f729Sjoerg clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} 1217330f729Sjoerg return 42; 1227330f729Sjoerg } 1237330f729Sjoerg 1247330f729Sjoerg void topLevel() { 1257330f729Sjoerg clang_analyzer_checkInlined(false); // no-warning (not inlined) 1267330f729Sjoerg int value = inlined(); 1277330f729Sjoerg // This assertion will not be valid if the previous call was not inlined. 1287330f729Sjoerg clang_analyzer_eval(value == 42); // expected-warning{{TRUE}} 1297330f729Sjoerg } 1307330f729Sjoerg 1317330f729Sjoerg- ``void clang_analyzer_warnIfReached();`` 1327330f729Sjoerg 1337330f729Sjoerg Generate a warning if this line of code gets reached by the analyzer. 1347330f729Sjoerg 1357330f729Sjoerg Example usage:: 1367330f729Sjoerg 1377330f729Sjoerg if (true) { 1387330f729Sjoerg clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 1397330f729Sjoerg } 1407330f729Sjoerg else { 1417330f729Sjoerg clang_analyzer_warnIfReached(); // no-warning 1427330f729Sjoerg } 1437330f729Sjoerg 1447330f729Sjoerg- ``void clang_analyzer_numTimesReached();`` 1457330f729Sjoerg 1467330f729Sjoerg Same as above, but include the number of times this call expression 1477330f729Sjoerg gets reached by the analyzer during the current analysis. 1487330f729Sjoerg 1497330f729Sjoerg Example usage:: 1507330f729Sjoerg 1517330f729Sjoerg for (int x = 0; x < 3; ++x) { 1527330f729Sjoerg clang_analyzer_numTimesReached(); // expected-warning{{3}} 1537330f729Sjoerg } 1547330f729Sjoerg 1557330f729Sjoerg- ``void clang_analyzer_warnOnDeadSymbol(int);`` 1567330f729Sjoerg 1577330f729Sjoerg Subscribe for a delayed warning when the symbol that represents the value of 1587330f729Sjoerg the argument is garbage-collected by the analyzer. 1597330f729Sjoerg 1607330f729Sjoerg When calling 'clang_analyzer_warnOnDeadSymbol(x)', if value of 'x' is a 1617330f729Sjoerg symbol, then this symbol is marked by the ExprInspection checker. Then, 1627330f729Sjoerg during each garbage collection run, the checker sees if the marked symbol is 1637330f729Sjoerg being collected and issues the 'SYMBOL DEAD' warning if it does. 1647330f729Sjoerg This way you know where exactly, up to the line of code, the symbol dies. 1657330f729Sjoerg 1667330f729Sjoerg It is unlikely that you call this function after the symbol is already dead, 1677330f729Sjoerg because the very reference to it as the function argument prevents it from 1687330f729Sjoerg dying. However, if the argument is not a symbol but a concrete value, 1697330f729Sjoerg no warning would be issued. 1707330f729Sjoerg 1717330f729Sjoerg Example usage:: 1727330f729Sjoerg 1737330f729Sjoerg do { 1747330f729Sjoerg int x = generate_some_integer(); 1757330f729Sjoerg clang_analyzer_warnOnDeadSymbol(x); 1767330f729Sjoerg } while(0); // expected-warning{{SYMBOL DEAD}} 1777330f729Sjoerg 1787330f729Sjoerg 1797330f729Sjoerg- ``void clang_analyzer_explain(a single argument of any type);`` 1807330f729Sjoerg 1817330f729Sjoerg This function explains the value of its argument in a human-readable manner 1827330f729Sjoerg in the warning message. You can make as many overrides of its prototype 1837330f729Sjoerg in the test code as necessary to explain various integral, pointer, 1847330f729Sjoerg or even record-type values. To simplify usage in C code (where overloading 1857330f729Sjoerg the function declaration is not allowed), you may append an arbitrary suffix 1867330f729Sjoerg to the function name, without affecting functionality. 1877330f729Sjoerg 1887330f729Sjoerg Example usage:: 1897330f729Sjoerg 1907330f729Sjoerg void clang_analyzer_explain(int); 1917330f729Sjoerg void clang_analyzer_explain(void *); 1927330f729Sjoerg 1937330f729Sjoerg // Useful in C code 1947330f729Sjoerg void clang_analyzer_explain_int(int); 1957330f729Sjoerg 1967330f729Sjoerg void foo(int param, void *ptr) { 1977330f729Sjoerg clang_analyzer_explain(param); // expected-warning{{argument 'param'}} 1987330f729Sjoerg clang_analyzer_explain_int(param); // expected-warning{{argument 'param'}} 1997330f729Sjoerg if (!ptr) 2007330f729Sjoerg clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}} 2017330f729Sjoerg } 2027330f729Sjoerg 2037330f729Sjoerg- ``void clang_analyzer_dump( /* a single argument of any type */);`` 2047330f729Sjoerg 2057330f729Sjoerg Similar to clang_analyzer_explain, but produces a raw dump of the value, 2067330f729Sjoerg same as SVal::dump(). 2077330f729Sjoerg 2087330f729Sjoerg Example usage:: 2097330f729Sjoerg 2107330f729Sjoerg void clang_analyzer_dump(int); 2117330f729Sjoerg void foo(int x) { 2127330f729Sjoerg clang_analyzer_dump(x); // expected-warning{{reg_$0<x>}} 2137330f729Sjoerg } 2147330f729Sjoerg 2157330f729Sjoerg- ``size_t clang_analyzer_getExtent(void *);`` 2167330f729Sjoerg 2177330f729Sjoerg This function returns the value that represents the extent of a memory region 2187330f729Sjoerg pointed to by the argument. This value is often difficult to obtain otherwise, 2197330f729Sjoerg because no valid code that produces this value. However, it may be useful 2207330f729Sjoerg for testing purposes, to see how well does the analyzer model region extents. 2217330f729Sjoerg 2227330f729Sjoerg Example usage:: 2237330f729Sjoerg 2247330f729Sjoerg void foo() { 2257330f729Sjoerg int x, *y; 2267330f729Sjoerg size_t xs = clang_analyzer_getExtent(&x); 2277330f729Sjoerg clang_analyzer_explain(xs); // expected-warning{{'4'}} 2287330f729Sjoerg size_t ys = clang_analyzer_getExtent(&y); 2297330f729Sjoerg clang_analyzer_explain(ys); // expected-warning{{'8'}} 2307330f729Sjoerg } 2317330f729Sjoerg 2327330f729Sjoerg- ``void clang_analyzer_printState();`` 2337330f729Sjoerg 2347330f729Sjoerg Dumps the current ProgramState to the stderr. Quickly lookup the program state 2357330f729Sjoerg at any execution point without ViewExplodedGraph or re-compiling the program. 2367330f729Sjoerg This is not very useful for writing tests (apart from testing how ProgramState 2377330f729Sjoerg gets printed), but useful for debugging tests. Also, this method doesn't 2387330f729Sjoerg produce a warning, so it gets printed on the console before all other 2397330f729Sjoerg ExprInspection warnings. 2407330f729Sjoerg 2417330f729Sjoerg Example usage:: 2427330f729Sjoerg 2437330f729Sjoerg void foo() { 2447330f729Sjoerg int x = 1; 2457330f729Sjoerg clang_analyzer_printState(); // Read the stderr! 2467330f729Sjoerg } 2477330f729Sjoerg 2487330f729Sjoerg- ``void clang_analyzer_hashDump(int);`` 2497330f729Sjoerg 2507330f729Sjoerg The analyzer can generate a hash to identify reports. To debug what information 2517330f729Sjoerg is used to calculate this hash it is possible to dump the hashed string as a 2527330f729Sjoerg warning of an arbitrary expression using the function above. 2537330f729Sjoerg 2547330f729Sjoerg Example usage:: 2557330f729Sjoerg 2567330f729Sjoerg void foo() { 2577330f729Sjoerg int x = 1; 2587330f729Sjoerg clang_analyzer_hashDump(x); // expected-warning{{hashed string for x}} 2597330f729Sjoerg } 2607330f729Sjoerg 2617330f729Sjoerg- ``void clang_analyzer_denote(int, const char *);`` 2627330f729Sjoerg 2637330f729Sjoerg Denotes symbols with strings. A subsequent call to clang_analyzer_express() 2647330f729Sjoerg will expresses another symbol in terms of these string. Useful for testing 2657330f729Sjoerg relationships between different symbols. 2667330f729Sjoerg 2677330f729Sjoerg Example usage:: 2687330f729Sjoerg 2697330f729Sjoerg void foo(int x) { 2707330f729Sjoerg clang_analyzer_denote(x, "$x"); 2717330f729Sjoerg clang_analyzer_express(x + 1); // expected-warning{{$x + 1}} 2727330f729Sjoerg } 2737330f729Sjoerg 2747330f729Sjoerg- ``void clang_analyzer_express(int);`` 2757330f729Sjoerg 2767330f729Sjoerg See clang_analyzer_denote(). 2777330f729Sjoerg 278*e038c9c4Sjoerg- ``void clang_analyzer_isTainted(a single argument of any type);`` 279*e038c9c4Sjoerg 280*e038c9c4Sjoerg Queries the analyzer whether the expression used as argument is tainted or not. 281*e038c9c4Sjoerg This is useful in tests, where we don't want to issue warning for all tainted 282*e038c9c4Sjoerg expressions but only check for certain expressions. 283*e038c9c4Sjoerg This would help to reduce the *noise* that the `TaintTest` debug checker would 284*e038c9c4Sjoerg introduce and let you focus on the `expected-warning`'s that you really care 285*e038c9c4Sjoerg about. 286*e038c9c4Sjoerg 287*e038c9c4Sjoerg Example usage:: 288*e038c9c4Sjoerg 289*e038c9c4Sjoerg int read_integer() { 290*e038c9c4Sjoerg int n; 291*e038c9c4Sjoerg clang_analyzer_isTainted(n); // expected-warning{{NO}} 292*e038c9c4Sjoerg scanf("%d", &n); 293*e038c9c4Sjoerg clang_analyzer_isTainted(n); // expected-warning{{YES}} 294*e038c9c4Sjoerg clang_analyzer_isTainted(n + 2); // expected-warning{{YES}} 295*e038c9c4Sjoerg clang_analyzer_isTainted(n > 0); // expected-warning{{YES}} 296*e038c9c4Sjoerg int next_tainted_value = n; // no-warning 297*e038c9c4Sjoerg return n; 298*e038c9c4Sjoerg } 299*e038c9c4Sjoerg 300*e038c9c4Sjoerg- ``clang_analyzer_dumpExtent(a single argument of any type)`` 301*e038c9c4Sjoerg- ``clang_analyzer_dumpElementCount(a single argument of any type)`` 302*e038c9c4Sjoerg 303*e038c9c4Sjoerg Dumps out the extent and the element count of the argument. 304*e038c9c4Sjoerg 305*e038c9c4Sjoerg Example usage:: 306*e038c9c4Sjoerg 307*e038c9c4Sjoerg void array() { 308*e038c9c4Sjoerg int a[] = {1, 3}; 309*e038c9c4Sjoerg clang_analyzer_dumpExtent(a); // expected-warning {{8 S64b}} 310*e038c9c4Sjoerg clang_analyzer_dumpElementCount(a); // expected-warning {{2 S64b}} 311*e038c9c4Sjoerg } 312*e038c9c4Sjoerg 3137330f729SjoergStatistics 3147330f729Sjoerg========== 3157330f729Sjoerg 3167330f729SjoergThe debug.Stats checker collects various information about the analysis of each 3177330f729Sjoergfunction, such as how many blocks were reached and if the analyzer timed out. 3187330f729Sjoerg 3197330f729SjoergThere is also an additional -analyzer-stats flag, which enables various 3207330f729Sjoergstatistics within the analyzer engine. Note the Stats checker (which produces at 3217330f729Sjoergleast one bug report per function) may actually change the values reported by 3227330f729Sjoerg-analyzer-stats. 3237330f729Sjoerg 3247330f729SjoergOutput testing checkers 3257330f729Sjoerg======================= 3267330f729Sjoerg 3277330f729Sjoerg- debug.ReportStmts reports a warning at **every** statement, making it a very 3287330f729Sjoerg useful tool for testing thoroughly bug report construction and output 3297330f729Sjoerg emission. 330