2012-12-13 07:44:55 +08:00
|
|
|
ThreadSanitizer
|
|
|
|
===============
|
|
|
|
|
|
|
|
Introduction
|
|
|
|
------------
|
|
|
|
|
|
|
|
ThreadSanitizer is a tool that detects data races. It consists of a compiler
|
|
|
|
instrumentation module and a run-time library. Typical slowdown introduced by
|
2012-12-17 15:16:54 +08:00
|
|
|
ThreadSanitizer is about **5x-15x**. Typical memory overhead introduced by
|
|
|
|
ThreadSanitizer is about **5x-10x**.
|
2012-12-13 07:44:55 +08:00
|
|
|
|
|
|
|
How to build
|
|
|
|
------------
|
|
|
|
|
2018-11-05 01:02:00 +08:00
|
|
|
Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>`_.
|
2012-12-13 07:44:55 +08:00
|
|
|
|
|
|
|
Supported Platforms
|
|
|
|
-------------------
|
|
|
|
|
2018-07-25 21:55:06 +08:00
|
|
|
ThreadSanitizer is supported on the following OS:
|
|
|
|
|
2019-03-06 05:10:42 +08:00
|
|
|
* Android aarch64, x86_64
|
|
|
|
* Darwin arm64, x86_64
|
2019-03-06 04:53:34 +08:00
|
|
|
* FreeBSD
|
2019-03-06 05:10:42 +08:00
|
|
|
* Linux aarch64, x86_64, powerpc64, powerpc64le
|
2018-07-25 21:55:06 +08:00
|
|
|
* NetBSD
|
2018-07-25 22:27:14 +08:00
|
|
|
|
2014-01-31 18:49:34 +08:00
|
|
|
Support for other 64-bit architectures is possible, contributions are welcome.
|
|
|
|
Support for 32-bit platforms is problematic and is not planned.
|
2012-12-13 07:44:55 +08:00
|
|
|
|
|
|
|
Usage
|
|
|
|
-----
|
|
|
|
|
2013-04-09 12:35:11 +08:00
|
|
|
Simply compile and link your program with ``-fsanitize=thread``. To get a
|
|
|
|
reasonable performance add ``-O1`` or higher. Use ``-g`` to get file names
|
|
|
|
and line numbers in the warning messages.
|
2012-12-13 07:44:55 +08:00
|
|
|
|
|
|
|
Example:
|
|
|
|
|
2016-06-21 10:19:43 +08:00
|
|
|
.. code-block:: console
|
2012-12-13 07:44:55 +08:00
|
|
|
|
2012-12-17 15:16:54 +08:00
|
|
|
% cat projects/compiler-rt/lib/tsan/lit_tests/tiny_race.c
|
2012-12-13 07:44:55 +08:00
|
|
|
#include <pthread.h>
|
|
|
|
int Global;
|
|
|
|
void *Thread1(void *x) {
|
|
|
|
Global = 42;
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
int main() {
|
|
|
|
pthread_t t;
|
|
|
|
pthread_create(&t, NULL, Thread1, NULL);
|
|
|
|
Global = 43;
|
|
|
|
pthread_join(t, NULL);
|
|
|
|
return Global;
|
|
|
|
}
|
|
|
|
|
2013-04-09 12:35:11 +08:00
|
|
|
$ clang -fsanitize=thread -g -O1 tiny_race.c
|
2012-12-13 07:44:55 +08:00
|
|
|
|
|
|
|
If a bug is detected, the program will print an error message to stderr.
|
|
|
|
Currently, ThreadSanitizer symbolizes its output using an external
|
|
|
|
``addr2line`` process (this will be fixed in future).
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
2012-12-17 15:16:54 +08:00
|
|
|
% ./a.out
|
2012-12-13 07:44:55 +08:00
|
|
|
WARNING: ThreadSanitizer: data race (pid=19219)
|
2012-12-17 15:16:54 +08:00
|
|
|
Write of size 4 at 0x7fcf47b21bc0 by thread T1:
|
2012-12-13 07:44:55 +08:00
|
|
|
#0 Thread1 tiny_race.c:4 (exe+0x00000000a360)
|
2012-12-17 15:16:54 +08:00
|
|
|
|
2012-12-13 07:44:55 +08:00
|
|
|
Previous write of size 4 at 0x7fcf47b21bc0 by main thread:
|
|
|
|
#0 main tiny_race.c:10 (exe+0x00000000a3b4)
|
2012-12-17 15:16:54 +08:00
|
|
|
|
|
|
|
Thread T1 (running) created at:
|
|
|
|
#0 pthread_create tsan_interceptors.cc:705 (exe+0x00000000c790)
|
2012-12-13 07:44:55 +08:00
|
|
|
#1 main tiny_race.c:9 (exe+0x00000000a3a4)
|
|
|
|
|
2012-12-17 16:52:05 +08:00
|
|
|
``__has_feature(thread_sanitizer)``
|
|
|
|
------------------------------------
|
|
|
|
|
|
|
|
In some cases one may need to execute different code depending on whether
|
|
|
|
ThreadSanitizer is enabled.
|
|
|
|
:ref:`\_\_has\_feature <langext-__has_feature-__has_extension>` can be used for
|
|
|
|
this purpose.
|
|
|
|
|
|
|
|
.. code-block:: c
|
|
|
|
|
2013-02-26 14:58:27 +08:00
|
|
|
#if defined(__has_feature)
|
|
|
|
# if __has_feature(thread_sanitizer)
|
2012-12-17 16:52:05 +08:00
|
|
|
// code that builds only under ThreadSanitizer
|
2013-02-26 14:58:27 +08:00
|
|
|
# endif
|
2012-12-17 16:52:05 +08:00
|
|
|
#endif
|
|
|
|
|
2016-10-28 05:38:44 +08:00
|
|
|
``__attribute__((no_sanitize("thread")))``
|
2013-02-26 14:58:27 +08:00
|
|
|
-----------------------------------------------
|
|
|
|
|
2015-10-19 09:24:08 +08:00
|
|
|
Some code should not be instrumented by ThreadSanitizer. One may use the
|
2016-10-28 05:38:44 +08:00
|
|
|
function attribute ``no_sanitize("thread")`` to disable instrumentation of plain
|
2015-10-19 09:24:08 +08:00
|
|
|
(non-atomic) loads/stores in a particular function. ThreadSanitizer still
|
|
|
|
instruments such functions to avoid false positives and provide meaningful stack
|
|
|
|
traces. This attribute may not be supported by other compilers, so we suggest
|
|
|
|
to use it together with ``__has_feature(thread_sanitizer)``.
|
2013-02-26 14:58:27 +08:00
|
|
|
|
2021-08-17 19:19:15 +08:00
|
|
|
``__attribute__((disable_sanitizer_instrumentation))``
|
|
|
|
--------------------------------------------------------
|
|
|
|
|
|
|
|
The ``disable_sanitizer_instrumentation`` attribute can be applied to functions
|
|
|
|
to prevent all kinds of instrumentation. As a result, it may introduce false
|
|
|
|
positives and incorrect stack traces. Therefore, it should be used with care,
|
|
|
|
and only if absolutely required; for example for certain code that cannot
|
|
|
|
tolerate any instrumentation and resulting side-effects. This attribute
|
|
|
|
overrides ``no_sanitize("thread")``.
|
|
|
|
|
2021-05-04 21:50:43 +08:00
|
|
|
Ignorelist
|
|
|
|
----------
|
2013-08-07 16:23:32 +08:00
|
|
|
|
|
|
|
ThreadSanitizer supports ``src`` and ``fun`` entity types in
|
2015-10-19 09:24:08 +08:00
|
|
|
:doc:`SanitizerSpecialCaseList`, that can be used to suppress data race reports
|
|
|
|
in the specified source files or functions. Unlike functions marked with
|
2021-05-04 21:50:43 +08:00
|
|
|
``no_sanitize("thread")`` attribute, ignored functions are not instrumented
|
2016-10-28 05:38:44 +08:00
|
|
|
at all. This can lead to false positives due to missed synchronization via
|
|
|
|
atomic operations and missed stack frames in reports.
|
2013-08-07 16:23:32 +08:00
|
|
|
|
2012-12-13 07:44:55 +08:00
|
|
|
Limitations
|
|
|
|
-----------
|
|
|
|
|
|
|
|
* ThreadSanitizer uses more real memory than a native run. At the default
|
2012-12-17 15:16:54 +08:00
|
|
|
settings the memory overhead is 5x plus 1Mb per each thread. Settings with 3x
|
|
|
|
(less accurate analysis) and 9x (more accurate analysis) overhead are also
|
|
|
|
available.
|
2012-12-13 07:44:55 +08:00
|
|
|
* ThreadSanitizer maps (but does not reserve) a lot of virtual address space.
|
|
|
|
This means that tools like ``ulimit`` may not work as usually expected.
|
2012-12-17 15:16:54 +08:00
|
|
|
* Libc/libstdc++ static linking is not supported.
|
2013-04-09 12:35:11 +08:00
|
|
|
* Non-position-independent executables are not supported. Therefore, the
|
|
|
|
``fsanitize=thread`` flag will cause Clang to act as though the ``-fPIE``
|
|
|
|
flag had been supplied if compiling without ``-fPIC``, and as though the
|
|
|
|
``-pie`` flag had been supplied if linking an executable.
|
2012-12-13 07:44:55 +08:00
|
|
|
|
|
|
|
Current Status
|
|
|
|
--------------
|
|
|
|
|
2012-12-17 15:16:54 +08:00
|
|
|
ThreadSanitizer is in beta stage. It is known to work on large C++ programs
|
|
|
|
using pthreads, but we do not promise anything (yet). C++11 threading is
|
2012-12-17 21:07:35 +08:00
|
|
|
supported with llvm libc++. The test suite is integrated into CMake build
|
2012-12-17 15:16:54 +08:00
|
|
|
and can be run with ``make check-tsan`` command.
|
2012-12-13 07:44:55 +08:00
|
|
|
|
|
|
|
We are actively working on enhancing the tool --- stay tuned. Any help,
|
|
|
|
especially in the form of minimized standalone tests is more than welcome.
|
|
|
|
|
|
|
|
More Information
|
|
|
|
----------------
|
2015-12-04 08:38:13 +08:00
|
|
|
`<https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual>`_
|