Skip to content

Commit 47e6d18

Browse files
[NFC][rtsan] Update docs to include [[clang::blocking]] (#111249)
Updates the RealtimeSanitizer documentation to: - include information about how to use `[[clang::blocking]]`, and - update the displayed error messages to the latest style
1 parent d3a367d commit 47e6d18

File tree

1 file changed

+60
-20
lines changed

1 file changed

+60
-20
lines changed

clang/docs/RealtimeSanitizer.rst

+60-20
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Introduction
99
============
1010
RealtimeSanitizer (a.k.a. RTSan) is a real-time safety testing tool for C and C++
1111
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 runtime requirements.
12+
that are not safe for use in functions with deterministic run time requirements.
1313
RTSan considers any function marked with the ``[[clang::nonblocking]]`` attribute
1414
to be a real-time function. If RTSan detects a call to ``malloc``, ``free``,
1515
``pthread_mutex_lock``, or anything else that could have a non-deterministic
@@ -58,31 +58,71 @@ code.
5858
return 0;
5959
}
6060
# Compile and link
61-
% clang++ -fsanitize=realtime -g example_realtime_violation.cpp
61+
% clang++ -fsanitize=realtime example_realtime_violation.cpp
6262
6363
If a real-time safety violation is detected in a ``[[clang::nonblocking]]``
6464
context, or any function invoked by that function, the program will exit with a
6565
non-zero exit code.
6666

6767
.. code-block:: console
6868
69-
% clang++ -fsanitize=realtime -g example_realtime_violation.cpp
69+
% clang++ -fsanitize=realtime example_realtime_violation.cpp
7070
% ./a.out
71-
Real-time violation: intercepted call to real-time unsafe function `malloc` in real-time context! Stack trace:
72-
#0 0x000102893034 in __rtsan::PrintStackTrace() rtsan_stack.cpp:45
73-
#1 0x000102892e64 in __rtsan::Context::ExpectNotRealtime(char const*) rtsan_context.cpp:78
74-
#2 0x00010289397c in malloc rtsan_interceptors.cpp:286
75-
#3 0x000195bd7bd0 in operator new(unsigned long)+0x1c (libc++abi.dylib:arm64+0x16bd0)
76-
#4 0x5c7f00010230f07c (<unknown module>)
77-
#5 0x00010230f058 in std::__1::__libcpp_allocate[abi:ue170006](unsigned long, unsigned long) new:324
78-
#6 0x00010230effc in std::__1::allocator<float>::allocate[abi:ue170006](unsigned long) allocator.h:114
79-
... snip ...
80-
#10 0x00010230e4bc in std::__1::vector<float, std::__1::allocator<float>>::__append(unsigned long) vector:1162
81-
#11 0x00010230dcdc in std::__1::vector<float, std::__1::allocator<float>>::resize(unsigned long) vector:1981
82-
#12 0x00010230dc28 in violation() main.cpp:5
83-
#13 0x00010230dd64 in main main.cpp:9
84-
#14 0x0001958960dc (<unknown module>)
85-
#15 0x2f557ffffffffffc (<unknown module>)
71+
==76290==ERROR: RealtimeSanitizer: unsafe-library-call
72+
Intercepted call to real-time unsafe function `malloc` in real-time context!
73+
#0 0x000102a7b884 in malloc rtsan_interceptors.cpp:426
74+
#1 0x00019c326bd0 in operator new(unsigned long)+0x1c (libc++abi.dylib:arm64+0x16bd0)
75+
#2 0xa30d0001024f79a8 (<unknown module>)
76+
#3 0x0001024f794c in std::__1::__libcpp_allocate[abi:ne200000](unsigned long, unsigned long)+0x44
77+
#4 0x0001024f78c4 in std::__1::allocator<float>::allocate[abi:ne200000](unsigned long)+0x44
78+
... snip ...
79+
#9 0x0001024f6868 in std::__1::vector<float, std::__1::allocator<float>>::resize(unsigned long)+0x48
80+
#10 0x0001024f67b4 in violation()+0x24
81+
#11 0x0001024f68f0 in main+0x18 (a.out:arm64+0x1000028f0)
82+
#12 0x00019bfe3150 (<unknown module>)
83+
#13 0xed5efffffffffffc (<unknown module>)
84+
85+
86+
Blocking functions
87+
------------------
88+
89+
Calls to system library functions such as ``malloc`` are automatically caught by
90+
RealtimeSanitizer. Real-time programmers may also write their own blocking
91+
(real-time unsafe) functions that they wish RealtimeSanitizer to be aware of.
92+
RealtimeSanitizer will raise an error at run time if any function attributed
93+
with ``[[clang::blocking]]`` is called in a ``[[clang::nonblocking]]`` context.
94+
95+
.. code-block:: console
96+
97+
$ cat example_blocking_violation.cpp
98+
#include <atomic>
99+
#include <thread>
100+
101+
std::atomic<bool> has_permission{false};
102+
103+
int wait_for_permission() [[clang::blocking]] {
104+
while (has_permission.load() == false)
105+
std::this_thread::yield();
106+
return 0;
107+
}
108+
109+
int real_time_function() [[clang::nonblocking]] {
110+
return wait_for_permission();
111+
}
112+
113+
int main() {
114+
return real_time_function();
115+
}
116+
117+
$ clang++ -fsanitize=realtime example_blocking_violation.cpp && ./a.out
118+
==76131==ERROR: RealtimeSanitizer: blocking-call
119+
Call to blocking function `wait_for_permission()` in real-time context!
120+
#0 0x0001000c3db0 in wait_for_permission()+0x10 (a.out:arm64+0x100003db0)
121+
#1 0x0001000c3e3c in real_time_function()+0x10 (a.out:arm64+0x100003e3c)
122+
#2 0x0001000c3e68 in main+0x10 (a.out:arm64+0x100003e68)
123+
#3 0x00019bfe3150 (<unknown module>)
124+
#4 0x5a27fffffffffffc (<unknown module>)
125+
86126
87127
Run-time flags
88128
--------------
@@ -159,7 +199,7 @@ Disabling
159199

160200
In some circumstances, you may want to suppress error reporting in a specific scope.
161201

162-
In C++, this is achieved via ``__rtsan::ScopedDisabler``. Within the scope where the ``ScopedDisabler`` object is instantiated, all sanitizer error reports are suppressed. This suppression applies to the current scope as well as all invoked functions, including any functions called transitively.
202+
In C++, this is achieved via ``__rtsan::ScopedDisabler``. Within the scope where the ``ScopedDisabler`` object is instantiated, all sanitizer error reports are suppressed. This suppression applies to the current scope as well as all invoked functions, including any functions called transitively.
163203

164204
.. code-block:: c++
165205

@@ -174,7 +214,7 @@ In C++, this is achieved via ``__rtsan::ScopedDisabler``. Within the scope wher
174214

175215
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.
176216

177-
In C, you can use the ``__rtsan_disable()`` and ``rtsan_enable()`` functions to manually disable and re-enable RealtimeSanitizer checks.
217+
In C, you can use the ``__rtsan_disable()`` and ``rtsan_enable()`` functions to manually disable and re-enable RealtimeSanitizer checks.
178218

179219
.. code-block:: c++
180220

0 commit comments

Comments
 (0)