Skip to content

Commit ac03915

Browse files
encukoupicnixzhugovk
authored
Modernize "Dynamic analysis with Clang" (GH-1378)
Remove instructions to build from source. Clang 18.x or 20.x is much easier to get “normally” than 3.4 was, and it has its own documentation. Mention the configure options, but keep the previous instructions (seting CC/CXX) as “thorough setup”. Use the modern option name `-fsanitize-ignorelist`. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
1 parent 94d4d60 commit ac03915

File tree

1 file changed

+81
-154
lines changed

1 file changed

+81
-154
lines changed

development-tools/clang.rst

Lines changed: 81 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,21 @@ Dynamic analysis with Clang
77
.. highlight:: bash
88

99
This document describes how to use Clang to perform analysis on Python and its
10-
libraries. In addition to performing the analysis, the document will cover
11-
downloading, building and installing the latest Clang/LLVM combination (which
12-
is currently 3.4).
10+
libraries.
1311

1412
This document does not cover interpreting the findings. For a discussion of
1513
interpreting results, see Marshall Clow's `Testing libc++ with
1614
-fsanitize=undefined <https://cplusplusmusings.wordpress.com/tag/clang/>`_. The
1715
blog posting is a detailed examinations of issues uncovered by Clang in
1816
``libc++``.
1917

18+
The document focuses on Clang, although most techniques should generally apply
19+
to GCC's sanitizers as well.
20+
21+
The instructions were tested on Linux, but they should work on macOS as well.
22+
Instructions for Windows are incomplete.
23+
24+
2025
What is Clang?
2126
==============
2227

@@ -49,177 +54,95 @@ A complete list of sanitizers can be found at `Controlling Code Generation
4954

5055
Clang and its sanitizers have strengths (and weaknesses). Its just one tool in
5156
the war chest to uncovering bugs and improving code quality. Clang should be
52-
used to compliment other methods, including Code Reviews, Valgrind, Coverity,
57+
used to complement other methods, including Code Reviews, Valgrind, Coverity,
5358
etc.
5459

5560
Clang/LLVM setup
5661
================
5762

58-
This portion of the document covers downloading, building and installing Clang
59-
and LLVM. There are three components to download and build. They are the LLVM
60-
compiler, the compiler front end and the compiler runtime library.
61-
62-
In preparation you should create a scratch directory. Also ensure you are using
63-
Python 2 and not Python 3. Python 3 will cause the build to fail.
64-
65-
Download, build and install
66-
---------------------------
67-
68-
Perform the following to download, build and install the Clang/LLVM 3.4. ::
69-
70-
# Download
71-
wget https://llvm.org/releases/3.4/llvm-3.4.src.tar.gz
72-
wget https://llvm.org/releases/3.4/clang-3.4.src.tar.gz
73-
wget https://llvm.org/releases/3.4/compiler-rt-3.4.src.tar.gz
74-
75-
# LLVM
76-
tar xvf llvm-3.4.src.tar.gz
77-
cd llvm-3.4/tools
63+
Pre-built Clang builds are available for most platforms:
7864

79-
# Clang Front End
80-
tar xvf ../../clang-3.4.src.tar.gz
81-
mv clang-3.4 clang
65+
- On macOS, Clang is the default compiler.
66+
- For mainstream Linux distros, you can install a ``clang`` package.
67+
In some cases, you also need to install ``llvm`` separately, otherwise
68+
some tools are not available.
69+
- On Windows, the installer for Visual Studio (not Code)
70+
includes the "C++ clang tools for windows" feature.
8271

83-
# Compiler RT
84-
cd ../projects
85-
tar xvf ../../compiler-rt-3.4.src.tar.gz
86-
mv compiler-rt-3.4/ compiler-rt
72+
You can also build ``clang`` from source; refer to
73+
`the clang documentation <https://clang.llvm.org/>`_ for details.
8774

