Bug 1869043 add a main thread record of track audio outputs r=padenot
[gecko.git] / tools / sanitizer / docs / tsan.rst
blob77fb6c89d7f87f2f3c9f2d34a534f76d49d4de19
1 Thread Sanitizer
2 ================
4 What is Thread Sanitizer?
5 --------------------------
7 Thread Sanitizer (TSan) is a fast data race detector for C/C++ and Rust
8 programs. It uses a compile-time instrumentation to check all non-race-free
9 memory access at runtime. Unlike other tools, it understands compiler-builtin
10 atomics and synchronization and therefore provides very accurate results
11 with no false positives (except if unsupported synchronization primitives
12 like inline assembly or memory fences are used). More information on how
13 TSan works can be found on `the Thread Sanitizer wiki <https://github.com/google/sanitizers/wiki/ThreadSanitizerAlgorithm>`__.
15 A `meta bug called tsan <https://bugzilla.mozilla.org/show_bug.cgi?id=tsan>`__
16 is maintained to keep track of all the bugs found with TSan.
18 A `blog post on hacks.mozilla.org <https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/>`__ describes this project.
20 Note that unlike other sanitizers, TSan is currently **only supported on Linux**.
22 Downloading artifact builds
23 ---------------------------
25 The easiest way to get Firefox builds with Thread Sanitizer is to download a
26 continuous integration TSan build of mozilla-central (updated at least daily):
28 -  mozilla-central optimized builds:
29    `linux <https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/gecko.v2.mozilla-central.latest.firefox.linux64-tsan-opt/artifacts/public/build/target.tar.bz2>`__
31 The fuzzing team also offers a tool called ``fuzzfetch`` to download this and many
32 other CI builds. It makes downloading and unpacking these builds much easier and
33 can be used not just for fuzzing but for all purposes that require a CI build download.
35 You can install ``fuzzfetch`` from
36 `Github <https://github.com/MozillaSecurity/fuzzfetch>`__ or
37 `via pip <https://pypi.org/project/fuzzfetch/>`__.
39 Afterwards, you can run
43    $ python -m fuzzfetch --tsan -n firefox-tsan
45 to get the build mentioned above unpacked into a directory called ``firefox-tsan``.
47 Creating Try builds
48 -------------------
50 If for some reason you can't use the pre-built binaries mentioned in the
51 previous section (e.g. you need to test a patch), you can either build
52 Firefox yourself (see the following section) or use the :ref:`try server <Pushing to Try>`
53 to create the customized build for you. Pushing to try requires L1 commit
54 access. If you don't have this access yet you can request access (see
55 `Becoming A Mozilla
56 Committer <https://www.mozilla.org/about/governance/policies/commit/>`__
57 and `Mozilla Commit Access
58 Policy <https://www.mozilla.org/about/governance/policies/commit/access-policy/>`__
59 for the requirements).
61 Using ``mach try fuzzy --full`` you can select the ``build-linux64-tsan/opt`` job
62 and related tests (if required).
64 Creating local builds on Linux
65 ------------------------------
67 Build prerequisites
68 ~~~~~~~~~~~~~~~~~~~
70 LLVM/Clang/Rust
71 ^^^^^^^^^^^^^^^
73 The TSan instrumentation is implemented as an LLVM pass and integrated
74 into Clang. We strongly recommend that you use the Clang version supplied
75 as part of the ``mach bootstrap`` process, as we backported several required
76 fixes for TSan on Firefox.
78 Sanitizer support in Rust is genuinely experimental,
79 so our build system only works with a specially patched version of Rust
80 that we build in our CI. To install that specific version (or update to a newer
81 version), run the following in the root of your mozilla-central checkout:
85     ./mach artifact toolchain --from-build linux64-rust-dev
86     rm -rf ~/.mozbuild/rustc-sanitizers
87     mv rustc ~/.mozbuild/rustc-sanitizers
88     rustup toolchain link gecko-sanitizers ~/.mozbuild/rustc-sanitizers
89     rustup override set gecko-sanitizers
91 ``mach artifact`` will always download the ``linux64-rust-dev`` toolchain associated
92 with the current mozilla central commit you have checked out. The toolchain should
93 mostly behave like a normal rust nightly but we don't recommend using it for anything
94 other than building gecko, just in case. Also note that
95 ``~/.mozbuild/rustc-sanitizers`` is just a reasonable default location -- feel
96 free to "install" the toolchain wherever you please.
98 Building Firefox
99 ~~~~~~~~~~~~~~~~
101 Getting the source
102 ^^^^^^^^^^^^^^^^^^
104 Using that or any later revision, all you need to do is to :ref:`get yourself
105 a clone of mozilla-central <Mercurial overview>`.
107 Adjusting the build configuration
108 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
110 Create the build configuration file ``mozconfig`` with the following
111 content in your mozilla-central directory:
115    # Combined .mozconfig file for TSan on Linux+Mac
117    mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-ff-tsan
119    # Enable ASan specific code and build workarounds
120    ac_add_options --enable-thread-sanitizer
122    # This ensures that we also instrument Rust code.
123    export RUSTFLAGS="-Zsanitizer=thread"
125    # rustfmt is currently missing in Rust nightly
126    unset RUSTFMT
128    # Current Rust Nightly has warnings
129    ac_add_options --disable-warnings-as-errors
131    # These are required by TSan
132    ac_add_options --disable-jemalloc
133    ac_add_options --disable-crashreporter
134    ac_add_options --disable-elf-hack
135    ac_add_options --disable-profiling
137    # The Thread Sanitizer is not compatible with sandboxing
138    # (see bug 1182565)
139    ac_add_options --disable-sandbox
141    # Keep symbols to symbolize TSan traces later
142    export MOZ_DEBUG_SYMBOLS=1
143    ac_add_options --enable-debug-symbols
144    ac_add_options --disable-install-strip
146    # Settings for an opt build (preferred)
147    # The -gline-tables-only ensures that all the necessary debug information for ASan
148    # is present, but the rest is stripped so the resulting binaries are smaller.
149    ac_add_options --enable-optimize="-O2 -gline-tables-only"
150    ac_add_options --disable-debug
152    # Settings for a debug+opt build
153    #ac_add_options --enable-optimize
154    #ac_add_options --enable-debug
157 Starting the build process
158 ^^^^^^^^^^^^^^^^^^^^^^^^^^
160 Now you start the build process using the regular ``./mach build``
161 command.
163 Starting Firefox
164 ^^^^^^^^^^^^^^^^
166 After the build has completed, ``./mach run`` with the usual options for
167 running in a debugger (``gdb``, ``lldb``, ``rr``, etc.) work fine, as do
168 the ``--disable-e10s`` and other options.
170 Building only the JavaScript shell
171 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
173 If you want to build only the JavaScript shell instead of doing a full
174 Firefox build, the build script below will probably help you to do so.
175 Execute this script in the ``js/src/`` subdirectory and pass a directory
176 name as the first parameter. The build will then be created in a new
177 subdirectory with that name.
181    #! /bin/sh
183    if [ -z $1 ] ; then
184         echo "usage: $0 <dirname>"
185    elif [ -d $1 ] ; then
186         echo "directory $1 already exists"
187    else
188         autoconf2.13
189         mkdir $1
190         cd $1
191         CC="/path/to/mozbuild/clang" \
192         CXX="/path/to/mozbuild/clang++" \
193         ../configure --disable-debug --enable-optimize="-O2 -gline-tables-only" --enable-thread-sanitizer --disable-jemalloc
194    fi
196 Thread Sanitizer and Symbols
197 ----------------------------
199 Unlike Address Sanitizer, TSan requires in-process symbolizing to work
200 properly in the first place, as any kind of runtime suppressions will
201 otherwise not work.
203 Hence, it is required that you have a copy of ``llvm-symbolizer`` either
204 in your ``PATH`` or pointed to by the ``TSAN_SYMBOLIZER_PATH`` environment
205 variable. This binary is included in your local mozbuild directory, obtained
206 by ``./mach bootstrap``.
209 Runtime Suppressions
210 --------------------
212 TSan has the ability to suppress race reports at runtime. This can be used to
213 silence a race while a fix is developed as well as to permanently silence a
214 (benign) race that cannot be fixed.
216 .. warning::
217        **Warning**: Many races *look* benign but are indeed not. Please read
218        the :ref:`FAQ section <Frequently Asked Questions about TSan>` carefully
219        and think twice before attempting to suppress a race.
221 The runtime Suppression list is directly baked into Firefox at compile-time and
222 located at `mozglue/build/TsanOptions.cpp <https://searchfox.org/mozilla-central/source/mozglue/build/TsanOptions.cpp>`__.
224 .. warning::
225        **Important**: When adding a suppression, always make sure to include
226        the bug number. If the suppression is supposed to be permanent, please
227        add the string ``permanent`` in the same line as the bug number.
229 .. warning::
230        **Important**: When adding a suppression for a *data race*, always make
231        sure to include a stack frame from **each** of the two race stacks.
232        Adding only one suppression for one stack can cause intermittent failures
233        that are later on hard to track. One exception to this rule is when suppressing
234        races on global variables. In that case, a single race entry with the name of
235        the variable is sufficient.
237 Troubleshooting / Known Problems
238 --------------------------------
240 Known Sources of False Positives
241 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
243 TSan has a number of things that can cause false positives, namely:
245   * The use of memory fences (e.g. Rust Arc)
246   * The use of inline assembly for synchronization
247   * Uninstrumented code (e.g. external libraries) using compiler-builtins for synchronization
248   * A lock order inversion involving only a single thread can cause a false positive deadlock
249     report (see also https://github.com/google/sanitizers/issues/488).
251 If none of these four items are involved, you should *never* assume that TSan is reporting
252 a false positive to you without consulting TSan peers. It is very easy to misjudge a race
253 to be a false positive because races can be highly complex and totally non-obvious due to
254 compiler optimizations and the nature of parallel code.
256 Intermittent Broken Stacks
257 ~~~~~~~~~~~~~~~~~~~~~~~~~~
259 If you intermittently see race reports where one stack is missing with a ``failed to restore the stack``
260 message, this can indicate that a suppression is partially covering the race you are seeing.
262 Any race where only one of the two stacks is matched by a runtime suppression will show up
263 if that particular stack fails to symbolize for some reason. The usual solution is to search
264 the suppressions for potential candidates and disable them temporarily to check if your race
265 report now becomes mostly consistent.
267 However, there are other reasons for broken TSan stacks, in particular if they are not intermittent.
268 See also the ``history_size`` parameter in the `TSan flags <https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags>`__.
270 Intermittent Race Reports
271 ~~~~~~~~~~~~~~~~~~~~~~~~~
273 Unfortunately, the TSan algorithm does not guarantee, that a race is detected 100% of the
274 time. Intermittent failures with TSan are (to a certain degree) to be expected and the races
275 involved should be filed and fixed to solve the problem.
277 .. _Frequently Asked Questions about TSan:
279 Frequently Asked Questions about TSan
280 -------------------------------------
282 Why fix data races?
283 ~~~~~~~~~~~~~~~~~~~
285 Data races are undefined behavior and can cause crashes as well as correctness issues.
286 Compiler optimizations can cause racy code to have unpredictable and hard-to-reproduce behavior.
288 At Mozilla, we have already seen several dangerous races, causing random
289 `use-after-free crashes <https://bugzilla.mozilla.org/show_bug.cgi?id=1580288>`__,
290 `intermittent test failures <https://bugzilla.mozilla.org/show_bug.cgi?id=1602009>`__,
291 `hangs <https://bugzilla.mozilla.org/show_bug.cgi?id=1607008>`__,
292 `performance issues <https://bugzilla.mozilla.org/show_bug.cgi?id=1615045>`__ and
293 `intermittent asserts <https://bugzilla.mozilla.org/show_bug.cgi?id=1601940>`__. Such problems do
294 not only decrease the quality of our code and user experience, but they also waste countless hours
295 of developer time.
297 Since it is very hard to judge if a particular race could cause such a situation, we
298 have decided to fix all data races wherever possible, since doing so is often cheaper
299 than analyzing a race.
301 My race is benign, can we ignore it?
302 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
304 While it is possible to add a runtime suppression to ignore the race, we *strongly* encourage
305 you to not do so, for two reasons:
307     1. Each suppressed race decreases the overall performance of the TSan build, as the race
308        has to be symbolized each time when it occurs. Since TSan is already in itself a slow
309        build, we need to keep the amount of suppressed races as low as possible.
311     2. Deciding if a race is truly benign is surprisingly hard. We recommend to read
312        `this blog post <http://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong>`__
313        and `this paper <https://www.usenix.org/legacy/events/hotpar11/tech/final_files/Boehm.pdf>`
314        on the effects of seemingly benign races.
316 Valid reasons to suppress a confirmed benign race include performance problems arising from
317 fixing the race or cases where fixing the race would require an unreasonable amount of work.
319 Note that the use of atomics usually does not have the bad performance impact that developers
320 tend to associate with it. If you assume that e.g. using atomics for synchronization will
321 cause performance regressions, we suggest to perform a benchmark to confirm this. In many
322 cases, the difference is not measurable.
324 How does TSan work exactly?
325 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
327 More information on how TSan works can be found on `the Thread Sanitizer wiki <https://github.com/google/sanitizers/wiki/ThreadSanitizerAlgorithm>`__.