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