88-
# Build
89-
cd ..
90-
./configure --enable-optimized --prefix=/usr/local
91-
make -j4
92-
sudo make install
93-
94-
.. note::
95-
96-
If you receive an error ``'LibraryDependencies.inc' file not found``, then
97-
ensure you are utilizing Python 2 and not Python 3. If you encounter the
98-
error after switching to Python 2, then delete everything and start over.
99-
100-
After ``make install`` executes, the compilers will be installed in
101-
``/usr/local/bin`` and the various libraries will be installed in
102-
``/usr/local/lib/clang/3.4/lib/linux/``:
103-
104-
.. code-block:: console
75+
The installer does not install all the components needed on occasion. For
76+
example, you might want to run a ``scan-build`` or examine the results with
77+
``scan-view``. If this is your case, you can build Clang from source and
78+
copy tools from ``tools/clang/tools`` to a directory on your ``PATH``.
10579

106-
$ ls /usr/local/lib/clang/3.4/lib/linux/
107-
libclang_rt.asan-x86_64.a libclang_rt.profile-x86_64.a
108-
libclang_rt.dfsan-x86_64.a libclang_rt.san-x86_64.a
109-
libclang_rt.full-x86_64.a libclang_rt.tsan-x86_64.a
110-
libclang_rt.lsan-x86_64.a libclang_rt.ubsan_cxx-x86_64.a
111-
libclang_rt.msan-x86_64.a libclang_rt.ubsan-x86_64.a
80+
Another reason to build from source is to get the latest version of Clang/LLVM,
81+
if your platform's channels don't provide it yet.
82+
Newer versions of Clang/LLVM introduce new sanitizer checks.
11283

113-
On macOS, the libraries are installed in
114-
``/usr/local/lib/clang/3.3/lib/darwin/``:
11584

116-
.. code-block:: console
85+
Python build setup
86+
==================
11787

118-
$ ls /usr/local/lib/clang/3.3/lib/darwin/
119-
libclang_rt.10.4.a libclang_rt.ios.a
120-
libclang_rt.asan_osx.a libclang_rt.osx.a
121-
libclang_rt.asan_osx_dynamic.dylib libclang_rt.profile_ios.a
122-
libclang_rt.cc_kext.a libclang_rt.profile_osx.a
123-
libclang_rt.cc_kext_ios5.a libclang_rt.ubsan_osx.a
124-
libclang_rt.eprintf.a
88+
This portion of the document covers invoking Clang and LLVM with the options
89+
required so the sanitizers analyze Python with under its test suite.
12590

126-
.. note::
91+
Set the compiler to Clang, in case it's not the default::
12792

128-
You should never have to add the libraries to a project. Clang will handle
129-
it for you. If you find you cannot pass the ``-fsanitize=XXX`` flag through
130-
``make``'s implicit variables (``CFLAGS``, ``CXXFLAGS``, ``CC``,
131-
``CXXFLAGS``, ``LDFLAGS``) during ``configure``, then you should modify the
132-
makefile after configuring to ensure the flag is passed through the
133-
compiler.
93+
export CC="clang"
13494

135-
The installer does not install all the components needed on occasion. For
136-
example, you might want to run a ``scan-build`` or examine the results with
137-
``scan-view``. You can copy the components by hand with: ::
95+
If you want to use additional sanitizer options (found in Clang documentation),
96+
add them to the ``CFLAGS`` variable.
97+
For example, you may want the checked process to exit after the first failure::
13898

139-
sudo mkdir /usr/local/bin/scan-build
140-
sudo cp -r llvm-3.4/tools/clang/tools/scan-build /usr/local/bin
141-
sudo mkdir /usr/local/bin/scan-view
142-
sudo cp -r llvm-3.4/tools/clang/tools/scan-view /usr/local/bin
99+
export CFLAGS="-fno-sanitize-recover"
143100

144-
.. note::
101+
Then, run ``./configure`` with the relevant flags:
145102

