7 ms·
Thread Safety Analysis in Clang
- eridius 10y agoThe title currently reads "Thread Safety Analysis Is Clang". I suspect it was meant to read "Thread Safety Analysis In Clang".
- chrisseaton 10y agoI thought it was a joke about race conditions.
- nebabyte 10y agoRAII, and TSAIC
- tlb 10y agoFixed, thanks.
- anonymousDan 10y agoDoes anyone know of a similar tool for Java?
- nurblieh 10y agoGoogle's ErrorProne, https://github.com/google/error-prone/tree/master/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety https://github.com/google/error-prone/tree/master/core/src/m... Bill Pugh's FindBugs, http://findbugs.sourceforge.net/bugDescriptions.html http://findbugs.sourceforge.net/bugDescriptions.html
- pjtr 10y agoNot Java, but C# http://parallel-checker.com/ http://parallel-checker.com/
- jerven 10y agoThe checker framework is also nice for helping with thread safety. https://checkerframework.org/ https://checkerframework.org/ its an extend type system for the Java Language using annotated variables and methods. Its really nice and helped catch quite a few subtle bugs at low cost.
- lemming 10y agoIntellij has similar inspections using annotations.
- _shb 10y agoInfer has a thread-safety checker that identifies races in classes annotated with `@ThreadSafe` (http://fbinfer.com/docs/experimental-checkers.html http://fbinfer.com/docs/experimental-checkers.html).
- bla2 10y agoIn my experience dynamic checkers like https://clang.llvm.org/docs/ThreadSanitizer.html https://clang.llvm.org/docs/ThreadSanitizer.html tend to work better that static checks.
- jsolson 10y agoWe (Google) do both. Having recently done some coding in Swift to implement a little toy Hypervisor, I sorely missed these annotations. By and large the errors they catch are ones I'd be embarrassed to have pointed out in a code review; I don't mind nearly so much when the compiler catches me without my mutex locked.
- duneroadrunner 10y agoWhen data races are the concern, SaferCPlusPlus provides nice data types for safely sharing objects asynchronously[1]. Basically, glorified shared_ptrs that automatically handle all the necessary locking (and blocking). [1] shameless plug: https://github.com/duneroadrunner/SaferCPlusPlus#asynchronously-shared-objects https://github.com/duneroadrunner/SaferCPlusPlus#asynchronou...
- nurettin 10y agoSo is this a Rust killer?
- rurban 10y agoWhy Rust? Rust doesn't have concurrency capabilities. ponylang has. But like Rust it needs mutexes and errors with wrong or missing mutexes. So in this regard it's equal to Rust.
- adrianN 10y ago> Rust doesn't have concurrency capabilities https://doc.rust-lang.org/book/concurrency.html https://doc.rust-lang.org/book/concurrency.html
- rurban 10y agoOh my, those rusters, still downvoting what they have no idea about. So why do have to manually mutex or semaphore your threads? This is not a type system with concurrency capabilities is meant for. At least parrot and pony do away without that nonsense, guaranteed lock-free.
- steveklabnik 10y ago> still downvoting what they have no idea about. What specifically do people not have an idea about? > So why do have to manually mutex or semaphore your threads? You don't _have_ to, but it is an option. Rust, as a low-level language, provides a number of options for dealing with concurrency. Frankly, I wrote that chapter above and in a hurry; it's my least favorite out of the whole book. Rust can prove a lack of data-races at compile time, which is a big deal.
- stymaar 10y ago> So why do have to manually mutex or semaphore your threads? This is not a type system with concurrency capabilities is meant for. You don't have to use mutex ! The Rust type system has two traits to ensure thread-safety : Send and Sync, and you can safely use anything which implement those traits. Mutex is one easy way to have these capabilities, but it's not the only one. You can build your own thread-safe data structure if you want, or even use third-party ones like crossbeam[1]. The compiler will then ensure that you never use non-thread-safe objects accross threads. > At least parrot and pony do away without that nonsense. What is parrot ? I've read about pony but not parrot, and Google isn't helping. [1] : https://github.com/crossbeam-rs/crossbeam/blob/master/README.md https://github.com/crossbeam-rs/crossbeam/blob/master/README...
- hellofunk 10y agoThis is interesting, but I am curious why the effort has gone into this C++ tool when Google's own multi-threading-first language, Go, is based on Tony Hoare's work from decades ago, except that it omits the most interesting feature of CSP, the specialized calculus theorem that can prove the correctness of all your multihreaded logic. It would seem that those interesting ideas were ignored in favor of providing tooling for C++.
- flamedoge 10y agoBecause people can write multi-threaded code in C++.
- stymaar 10y agoFor the record, Go has no static thread safety guaranty. It's easy to write a data-race in Go (and it occurs frequently). Fortunately the go compiler has a tool that help detecting data-races[1]. The only two languages I know that offer data-race-free multi-threading are Pony[2] and Rust. Additionally, Go isn't really a C++ competitor: you'll probably never see Google Chrome using Go instead of C++. Go is a good language for back-end micro-services and cli tools, not for building performance-sensitive native desktop applications. [1]: https://golang.org/doc/articles/race_detector.html https://golang.org/doc/articles/race_detector.html [2]: http://www.ponylang.org/ http://www.ponylang.org/
- SCHiM 10y agoIsn't manually locking and unlocking (as seen in the examples) frowned upon anyway? In any development I do, and with every developer I've ever developed a project internally, the use of std::lock_guard<> (which is a scope lock) was required when working with mutexes. This code looks like that classic "C with arrays" type of C++ code, that is prone to errors that have long been solved. As a rule of thumb, when prototyping new multi threaded code and I have a class that needs to be thread safe, I add a scoped lock in every member function that is not const. Problem solved, your class is now thread safe, although not very performant...
- flamedoge 10y agothere's also std atomic.
- hellofunk 10y agoThat does not solve the issue of locks, just abstracts the mechanisms away (hence why std::atomic has member functions related to checking for locks). The OP is correct, these tools are generally frowned upon in favor of better strategies.
- flamedoge 10y agoIt offers finer grain control than simple mutexes. One can write lock-free data structure easily with it.
- hellofunk 10y agoThe very fact that atomics do lock means that you cannot properly write lock-free data structures with them. "Lock free" typically refers to code that can prevent blocking operations; atomics do not do that, though some people think of atomics as a simple lock-free method, it really isn't. Lock-free is about algorithm design that can prevent locking in the first place, and atomics still lock, even if they hide that from you. If you mentioned atomics as a lock-free tool in an interview, you'd likely be chided. Here is more information: http://preshing.com/20120612/an-introduction-to-lock-free-programming/ http://preshing.com/20120612/an-introduction-to-lock-free-pr... "when you attempt to satisfy the non-blocking condition of lock-free programming, a whole family of techniques fall out: atomic operations"
- zvrba 10y agoI prefer to use language constructs to enforce correct usage where possible. For example, if a set of values have to be synchronized by a mutex, I wrap them in a struct and http://www.boost.org/doc/libs/1_63_0/doc/html/thread/sds.html#thread.sds.synchronized_valuesxxx http://www.boost.org/doc/libs/1_63_0/doc/html/thread/sds.htm... If a method requires that it's called while a mutex is held, I make it explicit by declaring the function as `void f(std::unique_lock<std::mutex>&)` [requiring a reference ensures that you have to have a constructed object before function entry]. Granted, this approach doesn't associate the mutex with its data.
- Matthias247 10y agoLooks interesting, especially as a way to introduce some extra thread safety checking into legacy codebases. Or improve the quality of new ones if C++ is the target (yes, I know that Rust can do similar things without extra tools). If anyone is familiar with it I directly have a question regarding it: An often used pattern besides locking is that data is owned by a particular thread, and only that thread is allowed to mutate the data. E.g. in GUIs only the main thread can mutate it. I guess that can also be expressed with the tool, but examples would be welcome. I guess the owning thread could have the capability, but a challenge could be that the start and end of the owning thread might be encapsulated by a library (e.g. QT or Windows mainloop), and be slightly hidden from the implementation of components. The goal should be that if I do field = value; inside an arbitrary thread I get a warning. And if I do owningThreadWithEventLoop.post([](){ field = value; }); everything is fine.