blob: 39a51336da708b361692b636c73df09ac50d6327 [file] [log] [blame] [view]
andybons222c4ee2015-08-25 16:51:031# The Clang Static Analyzer
andybons3322f762015-08-24 21:37:092
Kevin Marshall089565ec2017-07-13 02:57:213The Clang C/C++ compiler comes with a static analyzer which can be used to find
4bugs using path sensitive analysis. Path sensitive analysis is
5a technique that explores all the possible branches in code and
6records the codepaths that might lead to bad or undefined behavior,
7like an uninitialized reads, use after frees, pointer leaks, and so on.
andybons3322f762015-08-24 21:37:098
Kevin Marshall089565ec2017-07-13 02:57:219You can now use these static analysis capabilities to find potential bugs in
10Chromium code! Note that this capability is quite new, and as of this writing,
11there are still a large number of warnings to be fixed in Chromium and especially
12in its third_party dependencies. Some of the warnings might be false positives,
13see the section on "Addressing false positives" for more information on
14resolving them.
andybons222c4ee2015-08-25 16:51:0315
Kevin Marshall089565ec2017-07-13 02:57:2116We're still evaluating this tool, please let us know if you find it useful.
17
18See the [official Clang static analyzer page](http://clang-analyzer.llvm.org/)
19for more background information.
20
21## Save some time, look at the buildbot logs!
22
23We run static analysis builds continously, all day long on FYI buildbots.
24You can save yourself some time by first inspecting their build logs for errors
25before running your own analysis builds. You will probably need to Ctrl-F the
26logs to find any issues for the specific files you're interested in.
27
28You can find the analysis logs in the `compile stdout` step.
29* [Linux buildbot logs](https://build.chromium.org/p/chromium.fyi/waterfall?show=Linux%20Clang%20Analyzer)
30
31## Enabling static analysis
32To get static analysis running for your build, add the following flag to your GN
33args.
andybons3322f762015-08-24 21:37:0934
35```
kmarshall520f9512017-01-24 23:25:0136use_clang_static_analyzer = true
andybons3322f762015-08-24 21:37:0937```
38
Kevin Marshall089565ec2017-07-13 02:57:2139The next time you run your build, you should see static analysis warnings appear
40inline with the usual Clang build warnings and errors. Expect some slowdown on
41your build; anywhere from a 10% increase on local builds, to well over 100% under Goma
42([crbug](crbug.com/733363)).
43
44## Supported checks
45Clang's static analyzer comes with a wide variety of checkers. Some of the checks
46aren't useful because they are intended for different languages, platforms, or
47coding conventions than the ones used for Chromium development.
48
49The checkers that we are interested in running for Chromium are in the
50`analyzer_option_flags` variable in
51[clang_static_analyzer_wrapper.py](../build/toolchain/clang_static_analyzer_wrapper.py).
52
53As of this writing, the checker suites we support are
54[core](https://clang-analyzer.llvm.org/available_checks.html#core_checkers),
55[cplusplus](https://clang-analyzer.llvm.org/available_checks.html#cplusplus_checkers), and
56[deadcode](https://clang-analyzer.llvm.org/available_checks.html#deadcode_checkers).
57
58To add or remove checkers, simply modify the `-analyzer-checker=` flags.
59Remember that checkers aren't free; additional checkers will add to the
60analysis time.
61
62## Addressing false positives
63
64Some of the errors you encounter might be false positives, which occurs when the
65static analyzer naively follows codepaths which are practically impossible to hit
66at runtime. Fortunately, we have a tool at our disposal for guiding the analyzer
67away from impossible codepaths: assertion handlers like DCHECK/CHECK/LOG(FATAL).
68The analyzer won't check the codepaths which we assert are unreachable.
69
70An example would be that if the analyzer detected the function argument `*my_ptr`
71might be null and dereferencing it would potentially segfault, you would see the
72error `warning: Dereference of null pointer (loaded from variable 'my_ptr')`.
73If you know for a fact that my_ptr will not be null in practice, then you can
74place an assert at the top of the function: `DCHECK(my_ptr)`. The analyzer will
75no longer generate the warning.
76
77Be mindful about only specifying assertions which are factually correct! Don't
78DCHECK recklessly just to quiet down the analyzer. :)
79
80Other types of false positives and their suppressions:
81* Unreachable code paths. To suppress, add the `ANALYZER_SKIP_THIS_PATH();`
82 directive to the relevant code block.
83* Dead stores. To suppress, use the macro
84 `ANALYZER_ALLOW_UNUSED(my_var)`. This also suppresses dead store warnings
85 on conventional builds without static analysis enabled!
86
87See the definitions of the ANALYZER_* macros in base/logging.h for more
88detailed information about how the annotations are implemented.
89
90## Logging bugs
91
92If you find any issues with the static analyzer, or find Chromium code behaving
93badly with the analyzer, please check the `Infra>CodeAnalysis` CrBug component
94to look for known issues, or file a bug if it is a new problem.
95
96***
97
98## Technical details
99### GN hooks
100The platform toolchain .gni/BUILD.gn files check for the
101`use_clang_static_analyzer` flag and modify the compiler command line so as to
102call the analysis wrapper script rather than call the compiler directly.
103The flag has no effect on assembler invocations, linker invocations, or
104NaCl toolchain builds.
105
106### Analysis wrapper script
107The entry point for running analysis is the Python script
108`//build/toolchain/clang_static_analyzer_wrapper.py` which invokes Clang
109with the parameters for running static analysis.
110
111**Alternatives considered**
112A script-less, GN-based solution is not possible because GN's control flows
113are very limited in how they may be extended.
114
115The `scan-build` wrapper script included with Clang does not
116work with Goma, so it couldn't be used.
andybons3322f762015-08-24 21:37:09117