146-
Because the installer does not install all the components needed on
147-
occasion, you should not delete the scratch directory until you are sure
148-
things work as expected. If a library is missing, then you should search for
149-
it in the Clang/LLVM build directory.
103+
* ASan: ``--with-address-sanitizer --without-pymalloc``
104+
* UBsan: ``--with-undefined-behavior-sanitizer``
150105

151-
Python build setup
152-
==================
106+
It is OK to specify both sanitizers.
153107

154-
This portion of the document covers invoking Clang and LLVM with the options
155-
required so the sanitizers analyze Python with under its test suite. Two
156-
checkers are used - ASan and UBSan.
108+
After that, run ``make`` and ``make test`` as usual.
109+
Note that ``make`` itself may fail with a sanitizer failure,
110+
since the just-compiled Python runs during later stages of the build.
157111

158-
Because the sanitizers are runtime checkers, its best to have as many positive
159-
and negative self tests as possible. You can never have enough self tests.
160112

161-
The general idea is to compile and link with the sanitizer flags. At link time,
162-
Clang will include the needed runtime libraries. However, you can't use
163-
``CFLAGS`` and ``CXXFLAGS`` to pass the options through the compiler to the
164-
linker because the makefile rules for ``BUILDPYTHON``, ``_testembed`` and
165-
``_freeze_importlib`` don't use the implicit variables.
113+
Build setup for enabling sanitizers for all code
114+
------------------------------------------------
166115

167-
As a workaround to the absence of flags to the linker, you can pass the
168-
sanitizer options by way of the compilers - ``CC`` and ``CXX``. Passing the
169-
flags though the compiler is used below, but passing them through ``LDFLAGS`` is
170-
also reported to work.
116+
Some parts of Python (for example, ``_testembed``, ``_freeze_importlib``,
117+
``test_cppext``) may not use the variables set by ``configure``,
118+
and with the above settings they'll be compiled without sanitization.
171119

172-
Building Python
173-
---------------
120+
As a workaround, you can pass the sanitizer options by way of the *compilers*,
121+
``CC`` (for C) and ``CXX`` (for C++). This is used below.
122+
Passing the options through ``LDFLAGS`` is also reported to work.
174123

175-
To begin, export the variables of interest with the desired sanitizers. Its OK
176-
to specify both sanitizers: ::
124+
For ASan, use::
177125

178126
# ASan
179-
export CC="/usr/local/bin/clang -fsanitize=address"
180-
export CXX="/usr/local/bin/clang++ -fsanitize=address -fno-sanitize=vptr"
127+
export CC="clang -fsanitize=address"
128+
export CXX="clang++ -fsanitize=address -fno-sanitize=vptr"
181129

182-
Or: ::
130+
And for UBSan::
183131

184132
# UBSan
185-
export CC="/usr/local/bin/clang -fsanitize=undefined"
186-
export CXX="/usr/local/bin/clang++ -fsanitize=undefined -fno-sanitize=vptr"
187-
188-
The ``-fno-sanitize=vptr`` removes vtable checks that are part of UBSan from C++
189-
projects due to noise. Its not needed with Python, but you will likely need it
190-
for other C++ projects.
191-
192-
After exporting ``CC`` and ``CXX``, ``configure`` as normal:
193-
194-
.. code-block:: console
195-
196-
$ ./configure
197-
checking build system type... x86_64-unknown-linux-gnu
198-
checking host system type... x86_64-unknown-linux-gnu
199-
checking for --enable-universalsdk... no
200-
checking for --with-universal-archs... 32-bit
201-
checking MACHDEP... linux
202-
checking for --without-gcc... no
203-
checking for gcc... /usr/local/bin/clang -fsanitize=undefined
204-
checking whether the C compiler works... yes
205-
...
133+
export CC="clang -fsanitize=undefined"
134+
export CXX="clang++ -fsanitize=undefined -fno-sanitize=vptr"
206135

207-
Next is a standard ``make`` (formatting added for clarity):
136+
It's OK to specify both sanitizers.
208137

209-
.. code-block:: console
138+
After this, run ``./configure``, ``make`` and ``make test`` as usual.
210139

