Skip to content

Commit

Permalink
[clang][analyzer] Move unix.BlockInCriticalSection out of alpha (#93815)
Browse files Browse the repository at this point in the history
After recent improvements (#80029) and testing on open-source projects,
the checker is ready to move out of the alpha package.
  • Loading branch information
gamesh411 authored Jun 3, 2024
1 parent 72c901f commit 6ef785c
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 83 deletions.
87 changes: 44 additions & 43 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,50 @@ Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, mallo
.. literalinclude:: checkers/unix_api_example.c
:language: c
.. _unix-BlockInCriticalSection:
unix.BlockInCriticalSection (C, C++)
""""""""""""""""""""""""""""""""""""
Check for calls to blocking functions inside a critical section.
Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``.
Critical section handling functions modeled by this checker:
``lock, unlock, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``.
.. code-block:: c
void pthread_lock_example(pthread_mutex_t *m) {
pthread_mutex_lock(m); // note: entering critical section here
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
pthread_mutex_unlock(m);
}
.. code-block:: cpp
void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) {
std::lock_guard lg{m2}; // note: entering critical section here
mtx_lock(m1); // note: entering critical section here
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
mtx_unlock(m1);
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
// still inside of the critical section of the std::lock_guard
}
**Limitations**
* The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed.
This can lead to false positives.
.. code-block:: c
void trylock_example(pthread_mutex_t *m) {
if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
pthread_mutex_unlock(m);
} else {
sleep(10); // false positive: Incorrect warning about blocking function inside critical section.
}
}
.. _unix-Errno:
unix.Errno (C)
Expand Down Expand Up @@ -3130,49 +3174,6 @@ For a more detailed description of configuration options, please see the
alpha.unix
^^^^^^^^^^
.. _alpha-unix-BlockInCriticalSection:
alpha.unix.BlockInCriticalSection (C)
"""""""""""""""""""""""""""""""""""""
Check for calls to blocking functions inside a critical section.
Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``.
Critical section handling functions modelled by this checker: ``lock, unlock, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``.
.. code-block:: c
void pthread_lock_example(pthread_mutex_t *m) {
pthread_mutex_lock(m); // note: entering critical section here
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
pthread_mutex_unlock(m);
}
.. code-block:: cpp
void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) {
std::lock_guard lg{m2}; // note: entering critical section here
mtx_lock(m1); // note: entering critical section here
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
mtx_unlock(m1);
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
// still inside of the critical section of the std::lock_guard
}
**Limitations**
* The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed.
This can lead to false positives.
.. code-block:: c
void trylock_example(pthread_mutex_t *m) {
if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
pthread_mutex_unlock(m);
} else {
sleep(10); // false positive: Incorrect warning about blocking function inside critical section.
}
}
.. _alpha-unix-Chroot:
alpha.unix.Chroot (C)
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,10 @@ def UnixAPIMisuseChecker : Checker<"API">,
HelpText<"Check calls to various UNIX/Posix functions">,
Documentation<HasDocumentation>;

def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
HelpText<"Check for calls to blocking functions inside a critical section">,
Documentation<HasDocumentation>;

def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">,
HelpText<"The base of several malloc() related checkers. On it's own it "
"emits no reports, but adds valuable information to the analysis "
Expand Down Expand Up @@ -619,10 +623,6 @@ def SimpleStreamChecker : Checker<"SimpleStream">,
HelpText<"Check for misuses of stream APIs">,
Documentation<HasDocumentation>;

def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
HelpText<"Check for calls to blocking functions inside a critical section">,
Documentation<HasDocumentation>;

} // end "alpha.unix"

//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions clang/test/Analysis/analyzer-enabled-checkers.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
// CHECK-NEXT: security.insecureAPI.mktemp
// CHECK-NEXT: security.insecureAPI.vfork
// CHECK-NEXT: unix.API
// CHECK-NEXT: unix.BlockInCriticalSection
// CHECK-NEXT: unix.cstring.CStringModeling
// CHECK-NEXT: unix.DynamicMemoryModeling
// CHECK-NEXT: unix.Errno
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/block-in-critical-section.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.BlockInCriticalSection -verify %s
// expected-no-diagnostics

// This should not crash
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/block-in-critical-section.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang_analyze_cc1 \
// RUN: -analyzer-checker=alpha.unix.BlockInCriticalSection \
// RUN: -analyzer-checker=unix.BlockInCriticalSection \
// RUN: -std=c++11 \
// RUN: -analyzer-output text \
// RUN: -verify %s
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/block-in-critical-section.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify -Wno-objc-root-class %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.BlockInCriticalSection -verify -Wno-objc-root-class %s
// expected-no-diagnostics

@interface SomeClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
// CHECK-NEXT: security.insecureAPI.mktemp
// CHECK-NEXT: security.insecureAPI.vfork
// CHECK-NEXT: unix.API
// CHECK-NEXT: unix.BlockInCriticalSection
// CHECK-NEXT: unix.cstring.CStringModeling
// CHECK-NEXT: unix.DynamicMemoryModeling
// CHECK-NEXT: unix.Errno
Expand Down
33 changes: 0 additions & 33 deletions clang/www/analyzer/alpha_checks.html
Original file line number Diff line number Diff line change
Expand Up @@ -780,39 +780,6 @@ <h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3>
<tbody>


<tr><td><a id="alpha.unix.BlockInCriticalSection"><div class="namedescr expandable"><span class="name">
alpha.unix.BlockInCriticalSection</span><span class="lang">
(C)</span><div class="descr">
Check for calls to blocking functions inside a critical section. Applies to:
<div class=functions>
lock<br>
unlock<br>
sleep<br>
getc<br>
fgets<br>
read<br>
revc<br>
pthread_mutex_lock<br>
pthread_mutex_unlock<br>
mtx_lock<br>
mtx_timedlock<br>
mtx_trylock<br>
mtx_unlock<br>
lock_guard<br>
unique_lock</div>
</div></div></a></td>
<td><div class="exampleContainer expandable">
<div class="example"><pre>
void test() {
std::mutex m;
m.lock();
sleep(3); // warn: a blocking function sleep is called inside a critical
// section
m.unlock();
}
</pre></div></div></td></tr>


<tr><td><a id="alpha.unix.Chroot"><div class="namedescr expandable"><span class="name">
alpha.unix.Chroot</span><span class="lang">
(C)</span><div class="descr">
Expand Down

0 comments on commit 6ef785c

Please sign in to comment.