1===================================== 2Cross Translation Unit (CTU) Analysis 3===================================== 4 5Normally, static analysis works in the boundary of one translation unit (TU). 6However, with additional steps and configuration we can enable the analysis to inline the definition of a function from another TU. 7 8.. contents:: 9 :local: 10 11Manual CTU Analysis 12------------------- 13 14Let's consider these source files in our minimal example: 15 16.. code-block:: cpp 17 18 // main.cpp 19 int foo(); 20 21 int main() { 22 return 3 / foo(); 23 } 24 25.. code-block:: cpp 26 27 // foo.cpp 28 int foo() { 29 return 0; 30 } 31 32And a compilation database: 33 34.. code-block:: bash 35 36 [ 37 { 38 "directory": "/path/to/your/project", 39 "command": "clang++ -c foo.cpp -o foo.o", 40 "file": "foo.cpp" 41 }, 42 { 43 "directory": "/path/to/your/project", 44 "command": "clang++ -c main.cpp -o main.o", 45 "file": "main.cpp" 46 } 47 ] 48 49We'd like to analyze `main.cpp` and discover the division by zero bug. 50In order to be able to inline the definition of `foo` from `foo.cpp` first we have to generate the `AST` (or `PCH`) file of `foo.cpp`: 51 52.. code-block:: bash 53 54 $ pwd $ /path/to/your/project 55 $ clang++ -emit-ast -o foo.cpp.ast foo.cpp 56 $ # Check that the .ast file is generated: 57 $ ls 58 compile_commands.json foo.cpp.ast foo.cpp main.cpp 59 $ 60 61The next step is to create a CTU index file which holds the `USR` name and location of external definitions in the source files: 62 63.. code-block:: bash 64 65 $ clang-extdef-mapping -p . foo.cpp 66 c:@F@foo# /path/to/your/project/foo.cpp 67 $ clang-extdef-mapping -p . foo.cpp > externalDefMap.txt 68 69We have to modify `externalDefMap.txt` to contain the name of the `.ast` files instead of the source files: 70 71.. code-block:: bash 72 73 $ sed -i -e "s/.cpp/.cpp.ast/g" externalDefMap.txt 74 75We still have to further modify the `externalDefMap.txt` file to contain relative paths: 76 77.. code-block:: bash 78 79 $ sed -i -e "s|$(pwd)/||g" externalDefMap.txt 80 81Now everything is available for the CTU analysis. 82We have to feed Clang with CTU specific extra arguments: 83 84.. code-block:: bash 85 86 $ pwd 87 /path/to/your/project 88 $ clang++ --analyze -Xclang -analyzer-config -Xclang experimental-enable-naive-ctu-analysis=true -Xclang -analyzer-config -Xclang ctu-dir=. -Xclang -analyzer-output=plist-multi-file main.cpp 89 main.cpp:5:12: warning: Division by zero 90 return 3 / foo(); 91 ~~^~~~~~~ 92 1 warning generated. 93 $ # The plist file with the result is generated. 94 $ ls 95 compile_commands.json externalDefMap.txt foo.ast foo.cpp foo.cpp.ast main.cpp main.plist 96 $ 97 98This manual procedure is error-prone and not scalable, therefore to analyze real projects it is recommended to use `CodeChecker` or `scan-build-py`. 99 100Automated CTU Analysis with CodeChecker 101--------------------------------------- 102The `CodeChecker <https://github.com/Ericsson/codechecker>`_ project fully supports automated CTU analysis with Clang. 103Once we have set up the `PATH` environment variable and we activated the python `venv` then it is all it takes: 104 105.. code-block:: bash 106 107 $ CodeChecker analyze --ctu compile_commands.json -o reports 108 [INFO 2019-07-16 17:21] - Pre-analysis started. 109 [INFO 2019-07-16 17:21] - Collecting data for ctu analysis. 110 [INFO 2019-07-16 17:21] - [1/2] foo.cpp 111 [INFO 2019-07-16 17:21] - [2/2] main.cpp 112 [INFO 2019-07-16 17:21] - Pre-analysis finished. 113 [INFO 2019-07-16 17:21] - Starting static analysis ... 114 [INFO 2019-07-16 17:21] - [1/2] clangsa analyzed foo.cpp successfully. 115 [INFO 2019-07-16 17:21] - [2/2] clangsa analyzed main.cpp successfully. 116 [INFO 2019-07-16 17:21] - ----==== Summary ====---- 117 [INFO 2019-07-16 17:21] - Successfully analyzed 118 [INFO 2019-07-16 17:21] - clangsa: 2 119 [INFO 2019-07-16 17:21] - Total analyzed compilation commands: 2 120 [INFO 2019-07-16 17:21] - ----=================---- 121 [INFO 2019-07-16 17:21] - Analysis finished. 122 [INFO 2019-07-16 17:21] - To view results in the terminal use the "CodeChecker parse" command. 123 [INFO 2019-07-16 17:21] - To store results use the "CodeChecker store" command. 124 [INFO 2019-07-16 17:21] - See --help and the user guide for further options about parsing and storing the reports. 125 [INFO 2019-07-16 17:21] - ----=================---- 126 [INFO 2019-07-16 17:21] - Analysis length: 0.659618854523 sec. 127 $ ls 128 compile_commands.json foo.cpp foo.cpp.ast main.cpp reports 129 $ tree reports 130 reports 131 ├── compile_cmd.json 132 ├── compiler_info.json 133 ├── foo.cpp_53f6fbf7ab7ec9931301524b551959e2.plist 134 ├── main.cpp_23db3d8df52ff0812e6e5a03071c8337.plist 135 ├── metadata.json 136 └── unique_compile_commands.json 137 138 0 directories, 6 files 139 $ 140 141The `plist` files contain the results of the analysis, which may be viewed with the regular analysis tools. 142E.g. one may use `CodeChecker parse` to view the results in command line: 143 144.. code-block:: bash 145 146 $ CodeChecker parse reports 147 [HIGH] /home/egbomrt/ctu_mini_raw_project/main.cpp:5:12: Division by zero [core.DivideZero] 148 return 3 / foo(); 149 ^ 150 151 Found 1 defect(s) in main.cpp 152 153 154 ----==== Summary ====---- 155 ----------------------- 156 Filename | Report count 157 ----------------------- 158 main.cpp | 1 159 ----------------------- 160 ----------------------- 161 Severity | Report count 162 ----------------------- 163 HIGH | 1 164 ----------------------- 165 ----=================---- 166 Total number of reports: 1 167 ----=================---- 168 169Or we can use `CodeChecker parse -e html` to export the results into HTML format: 170 171.. code-block:: bash 172 173 $ CodeChecker parse -e html -o html_out reports 174 $ firefox html_out/index.html 175 176Automated CTU Analysis with scan-build-py (don't do it) 177------------------------------------------------------- 178We actively develop CTU with CodeChecker as a "runner" script, `scan-build-py` is not actively developed for CTU. 179`scan-build-py` has various errors and issues, expect it to work with the very basic projects only. 180 181Example usage of scan-build-py: 182 183.. code-block:: bash 184 185 $ /your/path/to/llvm-project/clang/tools/scan-build-py/bin/analyze-build --ctu 186 analyze-build: Run 'scan-view /tmp/scan-build-2019-07-17-17-53-33-810365-7fqgWk' to examine bug reports. 187 $ /your/path/to/llvm-project/clang/tools/scan-view/bin/scan-view /tmp/scan-build-2019-07-17-17-53-33-810365-7fqgWk 188 Starting scan-view at: http://127.0.0.1:8181 189 Use Ctrl-C to exit. 190 [6336:6431:0717/175357.633914:ERROR:browser_process_sub_thread.cc(209)] Waited 5 ms for network service 191 Opening in existing browser session. 192 ^C 193 $ 194