211-
$ make
212-
/usr/local/bin/clang -fsanitize=undefined -c -Wno-unused-result
213-
-DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I.
214-
-IInclude -I./Include -DPy_BUILD_CORE -o Modules/python.o
215-
./Modules/python.c
216-
/usr/local/bin/clang -fsanitize=undefined -c -Wno-unused-result
217-
-DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I.
218-
-IInclude -I./Include -DPy_BUILD_CORE -o Parser/acceler.o
219-
Parser/acceler.c
220-
...
221140

222-
Finally is ``make test`` (formatting added for clarity):
141+
Analyzing the output
142+
====================
143+
144+
Sanitizer failures will make the process fail and output a diagnostic,
145+
for example:
223146

224147
.. code-block:: none
225148
@@ -233,8 +156,12 @@ Finally is ``make test`` (formatting added for clarity):
233156
^
234157
...
235158
236-
If you are using the address sanitizer, its important to pipe the output through
237-
``asan_symbolize.py`` to get a good trace. For example, from Issue 20953 during
159+
If you are using the address sanitizer, an additional tool is needed to
160+
get good traces. Usually, this happens automatically through the
161+
``llvm-symbolizer`` tool. If this tool is not installed on your ``PATH``,
162+
you can set ``ASAN_SYMBOLIZER_PATH`` to the location of the tool,
163+
or pipe test output through ``asan_symbolize.py`` script from the
164+
Clang distribution. For example, from Issue 20953 during
238165
compile (formatting added for clarity):
239166

240167
.. code-block:: none
@@ -302,25 +229,25 @@ compile (formatting added for clarity):
302229
303230
.. note::
304231

305-
``asan_symbolize.py`` is supposed to be installed during ``make install``.
306-
If its not installed, then look in the Clang/LLVM build directory for it and
307-
copy it to ``/usr/local/bin``.
232+
If ``asan_symbolize.py`` is not installed, build Clang from source, then
233+
look in the Clang/LLVM build directory for it and use it directly or copy
234+
it to a directory on ``PATH``.
308235

309-
Blacklisting (ignoring) findings
310-
--------------------------------
236+
Ignoring findings
237+
-----------------
311238

312239
.. highlight:: none
313240

314241
Clang allows you to alter the behavior of sanitizer tools for certain
315-
source-level by providing a special blacklist file at compile-time. The
316-
blacklist is needed because it reports every instance of an issue, even if the
242+
source-level by providing a special ignorelist file at compile-time. The
243+
ignorelist is needed because it reports every instance of an issue, even if the
317244
issue is reported 10's of thousands of time in un-managed library code.
318245

319-
You specify the blacklist with ``-fsanitize-blacklist=XXX``. For example::
246+
You specify the ignorelist with ``-fsanitize-ignorelist=XXX``. For example::
320247

321-
-fsanitize-blacklist=my_blacklist.txt
248+
-fsanitize-ignorelist=my_ignorelist.txt
322249

323-
``my_blacklist.txt`` would then contain entries such as the following. The entry
250+
``my_ignorelist.txt`` would then contain entries such as the following. The entry
324251
will ignore a bug in ``libc++``'s ``ios`` formatting functions::
325252

326253
fun:_Ios_Fmtflags
@@ -342,15 +269,15 @@ findings::
342269
...
343270

344271
One of the function of interest is ``audioop_getsample_impl`` (flagged at line
345-
422), and the blacklist entry would include::
272+
422), and the ignorelist entry would include::
346273

347274
fun:audioop_getsample_imp
348275

349276
Or, you could ignore the entire file with::
350277

351278
src:Modules/audioop.c
352279

353-
Unfortunately, you won't know what to blacklist until you run the sanitizer.
280+
Unfortunately, you won't know what to ignorelist until you run the sanitizer.
354281

355282
The documentation is available at `Sanitizer special case list
356283
<https://clang.llvm.org/docs/SanitizerSpecialCaseList.html>`_.

0 commit comments

Comments
 (0)