Mercurial > hg > CbC > CbC_llvm
comparison clang/docs/ThreadSafetyAnalysis.rst @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 2e18cbf3894f |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 | |
2 ====================== | |
3 Thread Safety Analysis | |
4 ====================== | |
5 | |
6 Introduction | |
7 ============ | |
8 | |
9 Clang Thread Safety Analysis is a C++ language extension which warns about | |
10 potential race conditions in code. The analysis is completely static (i.e. | |
11 compile-time); there is no run-time overhead. The analysis is still | |
12 under active development, but it is mature enough to be deployed in an | |
13 industrial setting. It is being developed by Google, in collaboration with | |
14 CERT/SEI, and is used extensively in Google's internal code base. | |
15 | |
16 Thread safety analysis works very much like a type system for multi-threaded | |
17 programs. In addition to declaring the *type* of data (e.g. ``int``, ``float``, | |
18 etc.), the programmer can (optionally) declare how access to that data is | |
19 controlled in a multi-threaded environment. For example, if ``foo`` is | |
20 *guarded by* the mutex ``mu``, then the analysis will issue a warning whenever | |
21 a piece of code reads or writes to ``foo`` without first locking ``mu``. | |
22 Similarly, if there are particular routines that should only be called by | |
23 the GUI thread, then the analysis will warn if other threads call those | |
24 routines. | |
25 | |
26 Getting Started | |
27 ---------------- | |
28 | |
29 .. code-block:: c++ | |
30 | |
31 #include "mutex.h" | |
32 | |
33 class BankAccount { | |
34 private: | |
35 Mutex mu; | |
36 int balance GUARDED_BY(mu); | |
37 | |
38 void depositImpl(int amount) { | |
39 balance += amount; // WARNING! Cannot write balance without locking mu. | |
40 } | |
41 | |
42 void withdrawImpl(int amount) REQUIRES(mu) { | |
43 balance -= amount; // OK. Caller must have locked mu. | |
44 } | |
45 | |
46 public: | |
47 void withdraw(int amount) { | |
48 mu.Lock(); | |
49 withdrawImpl(amount); // OK. We've locked mu. | |
50 } // WARNING! Failed to unlock mu. | |
51 | |
52 void transferFrom(BankAccount& b, int amount) { | |
53 mu.Lock(); | |
54 b.withdrawImpl(amount); // WARNING! Calling withdrawImpl() requires locking b.mu. | |
55 depositImpl(amount); // OK. depositImpl() has no requirements. | |
56 mu.Unlock(); | |
57 } | |
58 }; | |
59 | |
60 This example demonstrates the basic concepts behind the analysis. The | |
61 ``GUARDED_BY`` attribute declares that a thread must lock ``mu`` before it can | |
62 read or write to ``balance``, thus ensuring that the increment and decrement | |
63 operations are atomic. Similarly, ``REQUIRES`` declares that | |
64 the calling thread must lock ``mu`` before calling ``withdrawImpl``. | |
65 Because the caller is assumed to have locked ``mu``, it is safe to modify | |
66 ``balance`` within the body of the method. | |
67 | |
68 The ``depositImpl()`` method does not have ``REQUIRES``, so the | |
69 analysis issues a warning. Thread safety analysis is not inter-procedural, so | |
70 caller requirements must be explicitly declared. | |
71 There is also a warning in ``transferFrom()``, because although the method | |
72 locks ``this->mu``, it does not lock ``b.mu``. The analysis understands | |
73 that these are two separate mutexes, in two different objects. | |
74 | |
75 Finally, there is a warning in the ``withdraw()`` method, because it fails to | |
76 unlock ``mu``. Every lock must have a corresponding unlock, and the analysis | |
77 will detect both double locks, and double unlocks. A function is allowed to | |
78 acquire a lock without releasing it, (or vice versa), but it must be annotated | |
79 as such (using ``ACQUIRE``/``RELEASE``). | |
80 | |
81 | |
82 Running The Analysis | |
83 -------------------- | |
84 | |
85 To run the analysis, simply compile with the ``-Wthread-safety`` flag, e.g. | |
86 | |
87 .. code-block:: bash | |
88 | |
89 clang -c -Wthread-safety example.cpp | |
90 | |
91 Note that this example assumes the presence of a suitably annotated | |
92 :ref:`mutexheader` that declares which methods perform locking, | |
93 unlocking, and so on. | |
94 | |
95 | |
96 Basic Concepts: Capabilities | |
97 ============================ | |
98 | |
99 Thread safety analysis provides a way of protecting *resources* with | |
100 *capabilities*. A resource is either a data member, or a function/method | |
101 that provides access to some underlying resource. The analysis ensures that | |
102 the calling thread cannot access the *resource* (i.e. call the function, or | |
103 read/write the data) unless it has the *capability* to do so. | |
104 | |
105 Capabilities are associated with named C++ objects which declare specific | |
106 methods to acquire and release the capability. The name of the object serves | |
107 to identify the capability. The most common example is a mutex. For example, | |
108 if ``mu`` is a mutex, then calling ``mu.Lock()`` causes the calling thread | |
109 to acquire the capability to access data that is protected by ``mu``. Similarly, | |
110 calling ``mu.Unlock()`` releases that capability. | |
111 | |
112 A thread may hold a capability either *exclusively* or *shared*. An exclusive | |
113 capability can be held by only one thread at a time, while a shared capability | |
114 can be held by many threads at the same time. This mechanism enforces a | |
115 multiple-reader, single-writer pattern. Write operations to protected data | |
116 require exclusive access, while read operations require only shared access. | |
117 | |
118 At any given moment during program execution, a thread holds a specific set of | |
119 capabilities (e.g. the set of mutexes that it has locked.) These act like keys | |
120 or tokens that allow the thread to access a given resource. Just like physical | |
121 security keys, a thread cannot make copy of a capability, nor can it destroy | |
122 one. A thread can only release a capability to another thread, or acquire one | |
123 from another thread. The annotations are deliberately agnostic about the | |
124 exact mechanism used to acquire and release capabilities; it assumes that the | |
125 underlying implementation (e.g. the Mutex implementation) does the handoff in | |
126 an appropriate manner. | |
127 | |
128 The set of capabilities that are actually held by a given thread at a given | |
129 point in program execution is a run-time concept. The static analysis works | |
130 by calculating an approximation of that set, called the *capability | |
131 environment*. The capability environment is calculated for every program point, | |
132 and describes the set of capabilities that are statically known to be held, or | |
133 not held, at that particular point. This environment is a conservative | |
134 approximation of the full set of capabilities that will actually held by a | |
135 thread at run-time. | |
136 | |
137 | |
138 Reference Guide | |
139 =============== | |
140 | |
141 The thread safety analysis uses attributes to declare threading constraints. | |
142 Attributes must be attached to named declarations, such as classes, methods, | |
143 and data members. Users are *strongly advised* to define macros for the various | |
144 attributes; example definitions can be found in :ref:`mutexheader`, below. | |
145 The following documentation assumes the use of macros. | |
146 | |
147 For historical reasons, prior versions of thread safety used macro names that | |
148 were very lock-centric. These macros have since been renamed to fit a more | |
149 general capability model. The prior names are still in use, and will be | |
150 mentioned under the tag *previously* where appropriate. | |
151 | |
152 | |
153 GUARDED_BY(c) and PT_GUARDED_BY(c) | |
154 ---------------------------------- | |
155 | |
156 ``GUARDED_BY`` is an attribute on data members, which declares that the data | |
157 member is protected by the given capability. Read operations on the data | |
158 require shared access, while write operations require exclusive access. | |
159 | |
160 ``PT_GUARDED_BY`` is similar, but is intended for use on pointers and smart | |
161 pointers. There is no constraint on the data member itself, but the *data that | |
162 it points to* is protected by the given capability. | |
163 | |
164 .. code-block:: c++ | |
165 | |
166 Mutex mu; | |
167 int *p1 GUARDED_BY(mu); | |
168 int *p2 PT_GUARDED_BY(mu); | |
169 unique_ptr<int> p3 PT_GUARDED_BY(mu); | |
170 | |
171 void test() { | |
172 p1 = 0; // Warning! | |
173 | |
174 *p2 = 42; // Warning! | |
175 p2 = new int; // OK. | |
176 | |
177 *p3 = 42; // Warning! | |
178 p3.reset(new int); // OK. | |
179 } | |
180 | |
181 | |
182 REQUIRES(...), REQUIRES_SHARED(...) | |
183 ----------------------------------- | |
184 | |
185 *Previously*: ``EXCLUSIVE_LOCKS_REQUIRED``, ``SHARED_LOCKS_REQUIRED`` | |
186 | |
187 ``REQUIRES`` is an attribute on functions or methods, which | |
188 declares that the calling thread must have exclusive access to the given | |
189 capabilities. More than one capability may be specified. The capabilities | |
190 must be held on entry to the function, *and must still be held on exit*. | |
191 | |
192 ``REQUIRES_SHARED`` is similar, but requires only shared access. | |
193 | |
194 .. code-block:: c++ | |
195 | |
196 Mutex mu1, mu2; | |
197 int a GUARDED_BY(mu1); | |
198 int b GUARDED_BY(mu2); | |
199 | |
200 void foo() REQUIRES(mu1, mu2) { | |
201 a = 0; | |
202 b = 0; | |
203 } | |
204 | |
205 void test() { | |
206 mu1.Lock(); | |
207 foo(); // Warning! Requires mu2. | |
208 mu1.Unlock(); | |
209 } | |
210 | |
211 | |
212 ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...) | |
213 -------------------------------------------------------------------- | |
214 | |
215 *Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``, | |
216 ``UNLOCK_FUNCTION`` | |
217 | |
218 ``ACQUIRE`` is an attribute on functions or methods, which | |
219 declares that the function acquires a capability, but does not release it. The | |
220 caller must not hold the given capability on entry, and it will hold the | |
221 capability on exit. ``ACQUIRE_SHARED`` is similar. | |
222 | |
223 ``RELEASE`` and ``RELEASE_SHARED`` declare that the function releases the given | |
224 capability. The caller must hold the capability on entry, and will no longer | |
225 hold it on exit. It does not matter whether the given capability is shared or | |
226 exclusive. | |
227 | |
228 .. code-block:: c++ | |
229 | |
230 Mutex mu; | |
231 MyClass myObject GUARDED_BY(mu); | |
232 | |
233 void lockAndInit() ACQUIRE(mu) { | |
234 mu.Lock(); | |
235 myObject.init(); | |
236 } | |
237 | |
238 void cleanupAndUnlock() RELEASE(mu) { | |
239 myObject.cleanup(); | |
240 } // Warning! Need to unlock mu. | |
241 | |
242 void test() { | |
243 lockAndInit(); | |
244 myObject.doSomething(); | |
245 cleanupAndUnlock(); | |
246 myObject.doSomething(); // Warning, mu is not locked. | |
247 } | |
248 | |
249 If no argument is passed to ``ACQUIRE`` or ``RELEASE``, then the argument is | |
250 assumed to be ``this``, and the analysis will not check the body of the | |
251 function. This pattern is intended for use by classes which hide locking | |
252 details behind an abstract interface. For example: | |
253 | |
254 .. code-block:: c++ | |
255 | |
256 template <class T> | |
257 class CAPABILITY("mutex") Container { | |
258 private: | |
259 Mutex mu; | |
260 T* data; | |
261 | |
262 public: | |
263 // Hide mu from public interface. | |
264 void Lock() ACQUIRE() { mu.Lock(); } | |
265 void Unlock() RELEASE() { mu.Unlock(); } | |
266 | |
267 T& getElem(int i) { return data[i]; } | |
268 }; | |
269 | |
270 void test() { | |
271 Container<int> c; | |
272 c.Lock(); | |
273 int i = c.getElem(0); | |
274 c.Unlock(); | |
275 } | |
276 | |
277 | |
278 EXCLUDES(...) | |
279 ------------- | |
280 | |
281 *Previously*: ``LOCKS_EXCLUDED`` | |
282 | |
283 ``EXCLUDES`` is an attribute on functions or methods, which declares that | |
284 the caller must *not* hold the given capabilities. This annotation is | |
285 used to prevent deadlock. Many mutex implementations are not re-entrant, so | |
286 deadlock can occur if the function acquires the mutex a second time. | |
287 | |
288 .. code-block:: c++ | |
289 | |
290 Mutex mu; | |
291 int a GUARDED_BY(mu); | |
292 | |
293 void clear() EXCLUDES(mu) { | |
294 mu.Lock(); | |
295 a = 0; | |
296 mu.Unlock(); | |
297 } | |
298 | |
299 void reset() { | |
300 mu.Lock(); | |
301 clear(); // Warning! Caller cannot hold 'mu'. | |
302 mu.Unlock(); | |
303 } | |
304 | |
305 Unlike ``REQUIRES``, ``EXCLUDES`` is optional. The analysis will not issue a | |
306 warning if the attribute is missing, which can lead to false negatives in some | |
307 cases. This issue is discussed further in :ref:`negative`. | |
308 | |
309 | |
310 NO_THREAD_SAFETY_ANALYSIS | |
311 ------------------------- | |
312 | |
313 ``NO_THREAD_SAFETY_ANALYSIS`` is an attribute on functions or methods, which | |
314 turns off thread safety checking for that method. It provides an escape hatch | |
315 for functions which are either (1) deliberately thread-unsafe, or (2) are | |
316 thread-safe, but too complicated for the analysis to understand. Reasons for | |
317 (2) will be described in the :ref:`limitations`, below. | |
318 | |
319 .. code-block:: c++ | |
320 | |
321 class Counter { | |
322 Mutex mu; | |
323 int a GUARDED_BY(mu); | |
324 | |
325 void unsafeIncrement() NO_THREAD_SAFETY_ANALYSIS { a++; } | |
326 }; | |
327 | |
328 Unlike the other attributes, NO_THREAD_SAFETY_ANALYSIS is not part of the | |
329 interface of a function, and should thus be placed on the function definition | |
330 (in the ``.cc`` or ``.cpp`` file) rather than on the function declaration | |
331 (in the header). | |
332 | |
333 | |
334 RETURN_CAPABILITY(c) | |
335 -------------------- | |
336 | |
337 *Previously*: ``LOCK_RETURNED`` | |
338 | |
339 ``RETURN_CAPABILITY`` is an attribute on functions or methods, which declares | |
340 that the function returns a reference to the given capability. It is used to | |
341 annotate getter methods that return mutexes. | |
342 | |
343 .. code-block:: c++ | |
344 | |
345 class MyClass { | |
346 private: | |
347 Mutex mu; | |
348 int a GUARDED_BY(mu); | |
349 | |
350 public: | |
351 Mutex* getMu() RETURN_CAPABILITY(mu) { return μ } | |
352 | |
353 // analysis knows that getMu() == mu | |
354 void clear() REQUIRES(getMu()) { a = 0; } | |
355 }; | |
356 | |
357 | |
358 ACQUIRED_BEFORE(...), ACQUIRED_AFTER(...) | |
359 ----------------------------------------- | |
360 | |
361 ``ACQUIRED_BEFORE`` and ``ACQUIRED_AFTER`` are attributes on member | |
362 declarations, specifically declarations of mutexes or other capabilities. | |
363 These declarations enforce a particular order in which the mutexes must be | |
364 acquired, in order to prevent deadlock. | |
365 | |
366 .. code-block:: c++ | |
367 | |
368 Mutex m1; | |
369 Mutex m2 ACQUIRED_AFTER(m1); | |
370 | |
371 // Alternative declaration | |
372 // Mutex m2; | |
373 // Mutex m1 ACQUIRED_BEFORE(m2); | |
374 | |
375 void foo() { | |
376 m2.Lock(); | |
377 m1.Lock(); // Warning! m2 must be acquired after m1. | |
378 m1.Unlock(); | |
379 m2.Unlock(); | |
380 } | |
381 | |
382 | |
383 CAPABILITY(<string>) | |
384 -------------------- | |
385 | |
386 *Previously*: ``LOCKABLE`` | |
387 | |
388 ``CAPABILITY`` is an attribute on classes, which specifies that objects of the | |
389 class can be used as a capability. The string argument specifies the kind of | |
390 capability in error messages, e.g. ``"mutex"``. See the ``Container`` example | |
391 given above, or the ``Mutex`` class in :ref:`mutexheader`. | |
392 | |
393 | |
394 SCOPED_CAPABILITY | |
395 ----------------- | |
396 | |
397 *Previously*: ``SCOPED_LOCKABLE`` | |
398 | |
399 ``SCOPED_CAPABILITY`` is an attribute on classes that implement RAII-style | |
400 locking, in which a capability is acquired in the constructor, and released in | |
401 the destructor. Such classes require special handling because the constructor | |
402 and destructor refer to the capability via different names; see the | |
403 ``MutexLocker`` class in :ref:`mutexheader`, below. | |
404 | |
405 | |
406 TRY_ACQUIRE(<bool>, ...), TRY_ACQUIRE_SHARED(<bool>, ...) | |
407 --------------------------------------------------------- | |
408 | |
409 *Previously:* ``EXCLUSIVE_TRYLOCK_FUNCTION``, ``SHARED_TRYLOCK_FUNCTION`` | |
410 | |
411 These are attributes on a function or method that tries to acquire the given | |
412 capability, and returns a boolean value indicating success or failure. | |
413 The first argument must be ``true`` or ``false``, to specify which return value | |
414 indicates success, and the remaining arguments are interpreted in the same way | |
415 as ``ACQUIRE``. See :ref:`mutexheader`, below, for example uses. | |
416 | |
417 | |
418 ASSERT_CAPABILITY(...) and ASSERT_SHARED_CAPABILITY(...) | |
419 -------------------------------------------------------- | |
420 | |
421 *Previously:* ``ASSERT_EXCLUSIVE_LOCK``, ``ASSERT_SHARED_LOCK`` | |
422 | |
423 These are attributes on a function or method that does a run-time test to see | |
424 whether the calling thread holds the given capability. The function is assumed | |
425 to fail (no return) if the capability is not held. See :ref:`mutexheader`, | |
426 below, for example uses. | |
427 | |
428 | |
429 GUARDED_VAR and PT_GUARDED_VAR | |
430 ------------------------------ | |
431 | |
432 Use of these attributes has been deprecated. | |
433 | |
434 | |
435 Warning flags | |
436 ------------- | |
437 | |
438 * ``-Wthread-safety``: Umbrella flag which turns on the following three: | |
439 | |
440 + ``-Wthread-safety-attributes``: Sanity checks on attribute syntax. | |
441 + ``-Wthread-safety-analysis``: The core analysis. | |
442 + ``-Wthread-safety-precise``: Requires that mutex expressions match precisely. | |
443 This warning can be disabled for code which has a lot of aliases. | |
444 + ``-Wthread-safety-reference``: Checks when guarded members are passed by reference. | |
445 | |
446 | |
447 :ref:`negative` are an experimental feature, which are enabled with: | |
448 | |
449 * ``-Wthread-safety-negative``: Negative capabilities. Off by default. | |
450 | |
451 When new features and checks are added to the analysis, they can often introduce | |
452 additional warnings. Those warnings are initially released as *beta* warnings | |
453 for a period of time, after which they are migrated into the standard analysis. | |
454 | |
455 * ``-Wthread-safety-beta``: New features. Off by default. | |
456 | |
457 | |
458 .. _negative: | |
459 | |
460 Negative Capabilities | |
461 ===================== | |
462 | |
463 Thread Safety Analysis is designed to prevent both race conditions and | |
464 deadlock. The GUARDED_BY and REQUIRES attributes prevent race conditions, by | |
465 ensuring that a capability is held before reading or writing to guarded data, | |
466 and the EXCLUDES attribute prevents deadlock, by making sure that a mutex is | |
467 *not* held. | |
468 | |
469 However, EXCLUDES is an optional attribute, and does not provide the same | |
470 safety guarantee as REQUIRES. In particular: | |
471 | |
472 * A function which acquires a capability does not have to exclude it. | |
473 * A function which calls a function that excludes a capability does not | |
474 have transitively exclude that capability. | |
475 | |
476 As a result, EXCLUDES can easily produce false negatives: | |
477 | |
478 .. code-block:: c++ | |
479 | |
480 class Foo { | |
481 Mutex mu; | |
482 | |
483 void foo() { | |
484 mu.Lock(); | |
485 bar(); // No warning. | |
486 baz(); // No warning. | |
487 mu.Unlock(); | |
488 } | |
489 | |
490 void bar() { // No warning. (Should have EXCLUDES(mu)). | |
491 mu.Lock(); | |
492 // ... | |
493 mu.Unlock(); | |
494 } | |
495 | |
496 void baz() { | |
497 bif(); // No warning. (Should have EXCLUDES(mu)). | |
498 } | |
499 | |
500 void bif() EXCLUDES(mu); | |
501 }; | |
502 | |
503 | |
504 Negative requirements are an alternative EXCLUDES that provide | |
505 a stronger safety guarantee. A negative requirement uses the REQUIRES | |
506 attribute, in conjunction with the ``!`` operator, to indicate that a capability | |
507 should *not* be held. | |
508 | |
509 For example, using ``REQUIRES(!mu)`` instead of ``EXCLUDES(mu)`` will produce | |
510 the appropriate warnings: | |
511 | |
512 .. code-block:: c++ | |
513 | |
514 class FooNeg { | |
515 Mutex mu; | |
516 | |
517 void foo() REQUIRES(!mu) { // foo() now requires !mu. | |
518 mu.Lock(); | |
519 bar(); | |
520 baz(); | |
521 mu.Unlock(); | |
522 } | |
523 | |
524 void bar() { | |
525 mu.Lock(); // WARNING! Missing REQUIRES(!mu). | |
526 // ... | |
527 mu.Unlock(); | |
528 } | |
529 | |
530 void baz() { | |
531 bif(); // WARNING! Missing REQUIRES(!mu). | |
532 } | |
533 | |
534 void bif() REQUIRES(!mu); | |
535 }; | |
536 | |
537 | |
538 Negative requirements are an experimental feature which is off by default, | |
539 because it will produce many warnings in existing code. It can be enabled | |
540 by passing ``-Wthread-safety-negative``. | |
541 | |
542 | |
543 .. _faq: | |
544 | |
545 Frequently Asked Questions | |
546 ========================== | |
547 | |
548 (Q) Should I put attributes in the header file, or in the .cc/.cpp/.cxx file? | |
549 | |
550 (A) Attributes are part of the formal interface of a function, and should | |
551 always go in the header, where they are visible to anything that includes | |
552 the header. Attributes in the .cpp file are not visible outside of the | |
553 immediate translation unit, which leads to false negatives and false positives. | |
554 | |
555 | |
556 (Q) "*Mutex is not locked on every path through here?*" What does that mean? | |
557 | |
558 (A) See :ref:`conditional_locks`, below. | |
559 | |
560 | |
561 .. _limitations: | |
562 | |
563 Known Limitations | |
564 ================= | |
565 | |
566 Lexical scope | |
567 ------------- | |
568 | |
569 Thread safety attributes contain ordinary C++ expressions, and thus follow | |
570 ordinary C++ scoping rules. In particular, this means that mutexes and other | |
571 capabilities must be declared before they can be used in an attribute. | |
572 Use-before-declaration is okay within a single class, because attributes are | |
573 parsed at the same time as method bodies. (C++ delays parsing of method bodies | |
574 until the end of the class.) However, use-before-declaration is not allowed | |
575 between classes, as illustrated below. | |
576 | |
577 .. code-block:: c++ | |
578 | |
579 class Foo; | |
580 | |
581 class Bar { | |
582 void bar(Foo* f) REQUIRES(f->mu); // Error: mu undeclared. | |
583 }; | |
584 | |
585 class Foo { | |
586 Mutex mu; | |
587 }; | |
588 | |
589 | |
590 Private Mutexes | |
591 --------------- | |
592 | |
593 Good software engineering practice dictates that mutexes should be private | |
594 members, because the locking mechanism used by a thread-safe class is part of | |
595 its internal implementation. However, private mutexes can sometimes leak into | |
596 the public interface of a class. | |
597 Thread safety attributes follow normal C++ access restrictions, so if ``mu`` | |
598 is a private member of ``c``, then it is an error to write ``c.mu`` in an | |
599 attribute. | |
600 | |
601 One workaround is to (ab)use the ``RETURN_CAPABILITY`` attribute to provide a | |
602 public *name* for a private mutex, without actually exposing the underlying | |
603 mutex. For example: | |
604 | |
605 .. code-block:: c++ | |
606 | |
607 class MyClass { | |
608 private: | |
609 Mutex mu; | |
610 | |
611 public: | |
612 // For thread safety analysis only. Does not actually return mu. | |
613 Mutex* getMu() RETURN_CAPABILITY(mu) { return 0; } | |
614 | |
615 void doSomething() REQUIRES(mu); | |
616 }; | |
617 | |
618 void doSomethingTwice(MyClass& c) REQUIRES(c.getMu()) { | |
619 // The analysis thinks that c.getMu() == c.mu | |
620 c.doSomething(); | |
621 c.doSomething(); | |
622 } | |
623 | |
624 In the above example, ``doSomethingTwice()`` is an external routine that | |
625 requires ``c.mu`` to be locked, which cannot be declared directly because ``mu`` | |
626 is private. This pattern is discouraged because it | |
627 violates encapsulation, but it is sometimes necessary, especially when adding | |
628 annotations to an existing code base. The workaround is to define ``getMu()`` | |
629 as a fake getter method, which is provided only for the benefit of thread | |
630 safety analysis. | |
631 | |
632 | |
633 .. _conditional_locks: | |
634 | |
635 No conditionally held locks. | |
636 ---------------------------- | |
637 | |
638 The analysis must be able to determine whether a lock is held, or not held, at | |
639 every program point. Thus, sections of code where a lock *might be held* will | |
640 generate spurious warnings (false positives). For example: | |
641 | |
642 .. code-block:: c++ | |
643 | |
644 void foo() { | |
645 bool b = needsToLock(); | |
646 if (b) mu.Lock(); | |
647 ... // Warning! Mutex 'mu' is not held on every path through here. | |
648 if (b) mu.Unlock(); | |
649 } | |
650 | |
651 | |
652 No checking inside constructors and destructors. | |
653 ------------------------------------------------ | |
654 | |
655 The analysis currently does not do any checking inside constructors or | |
656 destructors. In other words, every constructor and destructor is treated as | |
657 if it was annotated with ``NO_THREAD_SAFETY_ANALYSIS``. | |
658 The reason for this is that during initialization, only one thread typically | |
659 has access to the object which is being initialized, and it is thus safe (and | |
660 common practice) to initialize guarded members without acquiring any locks. | |
661 The same is true of destructors. | |
662 | |
663 Ideally, the analysis would allow initialization of guarded members inside the | |
664 object being initialized or destroyed, while still enforcing the usual access | |
665 restrictions on everything else. However, this is difficult to enforce in | |
666 practice, because in complex pointer-based data structures, it is hard to | |
667 determine what data is owned by the enclosing object. | |
668 | |
669 No inlining. | |
670 ------------ | |
671 | |
672 Thread safety analysis is strictly intra-procedural, just like ordinary type | |
673 checking. It relies only on the declared attributes of a function, and will | |
674 not attempt to inline any method calls. As a result, code such as the | |
675 following will not work: | |
676 | |
677 .. code-block:: c++ | |
678 | |
679 template<class T> | |
680 class AutoCleanup { | |
681 T* object; | |
682 void (T::*mp)(); | |
683 | |
684 public: | |
685 AutoCleanup(T* obj, void (T::*imp)()) : object(obj), mp(imp) { } | |
686 ~AutoCleanup() { (object->*mp)(); } | |
687 }; | |
688 | |
689 Mutex mu; | |
690 void foo() { | |
691 mu.Lock(); | |
692 AutoCleanup<Mutex>(&mu, &Mutex::Unlock); | |
693 // ... | |
694 } // Warning, mu is not unlocked. | |
695 | |
696 In this case, the destructor of ``Autocleanup`` calls ``mu.Unlock()``, so | |
697 the warning is bogus. However, | |
698 thread safety analysis cannot see the unlock, because it does not attempt to | |
699 inline the destructor. Moreover, there is no way to annotate the destructor, | |
700 because the destructor is calling a function that is not statically known. | |
701 This pattern is simply not supported. | |
702 | |
703 | |
704 No alias analysis. | |
705 ------------------ | |
706 | |
707 The analysis currently does not track pointer aliases. Thus, there can be | |
708 false positives if two pointers both point to the same mutex. | |
709 | |
710 | |
711 .. code-block:: c++ | |
712 | |
713 class MutexUnlocker { | |
714 Mutex* mu; | |
715 | |
716 public: | |
717 MutexUnlocker(Mutex* m) RELEASE(m) : mu(m) { mu->Unlock(); } | |
718 ~MutexUnlocker() ACQUIRE(mu) { mu->Lock(); } | |
719 }; | |
720 | |
721 Mutex mutex; | |
722 void test() REQUIRES(mutex) { | |
723 { | |
724 MutexUnlocker munl(&mutex); // unlocks mutex | |
725 doSomeIO(); | |
726 } // Warning: locks munl.mu | |
727 } | |
728 | |
729 The MutexUnlocker class is intended to be the dual of the MutexLocker class, | |
730 defined in :ref:`mutexheader`. However, it doesn't work because the analysis | |
731 doesn't know that munl.mu == mutex. The SCOPED_CAPABILITY attribute handles | |
732 aliasing for MutexLocker, but does so only for that particular pattern. | |
733 | |
734 | |
735 ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently unimplemented. | |
736 ------------------------------------------------------------------------- | |
737 | |
738 To be fixed in a future update. | |
739 | |
740 | |
741 .. _mutexheader: | |
742 | |
743 mutex.h | |
744 ======= | |
745 | |
746 Thread safety analysis can be used with any threading library, but it does | |
747 require that the threading API be wrapped in classes and methods which have the | |
748 appropriate annotations. The following code provides ``mutex.h`` as an example; | |
749 these methods should be filled in to call the appropriate underlying | |
750 implementation. | |
751 | |
752 | |
753 .. code-block:: c++ | |
754 | |
755 | |
756 #ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H | |
757 #define THREAD_SAFETY_ANALYSIS_MUTEX_H | |
758 | |
759 // Enable thread safety attributes only with clang. | |
760 // The attributes can be safely erased when compiling with other compilers. | |
761 #if defined(__clang__) && (!defined(SWIG)) | |
762 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) | |
763 #else | |
764 #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op | |
765 #endif | |
766 | |
767 #define CAPABILITY(x) \ | |
768 THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) | |
769 | |
770 #define SCOPED_CAPABILITY \ | |
771 THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) | |
772 | |
773 #define GUARDED_BY(x) \ | |
774 THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) | |
775 | |
776 #define PT_GUARDED_BY(x) \ | |
777 THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) | |
778 | |
779 #define ACQUIRED_BEFORE(...) \ | |
780 THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) | |
781 | |
782 #define ACQUIRED_AFTER(...) \ | |
783 THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) | |
784 | |
785 #define REQUIRES(...) \ | |
786 THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) | |
787 | |
788 #define REQUIRES_SHARED(...) \ | |
789 THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) | |
790 | |
791 #define ACQUIRE(...) \ | |
792 THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) | |
793 | |
794 #define ACQUIRE_SHARED(...) \ | |
795 THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) | |
796 | |
797 #define RELEASE(...) \ | |
798 THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) | |
799 | |
800 #define RELEASE_SHARED(...) \ | |
801 THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) | |
802 | |
803 #define TRY_ACQUIRE(...) \ | |
804 THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) | |
805 | |
806 #define TRY_ACQUIRE_SHARED(...) \ | |
807 THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) | |
808 | |
809 #define EXCLUDES(...) \ | |
810 THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) | |
811 | |
812 #define ASSERT_CAPABILITY(x) \ | |
813 THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) | |
814 | |
815 #define ASSERT_SHARED_CAPABILITY(x) \ | |
816 THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) | |
817 | |
818 #define RETURN_CAPABILITY(x) \ | |
819 THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) | |
820 | |
821 #define NO_THREAD_SAFETY_ANALYSIS \ | |
822 THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) | |
823 | |
824 | |
825 // Defines an annotated interface for mutexes. | |
826 // These methods can be implemented to use any internal mutex implementation. | |
827 class CAPABILITY("mutex") Mutex { | |
828 public: | |
829 // Acquire/lock this mutex exclusively. Only one thread can have exclusive | |
830 // access at any one time. Write operations to guarded data require an | |
831 // exclusive lock. | |
832 void Lock() ACQUIRE(); | |
833 | |
834 // Acquire/lock this mutex for read operations, which require only a shared | |
835 // lock. This assumes a multiple-reader, single writer semantics. Multiple | |
836 // threads may acquire the mutex simultaneously as readers, but a writer | |
837 // must wait for all of them to release the mutex before it can acquire it | |
838 // exclusively. | |
839 void ReaderLock() ACQUIRE_SHARED(); | |
840 | |
841 // Release/unlock an exclusive mutex. | |
842 void Unlock() RELEASE(); | |
843 | |
844 // Release/unlock a shared mutex. | |
845 void ReaderUnlock() RELEASE_SHARED(); | |
846 | |
847 // Try to acquire the mutex. Returns true on success, and false on failure. | |
848 bool TryLock() TRY_ACQUIRE(true); | |
849 | |
850 // Try to acquire the mutex for read operations. | |
851 bool ReaderTryLock() TRY_ACQUIRE_SHARED(true); | |
852 | |
853 // Assert that this mutex is currently held by the calling thread. | |
854 void AssertHeld() ASSERT_CAPABILITY(this); | |
855 | |
856 // Assert that is mutex is currently held for read operations. | |
857 void AssertReaderHeld() ASSERT_SHARED_CAPABILITY(this); | |
858 | |
859 // For negative capabilities. | |
860 const Mutex& operator!() const { return *this; } | |
861 }; | |
862 | |
863 | |
864 // MutexLocker is an RAII class that acquires a mutex in its constructor, and | |
865 // releases it in its destructor. | |
866 class SCOPED_CAPABILITY MutexLocker { | |
867 private: | |
868 Mutex* mut; | |
869 | |
870 public: | |
871 MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu) { | |
872 mu->Lock(); | |
873 } | |
874 ~MutexLocker() RELEASE() { | |
875 mut->Unlock(); | |
876 } | |
877 }; | |
878 | |
879 | |
880 #ifdef USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES | |
881 // The original version of thread safety analysis the following attribute | |
882 // definitions. These use a lock-based terminology. They are still in use | |
883 // by existing thread safety code, and will continue to be supported. | |
884 | |
885 // Deprecated. | |
886 #define PT_GUARDED_VAR \ | |
887 THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_var) | |
888 | |
889 // Deprecated. | |
890 #define GUARDED_VAR \ | |
891 THREAD_ANNOTATION_ATTRIBUTE__(guarded_var) | |
892 | |
893 // Replaced by REQUIRES | |
894 #define EXCLUSIVE_LOCKS_REQUIRED(...) \ | |
895 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__)) | |
896 | |
897 // Replaced by REQUIRES_SHARED | |
898 #define SHARED_LOCKS_REQUIRED(...) \ | |
899 THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__)) | |
900 | |
901 // Replaced by CAPABILITY | |
902 #define LOCKABLE \ | |
903 THREAD_ANNOTATION_ATTRIBUTE__(lockable) | |
904 | |
905 // Replaced by SCOPED_CAPABILITY | |
906 #define SCOPED_LOCKABLE \ | |
907 THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) | |
908 | |
909 // Replaced by ACQUIRE | |
910 #define EXCLUSIVE_LOCK_FUNCTION(...) \ | |
911 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__)) | |
912 | |
913 // Replaced by ACQUIRE_SHARED | |
914 #define SHARED_LOCK_FUNCTION(...) \ | |
915 THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__)) | |
916 | |
917 // Replaced by RELEASE and RELEASE_SHARED | |
918 #define UNLOCK_FUNCTION(...) \ | |
919 THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__)) | |
920 | |
921 // Replaced by TRY_ACQUIRE | |
922 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \ | |
923 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__)) | |
924 | |
925 // Replaced by TRY_ACQUIRE_SHARED | |
926 #define SHARED_TRYLOCK_FUNCTION(...) \ | |
927 THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__)) | |
928 | |
929 // Replaced by ASSERT_CAPABILITY | |
930 #define ASSERT_EXCLUSIVE_LOCK(...) \ | |
931 THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__)) | |
932 | |
933 // Replaced by ASSERT_SHARED_CAPABILITY | |
934 #define ASSERT_SHARED_LOCK(...) \ | |
935 THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__)) | |
936 | |
937 // Replaced by EXCLUDE_CAPABILITY. | |
938 #define LOCKS_EXCLUDED(...) \ | |
939 THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) | |
940 | |
941 // Replaced by RETURN_CAPABILITY | |
942 #define LOCK_RETURNED(x) \ | |
943 THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) | |
944 | |
945 #endif // USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES | |
946 | |
947 #endif // THREAD_SAFETY_ANALYSIS_MUTEX_H | |
948 |