This is an extension to an already existing alpha-checker which finds the calls to blocking functions inside a critical section. (See that original diff: https://reviews.llvm.org/D21506). In this patch C11 and Pthread locking/unlocking support has been added and also two new parameters have been implemented to be able to switch these on/off.
Details
- Reviewers
dcoughlin zaks.anna xazax.hun - Commits
- rG829c6bc04a6f: [analyzer] Extend block in critical section check with C11 and Pthread APIs.
rC297461: [analyzer] Extend block in critical section check with C11 and Pthread APIs.
rL297461: [analyzer] Extend block in critical section check with C11 and Pthread APIs.
Diff Detail
- Repository
- rL LLVM
Event Timeline
I saw on Twitter today that this checker already has at least one happy user! See https://twitter.com/steipete/status/830099493890703360
A question: under what scenarios do you envision the C11Enabled and PthreadEnabled analyzer options being used? Can we get away with not having the the options and just always check for them?
Also: Thanks for adding documentation to the .html!
lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp | ||
---|---|---|
145 ↗ | (On Diff #87156) | I think it is worth fixing the diagnostic now to correctly mention the called function rather than have a stray '%s' in the message. See, for example, CompareReturnTypes() in CheckObjCInstMethSignature.cpp for how to create a diagnostic message dynamically. |
I think we need to change CallDescription to enable those by default.
See https://clang.llvm.org/doxygen/CallEvent_8cpp_source.html#l00213
So in case an identifier does not exist in a translation unit, the identifier lookup is repeated on every CallEvent::isCalled call which might become a performance issue. We should cache the fact a lookup was already done.
I think we need to change CallDescription to enable those by default.
See https://clang.llvm.org/doxygen/CallEvent_8cpp_source.html#l00213
So in case an identifier does not exist in a translation unit, the identifier lookup is repeated on every CallEvent::isCalled call which might become a performance issue. We should cache the fact a lookup was already done.
Good point! Have you observed performance issues due to this or is this based on an observation that the implementation of CallEvent::isCalled is not optimal?
Do you propose to keep a cache of all identifiers that were were previously looked up by all callers of CallEvent? Or should there be a per checker cache?
The main adopters of the new CallEvent API are ValistChecker.cpp, SimpleStreamChecker.cpp, and BlockInCriticalSectionChecker.cpp. The API optimization should be a separate patch. Are there volunteers to tackle it?
I did not measure the performance, only observed the implementation. Do you want me to do a measurement first? I fear that it might be noisy due to the fact that the execution time might still be dominated by other parts of the analyzer.
Do you propose to keep a cache of all identifiers that were were previously looked up by all callers of CallEvent? Or should there be a per checker cache?
I would put the cache inside the CallDescription objects, so checker authors do not need to wory about this.
The main adopters of the new CallEvent API are ValistChecker.cpp, SimpleStreamChecker.cpp, and BlockInCriticalSectionChecker.cpp. The API optimization should be a separate patch. Are there volunteers to tackle it?
I will submit a separate patch.
https://reviews.llvm.org/D29884 is up for review. With those changes accepted +1 for removing the options.
lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp | ||
---|---|---|
145 ↗ | (On Diff #87156) | I think Devin suggests using llvm::raw_svector_ostream here. Another example is in MallocChecker.cpp. |
Based on your feedback I've removed the PThreadEnabled and C11Enabled options and also in the warning %s has been replaced by the function's name itself.
Thanks for your feedback and helpful comments!
Thanks for updating this!
It looks good to me with the diagnostic changes (single quotes, removed period) mentioned inline!
lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp | ||
---|---|---|
143 ↗ | (On Diff #90052) |
Also, here is a suggestion for a slightly re-worded diagnostic that seems more direct to me: "Call to blocking function 'foo' inside of critical section" What do you think? |
148 ↗ | (On Diff #90052) | You shouldn't do it in this commit, but one thing that would make this checker even more helpful would be to add a BugReporterVisitor adding a path note indicating where the critical section began. |
Thanks for the feedback again. I've changed the diagnostic message and uploaded the new diff.
Please note, that I'm not allowed to commit yet, so if it's accepted, may I ask some of you to commit my changes please? Thanks!
Did you rerun the tests? As far as I can see, you did not update the test files according to the rewording of the message, so I think they won't pass.