[memprof] Upgrade a unit test to MemProf Version 3 (#117063)
[llvm-project.git] / clang / docs / RealtimeSanitizer.rst
blob193f5217c1a1a1d9b1062486bc5f2091b246e7da
1 =================
2 RealtimeSanitizer
3 =================
5 .. contents::
6    :local:
8 Introduction
9 ============
10 RealtimeSanitizer (a.k.a. RTSan) is a real-time safety testing tool for C and C++
11 projects. RTSan can be used to detect real-time violations, i.e. calls to methods
12 that are not safe for use in functions with deterministic run time requirements.
13 RTSan considers any function marked with the ``[[clang::nonblocking]]`` attribute
14 to be a real-time function. At run-time, if RTSan detects a call to ``malloc``, 
15 ``free``, ``pthread_mutex_lock``, or anything else known to have a 
16 non-deterministic execution time in a function marked ``[[clang::nonblocking]]``
17 it raises an error. 
19 RTSan performs its analysis at run-time but shares the ``[[clang::nonblocking]]`` 
20 attribute with the :doc:`FunctionEffectAnalysis` system, which operates at 
21 compile-time to detect potential real-time safety violations. For comprehensive 
22 detection of real-time safety issues, it is recommended to use both systems together.
24 The runtime slowdown introduced by RealtimeSanitizer is negligible.
26 How to build
27 ============
29 Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>`_ and enable the
30 ``compiler-rt`` runtime. An example CMake configuration that will allow for the
31 use/testing of RealtimeSanitizer:
33 .. code-block:: console
35    $ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="compiler-rt" <path to source>/llvm
37 Usage
38 =====
40 There are two requirements:
42 1. The code must be compiled with the ``-fsanitize=realtime`` flag.
43 2. Functions that are subject to real-time constraints must be marked
44    with the ``[[clang::nonblocking]]`` attribute.
46 Typically, these attributes should be added onto the functions that are entry
47 points for threads with real-time priority. These threads are subject to a fixed
48 callback time, such as audio callback threads or rendering loops in video game
49 code.
51 .. code-block:: console
53    % cat example_realtime_violation.cpp
54    #include <vector>
56    void violation() [[clang::nonblocking]]{
57      std::vector<float> v;
58      v.resize(100);
59    }
61    int main() {
62      violation();
63      return 0;
64    }
65    # Compile and link
66    % clang++ -fsanitize=realtime example_realtime_violation.cpp
68 If a real-time safety violation is detected in a ``[[clang::nonblocking]]``
69 context, or any function invoked by that function, the program will exit with a
70 non-zero exit code.
72 .. code-block:: console
74    % clang++ -fsanitize=realtime example_realtime_violation.cpp
75    % ./a.out
76    ==76290==ERROR: RealtimeSanitizer: unsafe-library-call
77    Intercepted call to real-time unsafe function `malloc` in real-time context!
78        #0 0x000102a7b884 in malloc rtsan_interceptors.cpp:426
79        #1 0x00019c326bd0 in operator new(unsigned long)+0x1c (libc++abi.dylib:arm64+0x16bd0)
80        #2 0xa30d0001024f79a8  (<unknown module>)
81        #3 0x0001024f794c in std::__1::__libcpp_allocate[abi:ne200000](unsigned long, unsigned long)+0x44
82        #4 0x0001024f78c4 in std::__1::allocator<float>::allocate[abi:ne200000](unsigned long)+0x44
83        ... snip ...
84        #9 0x0001024f6868 in std::__1::vector<float, std::__1::allocator<float>>::resize(unsigned long)+0x48
85        #10 0x0001024f67b4 in violation()+0x24
86        #11 0x0001024f68f0 in main+0x18 (a.out:arm64+0x1000028f0)
87        #12 0x00019bfe3150  (<unknown module>)
88        #13 0xed5efffffffffffc  (<unknown module>)
91 Blocking functions
92 ------------------
94 Calls to system library functions such as ``malloc`` are automatically caught by
95 RealtimeSanitizer. Real-time programmers may also write their own blocking
96 (real-time unsafe) functions that they wish RealtimeSanitizer to be aware of.
97 RealtimeSanitizer will raise an error at run time if any function attributed
98 with ``[[clang::blocking]]`` is called in a ``[[clang::nonblocking]]`` context.
100 .. code-block:: console
102     $ cat example_blocking_violation.cpp
103     #include <atomic>
104     #include <thread>
106     std::atomic<bool> has_permission{false};
108     int wait_for_permission() [[clang::blocking]] {
109       while (has_permission.load() == false)
110         std::this_thread::yield();
111       return 0;
112     }
114     int real_time_function() [[clang::nonblocking]] {
115       return wait_for_permission();
116     }
118     int main() {
119       return real_time_function();
120     }
122     $ clang++ -fsanitize=realtime example_blocking_violation.cpp && ./a.out
123     ==76131==ERROR: RealtimeSanitizer: blocking-call
124     Call to blocking function `wait_for_permission()` in real-time context!
125         #0 0x0001000c3db0 in wait_for_permission()+0x10 (a.out:arm64+0x100003db0)
126         #1 0x0001000c3e3c in real_time_function()+0x10 (a.out:arm64+0x100003e3c)
127         #2 0x0001000c3e68 in main+0x10 (a.out:arm64+0x100003e68)
128         #3 0x00019bfe3150  (<unknown module>)
129         #4 0x5a27fffffffffffc  (<unknown module>)
132 Run-time flags
133 --------------
135 RealtimeSanitizer supports a number of run-time flags, which can be specified in the ``RTSAN_OPTIONS`` environment variable:
137 .. code-block:: console
139    % RTSAN_OPTIONS=option_1=true:path_option_2="/some/file.txt" ./a.out
140    ...
142 Or at compile-time by providing the symbol ``__rtsan_default_options``:
144 .. code-block:: c
146   __attribute__((__visibility__("default")))
147   extern "C" const char *__rtsan_default_options() {
148     return "symbolize=false:abort_on_error=0:log_to_syslog=0";
149   }
151 You can see all sanitizer options (some of which are unsupported) by using the ``help`` flag:
153 .. code-block:: console
155    % RTSAN_OPTIONS=help=true ./a.out
157 A **partial** list of flags RealtimeSanitizer respects:
159 .. list-table:: Run-time Flags
160    :widths: 20 10 10 70
161    :header-rows: 1
163    * - Flag name
164      - Default value
165      - Type
166      - Short description
167    * - ``halt_on_error``
168      - ``true``
169      - boolean
170      - Exit after first reported error. If false (continue after a detected error), deduplicates error stacks so errors appear only once.
171    * - ``print_stats_on_exit``
172      - ``false``
173      - boolean
174      - Print stats on exit. Includes total and unique errors.
175    * - ``color``
176      - ``"auto"``
177      - string
178      - Colorize reports: (always|never|auto).
179    * - ``fast_unwind_on_fatal``
180      - ``false``
181      - boolean
182      - If available, use the fast frame-pointer-based unwinder on detected errors. If true, ensure the code under test has been compiled with frame pointers with ``-fno-omit-frame-pointers`` or similar.
183    * - ``abort_on_error``
184      - OS dependent
185      - boolean
186      - If true, the tool calls abort() instead of _exit() after printing the error report. On some OSes (OSX, for exmple) this is beneficial because a better stack trace is emitted on crash.
187    * - ``symbolize``
188      - ``true``
189      - boolean
190      - If set, use the symbolizer to turn virtual addresses to file/line locations. If false, can greatly speed up the error reporting.
191    * - ``suppressions``
192      - ""
193      - path
194      - If set to a valid suppressions file, will suppress issue reporting. See details in "Disabling", below.
197 Some issues with flags can be debugged using the ``verbosity=$NUM`` flag:
199 .. code-block:: console
201    % RTSAN_OPTIONS=verbosity=1:misspelled_flag=true ./a.out
202    WARNING: found 1 unrecognized flag(s):
203    misspelled_flag
204    ...
206 Disabling and suppressing
207 -------------------------
209 There are multiple ways to disable error reporting when using RealtimeSanitizer.
211 In general, ``ScopedDisabler`` should be preferred, as it is the most performant.
213 .. list-table:: Suppression methods
214    :widths: 30 15 15 10 70
215    :header-rows: 1
217    * - Method
218      - Specified at?
219      - Scope
220      - Run-time cost
221      - Description
222    * - ``ScopedDisabler``
223      - Compile-time
224      - Stack
225      - Very low
226      - Violations are ignored for the lifetime of the ``ScopedDisabler`` object.
227    * - ``function-name-matches`` suppression
228      - Run-time
229      - Single function
230      - Medium
231      - Suppresses intercepted and ``[[clang::blocking]]`` function calls by name.
232    * - ``call-stack-contains`` suppression
233      - Run-time
234      - Stack
235      - High
236      - Suppresses any stack trace contaning the specified pattern.
237     
239 ``ScopedDisabler``
240 ##################
242 At compile time, RealtimeSanitizer may be disabled using ``__rtsan::ScopedDisabler``. RTSan ignores any errors originating within the ``ScopedDisabler`` instance variable scope.
244 .. code-block:: c++
246     #include <sanitizer/rtsan_interface.h>
248     void process(const std::vector<float>& buffer) [[clang::nonblocking]] {
249         {
250             __rtsan::ScopedDisabler d;
251             ...
252         }
253     }
255 If RealtimeSanitizer is not enabled at compile time (i.e., the code is not compiled with the ``-fsanitize=realtime`` flag), the ``ScopedDisabler`` is compiled as a no-op.
257 In C, you can use the ``__rtsan_disable()`` and ``rtsan_enable()`` functions to manually disable and re-enable RealtimeSanitizer checks.
259 .. code-block:: c++
261     #include <sanitizer/rtsan_interface.h>
263     int process(const float* buffer) [[clang::nonblocking]]
264     {
265         {
266             __rtsan_disable();
268             ...
270             __rtsan_enable();
271         }
272     }
274 Each call to ``__rtsan_disable()`` must be paired with a subsequent call to ``__rtsan_enable()`` to restore normal sanitizer functionality. If a corresponding ``rtsan_enable()`` call is not made, the behavior is undefined.
276 Suppression file
277 ################
279 At run-time, suppressions may be specified using a suppressions file passed in ``RTSAN_OPTIONS``. Run-time suppression may be useful if the source cannot be changed.
281 .. code-block:: console
283    > cat suppressions.supp
284    call-stack-contains:MallocViolation
285    call-stack-contains:std::*vector
286    function-name-matches:free
287    function-name-matches:CustomMarkedBlocking*
288    > RTSAN_OPTIONS="suppressions=suppressions.supp" ./a.out
289    ...
291 Suppressions specified in this file are one of two flavors.
293 ``function-name-matches`` suppresses reporting of any intercepted library call, or function marked ``[[clang::blocking]]`` by name. If, for instance, you know that ``malloc`` is real-time safe on your system, you can disable the check for it via ``function-name-matches:malloc``.
295 ``call-stack-contains`` suppresses reporting of errors in any stack that contains a string matching the pattern specified. For example, suppressing error reporting of any non-real-time-safe behavior in ``std::vector`` may be specified ``call-stack-contains:std::*vector``. You must include symbols in your build for this method to be effective, unsymbolicated stack traces cannot be matched. ``call-stack-contains`` has the highest run-time cost of any method of suppression.
297 Patterns may be exact matches or are "regex-light" patterns, containing special characters such as ``^$*``.
299 The number of potential errors suppressed via this method may be seen on exit when using the ``print_stats_on_exit`` flag.
301 Compile-time sanitizer detection
302 --------------------------------
304 Clang provides the pre-processor macro ``__has_feature`` which may be used to detect if RealtimeSanitizer is enabled at compile-time.
306 .. code-block:: c++
308     #if defined(__has_feature) && __has_feature(realtime_sanitizer)
309     ...
310     #endif