1e5dd7070Spatrick============ 2e5dd7070SpatrickDebug Checks 3e5dd7070Spatrick============ 4e5dd7070Spatrick 5e5dd7070Spatrick.. contents:: 6e5dd7070Spatrick :local: 7e5dd7070Spatrick 8e5dd7070SpatrickThe analyzer contains a number of checkers which can aid in debugging. Enable 9e5dd7070Spatrickthem by using the "-analyzer-checker=" flag, followed by the name of the 10e5dd7070Spatrickchecker. 11e5dd7070Spatrick 12e5dd7070Spatrick 13e5dd7070SpatrickGeneral Analysis Dumpers 14e5dd7070Spatrick======================== 15e5dd7070Spatrick 16e5dd7070SpatrickThese checkers are used to dump the results of various infrastructural analyses 17e5dd7070Spatrickto stderr. Some checkers also have "view" variants, which will display a graph 18e5dd7070Spatrickusing a 'dot' format viewer (such as Graphviz on macOS) instead. 19e5dd7070Spatrick 20e5dd7070Spatrick- debug.DumpCallGraph, debug.ViewCallGraph: Show the call graph generated for 21e5dd7070Spatrick the current translation unit. This is used to determine the order in which to 22e5dd7070Spatrick analyze functions when inlining is enabled. 23e5dd7070Spatrick 24e5dd7070Spatrick- debug.DumpCFG, debug.ViewCFG: Show the CFG generated for each top-level 25e5dd7070Spatrick function being analyzed. 26e5dd7070Spatrick 27e5dd7070Spatrick- debug.DumpDominators: Shows the dominance tree for the CFG of each top-level 28e5dd7070Spatrick function. 29e5dd7070Spatrick 30e5dd7070Spatrick- debug.DumpLiveVars: Show the results of live variable analysis for each 31e5dd7070Spatrick top-level function being analyzed. 32e5dd7070Spatrick 33a9ac8606Spatrick- debug.DumpLiveExprs: Show the results of live expression analysis for each 34e5dd7070Spatrick top-level function being analyzed. 35e5dd7070Spatrick 36e5dd7070Spatrick- debug.ViewExplodedGraph: Show the Exploded Graphs generated for the 37e5dd7070Spatrick analysis of different functions in the input translation unit. When there 38e5dd7070Spatrick are several functions analyzed, display one graph per function. Beware 39e5dd7070Spatrick that these graphs may grow very large, even for small functions. 40e5dd7070Spatrick 41e5dd7070SpatrickPath Tracking 42e5dd7070Spatrick============= 43e5dd7070Spatrick 44e5dd7070SpatrickThese checkers print information about the path taken by the analyzer engine. 45e5dd7070Spatrick 46e5dd7070Spatrick- debug.DumpCalls: Prints out every function or method call encountered during a 47e5dd7070Spatrick path traversal. This is indented to show the call stack, but does NOT do any 48e5dd7070Spatrick special handling of branches, meaning different paths could end up 49e5dd7070Spatrick interleaved. 50e5dd7070Spatrick 51e5dd7070Spatrick- debug.DumpTraversal: Prints the name of each branch statement encountered 52e5dd7070Spatrick during a path traversal ("IfStmt", "WhileStmt", etc). Currently used to check 53e5dd7070Spatrick whether the analysis engine is doing BFS or DFS. 54e5dd7070Spatrick 55e5dd7070Spatrick 56e5dd7070SpatrickState Checking 57e5dd7070Spatrick============== 58e5dd7070Spatrick 59e5dd7070SpatrickThese checkers will print out information about the analyzer state in the form 60e5dd7070Spatrickof analysis warnings. They are intended for use with the -verify functionality 61e5dd7070Spatrickin regression tests. 62e5dd7070Spatrick 63e5dd7070Spatrick- debug.TaintTest: Prints out the word "tainted" for every expression that 64e5dd7070Spatrick carries taint. At the time of this writing, taint was only introduced by the 65e5dd7070Spatrick checks under experimental.security.taint.TaintPropagation; this checker may 66e5dd7070Spatrick eventually move to the security.taint package. 67e5dd7070Spatrick 68e5dd7070Spatrick- debug.ExprInspection: Responds to certain function calls, which are modeled 69e5dd7070Spatrick after builtins. These function calls should affect the program state other 70e5dd7070Spatrick than the evaluation of their arguments; to use them, you will need to declare 71e5dd7070Spatrick them within your test file. The available functions are described below. 72e5dd7070Spatrick 73e5dd7070Spatrick(FIXME: debug.ExprInspection should probably be renamed, since it no longer only 74e5dd7070Spatrickinspects expressions.) 75e5dd7070Spatrick 76e5dd7070Spatrick 77e5dd7070SpatrickExprInspection checks 78e5dd7070Spatrick--------------------- 79e5dd7070Spatrick 80e5dd7070Spatrick- ``void clang_analyzer_eval(bool);`` 81e5dd7070Spatrick 82e5dd7070Spatrick Prints TRUE if the argument is known to have a non-zero value, FALSE if the 83e5dd7070Spatrick argument is known to have a zero or null value, and UNKNOWN if the argument 84e5dd7070Spatrick isn't sufficiently constrained on this path. You can use this to test other 85e5dd7070Spatrick values by using expressions like "x == 5". Note that this functionality is 86e5dd7070Spatrick currently DISABLED in inlined functions, since different calls to the same 87e5dd7070Spatrick inlined function could provide different information, making it difficult to 88e5dd7070Spatrick write proper -verify directives. 89e5dd7070Spatrick 90e5dd7070Spatrick In C, the argument can be typed as 'int' or as '_Bool'. 91e5dd7070Spatrick 92e5dd7070Spatrick Example usage:: 93e5dd7070Spatrick 94e5dd7070Spatrick clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 95e5dd7070Spatrick if (!x) return; 96e5dd7070Spatrick clang_analyzer_eval(x); // expected-warning{{TRUE}} 97e5dd7070Spatrick 98e5dd7070Spatrick 99e5dd7070Spatrick- ``void clang_analyzer_checkInlined(bool);`` 100e5dd7070Spatrick 101e5dd7070Spatrick If a call occurs within an inlined function, prints TRUE or FALSE according to 102e5dd7070Spatrick the value of its argument. If a call occurs outside an inlined function, 103e5dd7070Spatrick nothing is printed. 104e5dd7070Spatrick 105e5dd7070Spatrick The intended use of this checker is to assert that a function is inlined at 106e5dd7070Spatrick least once (by passing 'true' and expecting a warning), or to assert that a 107e5dd7070Spatrick function is never inlined (by passing 'false' and expecting no warning). The 108e5dd7070Spatrick argument is technically unnecessary but is intended to clarify intent. 109e5dd7070Spatrick 110e5dd7070Spatrick You might wonder why we can't print TRUE if a function is ever inlined and 111e5dd7070Spatrick FALSE if it is not. The problem is that any inlined function could conceivably 112e5dd7070Spatrick also be analyzed as a top-level function (in which case both TRUE and FALSE 113e5dd7070Spatrick would be printed), depending on the value of the -analyzer-inlining option. 114e5dd7070Spatrick 115e5dd7070Spatrick In C, the argument can be typed as 'int' or as '_Bool'. 116e5dd7070Spatrick 117e5dd7070Spatrick Example usage:: 118e5dd7070Spatrick 119e5dd7070Spatrick int inlined() { 120e5dd7070Spatrick clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} 121e5dd7070Spatrick return 42; 122e5dd7070Spatrick } 123e5dd7070Spatrick 124e5dd7070Spatrick void topLevel() { 125e5dd7070Spatrick clang_analyzer_checkInlined(false); // no-warning (not inlined) 126e5dd7070Spatrick int value = inlined(); 127e5dd7070Spatrick // This assertion will not be valid if the previous call was not inlined. 128e5dd7070Spatrick clang_analyzer_eval(value == 42); // expected-warning{{TRUE}} 129e5dd7070Spatrick } 130e5dd7070Spatrick 131e5dd7070Spatrick- ``void clang_analyzer_warnIfReached();`` 132e5dd7070Spatrick 133e5dd7070Spatrick Generate a warning if this line of code gets reached by the analyzer. 134e5dd7070Spatrick 135e5dd7070Spatrick Example usage:: 136e5dd7070Spatrick 137e5dd7070Spatrick if (true) { 138e5dd7070Spatrick clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 139e5dd7070Spatrick } 140e5dd7070Spatrick else { 141e5dd7070Spatrick clang_analyzer_warnIfReached(); // no-warning 142e5dd7070Spatrick } 143e5dd7070Spatrick 144e5dd7070Spatrick- ``void clang_analyzer_numTimesReached();`` 145e5dd7070Spatrick 146e5dd7070Spatrick Same as above, but include the number of times this call expression 147e5dd7070Spatrick gets reached by the analyzer during the current analysis. 148e5dd7070Spatrick 149e5dd7070Spatrick Example usage:: 150e5dd7070Spatrick 151e5dd7070Spatrick for (int x = 0; x < 3; ++x) { 152e5dd7070Spatrick clang_analyzer_numTimesReached(); // expected-warning{{3}} 153e5dd7070Spatrick } 154e5dd7070Spatrick 155e5dd7070Spatrick- ``void clang_analyzer_warnOnDeadSymbol(int);`` 156e5dd7070Spatrick 157e5dd7070Spatrick Subscribe for a delayed warning when the symbol that represents the value of 158e5dd7070Spatrick the argument is garbage-collected by the analyzer. 159e5dd7070Spatrick 160e5dd7070Spatrick When calling 'clang_analyzer_warnOnDeadSymbol(x)', if value of 'x' is a 161e5dd7070Spatrick symbol, then this symbol is marked by the ExprInspection checker. Then, 162e5dd7070Spatrick during each garbage collection run, the checker sees if the marked symbol is 163e5dd7070Spatrick being collected and issues the 'SYMBOL DEAD' warning if it does. 164e5dd7070Spatrick This way you know where exactly, up to the line of code, the symbol dies. 165e5dd7070Spatrick 166e5dd7070Spatrick It is unlikely that you call this function after the symbol is already dead, 167e5dd7070Spatrick because the very reference to it as the function argument prevents it from 168e5dd7070Spatrick dying. However, if the argument is not a symbol but a concrete value, 169e5dd7070Spatrick no warning would be issued. 170e5dd7070Spatrick 171e5dd7070Spatrick Example usage:: 172e5dd7070Spatrick 173e5dd7070Spatrick do { 174e5dd7070Spatrick int x = generate_some_integer(); 175e5dd7070Spatrick clang_analyzer_warnOnDeadSymbol(x); 176e5dd7070Spatrick } while(0); // expected-warning{{SYMBOL DEAD}} 177e5dd7070Spatrick 178e5dd7070Spatrick 179e5dd7070Spatrick- ``void clang_analyzer_explain(a single argument of any type);`` 180e5dd7070Spatrick 181e5dd7070Spatrick This function explains the value of its argument in a human-readable manner 182e5dd7070Spatrick in the warning message. You can make as many overrides of its prototype 183e5dd7070Spatrick in the test code as necessary to explain various integral, pointer, 184e5dd7070Spatrick or even record-type values. To simplify usage in C code (where overloading 185e5dd7070Spatrick the function declaration is not allowed), you may append an arbitrary suffix 186e5dd7070Spatrick to the function name, without affecting functionality. 187e5dd7070Spatrick 188e5dd7070Spatrick Example usage:: 189e5dd7070Spatrick 190e5dd7070Spatrick void clang_analyzer_explain(int); 191e5dd7070Spatrick void clang_analyzer_explain(void *); 192e5dd7070Spatrick 193e5dd7070Spatrick // Useful in C code 194e5dd7070Spatrick void clang_analyzer_explain_int(int); 195e5dd7070Spatrick 196e5dd7070Spatrick void foo(int param, void *ptr) { 197e5dd7070Spatrick clang_analyzer_explain(param); // expected-warning{{argument 'param'}} 198e5dd7070Spatrick clang_analyzer_explain_int(param); // expected-warning{{argument 'param'}} 199e5dd7070Spatrick if (!ptr) 200e5dd7070Spatrick clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}} 201e5dd7070Spatrick } 202e5dd7070Spatrick 203e5dd7070Spatrick- ``void clang_analyzer_dump( /* a single argument of any type */);`` 204e5dd7070Spatrick 205e5dd7070Spatrick Similar to clang_analyzer_explain, but produces a raw dump of the value, 206e5dd7070Spatrick same as SVal::dump(). 207e5dd7070Spatrick 208e5dd7070Spatrick Example usage:: 209e5dd7070Spatrick 210e5dd7070Spatrick void clang_analyzer_dump(int); 211e5dd7070Spatrick void foo(int x) { 212e5dd7070Spatrick clang_analyzer_dump(x); // expected-warning{{reg_$0<x>}} 213e5dd7070Spatrick } 214e5dd7070Spatrick 215e5dd7070Spatrick- ``size_t clang_analyzer_getExtent(void *);`` 216e5dd7070Spatrick 217e5dd7070Spatrick This function returns the value that represents the extent of a memory region 218e5dd7070Spatrick pointed to by the argument. This value is often difficult to obtain otherwise, 219e5dd7070Spatrick because no valid code that produces this value. However, it may be useful 220e5dd7070Spatrick for testing purposes, to see how well does the analyzer model region extents. 221e5dd7070Spatrick 222e5dd7070Spatrick Example usage:: 223e5dd7070Spatrick 224e5dd7070Spatrick void foo() { 225e5dd7070Spatrick int x, *y; 226e5dd7070Spatrick size_t xs = clang_analyzer_getExtent(&x); 227e5dd7070Spatrick clang_analyzer_explain(xs); // expected-warning{{'4'}} 228e5dd7070Spatrick size_t ys = clang_analyzer_getExtent(&y); 229e5dd7070Spatrick clang_analyzer_explain(ys); // expected-warning{{'8'}} 230e5dd7070Spatrick } 231e5dd7070Spatrick 232e5dd7070Spatrick- ``void clang_analyzer_printState();`` 233e5dd7070Spatrick 234e5dd7070Spatrick Dumps the current ProgramState to the stderr. Quickly lookup the program state 235e5dd7070Spatrick at any execution point without ViewExplodedGraph or re-compiling the program. 236e5dd7070Spatrick This is not very useful for writing tests (apart from testing how ProgramState 237e5dd7070Spatrick gets printed), but useful for debugging tests. Also, this method doesn't 238e5dd7070Spatrick produce a warning, so it gets printed on the console before all other 239e5dd7070Spatrick ExprInspection warnings. 240e5dd7070Spatrick 241e5dd7070Spatrick Example usage:: 242e5dd7070Spatrick 243e5dd7070Spatrick void foo() { 244e5dd7070Spatrick int x = 1; 245e5dd7070Spatrick clang_analyzer_printState(); // Read the stderr! 246e5dd7070Spatrick } 247e5dd7070Spatrick 248e5dd7070Spatrick- ``void clang_analyzer_hashDump(int);`` 249e5dd7070Spatrick 250e5dd7070Spatrick The analyzer can generate a hash to identify reports. To debug what information 251e5dd7070Spatrick is used to calculate this hash it is possible to dump the hashed string as a 252e5dd7070Spatrick warning of an arbitrary expression using the function above. 253e5dd7070Spatrick 254e5dd7070Spatrick Example usage:: 255e5dd7070Spatrick 256e5dd7070Spatrick void foo() { 257e5dd7070Spatrick int x = 1; 258e5dd7070Spatrick clang_analyzer_hashDump(x); // expected-warning{{hashed string for x}} 259e5dd7070Spatrick } 260e5dd7070Spatrick 261e5dd7070Spatrick- ``void clang_analyzer_denote(int, const char *);`` 262e5dd7070Spatrick 263e5dd7070Spatrick Denotes symbols with strings. A subsequent call to clang_analyzer_express() 264e5dd7070Spatrick will expresses another symbol in terms of these string. Useful for testing 265e5dd7070Spatrick relationships between different symbols. 266e5dd7070Spatrick 267e5dd7070Spatrick Example usage:: 268e5dd7070Spatrick 269e5dd7070Spatrick void foo(int x) { 270e5dd7070Spatrick clang_analyzer_denote(x, "$x"); 271e5dd7070Spatrick clang_analyzer_express(x + 1); // expected-warning{{$x + 1}} 272e5dd7070Spatrick } 273e5dd7070Spatrick 274e5dd7070Spatrick- ``void clang_analyzer_express(int);`` 275e5dd7070Spatrick 276e5dd7070Spatrick See clang_analyzer_denote(). 277e5dd7070Spatrick 278ec727ea7Spatrick- ``void clang_analyzer_isTainted(a single argument of any type);`` 279ec727ea7Spatrick 280ec727ea7Spatrick Queries the analyzer whether the expression used as argument is tainted or not. 281ec727ea7Spatrick This is useful in tests, where we don't want to issue warning for all tainted 282ec727ea7Spatrick expressions but only check for certain expressions. 283ec727ea7Spatrick This would help to reduce the *noise* that the `TaintTest` debug checker would 284ec727ea7Spatrick introduce and let you focus on the `expected-warning`'s that you really care 285ec727ea7Spatrick about. 286ec727ea7Spatrick 287ec727ea7Spatrick Example usage:: 288ec727ea7Spatrick 289ec727ea7Spatrick int read_integer() { 290ec727ea7Spatrick int n; 291ec727ea7Spatrick clang_analyzer_isTainted(n); // expected-warning{{NO}} 292ec727ea7Spatrick scanf("%d", &n); 293ec727ea7Spatrick clang_analyzer_isTainted(n); // expected-warning{{YES}} 294ec727ea7Spatrick clang_analyzer_isTainted(n + 2); // expected-warning{{YES}} 295ec727ea7Spatrick clang_analyzer_isTainted(n > 0); // expected-warning{{YES}} 296ec727ea7Spatrick int next_tainted_value = n; // no-warning 297ec727ea7Spatrick return n; 298ec727ea7Spatrick } 299ec727ea7Spatrick 300a9ac8606Spatrick- ``clang_analyzer_dumpExtent(a single argument of any type)`` 301a9ac8606Spatrick- ``clang_analyzer_dumpElementCount(a single argument of any type)`` 302a9ac8606Spatrick 303a9ac8606Spatrick Dumps out the extent and the element count of the argument. 304a9ac8606Spatrick 305a9ac8606Spatrick Example usage:: 306a9ac8606Spatrick 307a9ac8606Spatrick void array() { 308a9ac8606Spatrick int a[] = {1, 3}; 309a9ac8606Spatrick clang_analyzer_dumpExtent(a); // expected-warning {{8 S64b}} 310a9ac8606Spatrick clang_analyzer_dumpElementCount(a); // expected-warning {{2 S64b}} 311*12c85518Srobert } 312*12c85518Srobert 313*12c85518Srobert- ``clang_analyzer_value(a single argument of integer or pointer type)`` 314*12c85518Srobert 315*12c85518Srobert Prints an associated value for the given argument. 316*12c85518Srobert Supported argument types are integers, enums and pointers. 317*12c85518Srobert The value can be represented either as a range set or as a concrete integer. 318*12c85518Srobert For the rest of the types function prints ``n/a`` (aka not available). 319*12c85518Srobert 320*12c85518Srobert **Note:** This function will print nothing for clang built with Z3 constraint manager. 321*12c85518Srobert This may cause crashes of your tests. To manage this use one of the test constraining 322*12c85518Srobert techniques: 323*12c85518Srobert 324*12c85518Srobert * llvm-lit commands ``REQUIRES no-z3`` or ``UNSUPPORTED z3`` `See for details. <https://llvm.org/docs/TestingGuide.html#constraining-test-execution>`_ 325*12c85518Srobert 326*12c85518Srobert * a preprocessor directive ``#ifndef ANALYZER_CM_Z3`` 327*12c85518Srobert 328*12c85518Srobert * a clang command argument ``-analyzer-constraints=range`` 329*12c85518Srobert 330*12c85518Srobert Example usage:: 331*12c85518Srobert 332*12c85518Srobert void print(char c, unsigned u) { 333*12c85518Srobert clang_analyzer_value(c); // expected-warning {{8s:{ [-128, 127] }}} 334*12c85518Srobert if(u != 42) 335*12c85518Srobert clang_analyzer_value(u); // expected-warning {{32u:{ [0, 41], [43, 4294967295] }}} 336*12c85518Srobert else 337*12c85518Srobert clang_analyzer_value(u); // expected-warning {{32u:42}} 338a9ac8606Spatrick } 339a9ac8606Spatrick 340e5dd7070SpatrickStatistics 341e5dd7070Spatrick========== 342e5dd7070Spatrick 343e5dd7070SpatrickThe debug.Stats checker collects various information about the analysis of each 344e5dd7070Spatrickfunction, such as how many blocks were reached and if the analyzer timed out. 345e5dd7070Spatrick 346e5dd7070SpatrickThere is also an additional -analyzer-stats flag, which enables various 347e5dd7070Spatrickstatistics within the analyzer engine. Note the Stats checker (which produces at 348e5dd7070Spatrickleast one bug report per function) may actually change the values reported by 349e5dd7070Spatrick-analyzer-stats. 350e5dd7070Spatrick 351e5dd7070SpatrickOutput testing checkers 352e5dd7070Spatrick======================= 353e5dd7070Spatrick 354e5dd7070Spatrick- debug.ReportStmts reports a warning at **every** statement, making it a very 355e5dd7070Spatrick useful tool for testing thoroughly bug report construction and output 356e5dd7070Spatrick emission. 357