Double unlock
Unlock function is called twice in a task without an intermediate call to lock function
Description
This checker is deactivated in a default Polyspace® as You Code analysis. See Checkers Deactivated in Polyspace as You Code Analysis (Polyspace Access).
This defect occurs when:
A task calls a lock function
my_lock
.The task calls the corresponding unlock function
my_unlock
.The task calls
my_unlock
again. The task does not callmy_lock
a second time between the two calls tomy_unlock
.
In multitasking code, a lock function begins a critical section of code and an unlock function ends it. When a task task1
calls a lock function my_lock
, other tasks calling my_lock
must wait until task1
calls the corresponding unlock function.
To find this defect, specify your lock and unlock functions using one of these methods:
Invoke one of the concurrency primitives that Polyspace Bug Finder™ can detect automatically. See Auto-Detection of Thread Creation and Critical Section in Polyspace.
Specify lock and unlock functions explicitly before analysis as configuration options. Polyspace requires that both lock and unlock functions must have the form
void func(void)
. SeeCritical section details (-critical-section-begin -critical-section-end)
.
Risk
A double unlock defect can indicate a coding error. Perhaps you wanted to call a different unlock function to end a different critical section. Perhaps you called the unlock function prematurely the first time and only the second call indicates the end of the critical section.
Fix
The fix depends on the root cause of the defect.
Identify each critical section of code, that is, the section that you want to be executed as an atomic block. Call a lock function at the beginning of the section. Only at the end of the section, call the unlock function that corresponds to the lock function. Remove any other redundant call to the unlock function.
See examples of fixes below. To avoid the
issue, you can follow the practice of calling the lock and unlock functions in the
same module at the same level of abstraction. For instance, in this example,
func
calls the lock and unlock function at the same level but
func2
does
not.
void func() { my_lock(); { ... } my_unlock(); } void func2() { { my_lock(); ... } my_unlock(); }
If you do not want to fix the issue, add comments to your result or code to avoid another review. See:
Address Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
Extend Checker
You might be using unlocking functions that are not supported by Polyspace. Extend this checker by mapping your unlocking functions to its known POSIX® equivalent. See Extend Concurrency Defect Checkers to Unsupported Multithreading Environments.
Examples
Result Information
Group: Concurrency |
Language: C | C++ |
Default: On |
Command-Line Syntax: DOUBLE_UNLOCK |
Impact: High |
Version History
Introduced in R2014bSee Also
Temporally exclusive tasks (-temporal-exclusions-file)
| Critical section details (-critical-section-begin -critical-section-end)
| Tasks (-entry-points)
| Configure multitasking manually
| Find defects (-checkers)
| Data race
| Data race through standard library function call
| Deadlock
| Destruction of locked mutex
| Double lock
| Missing lock
| Missing unlock
Topics
- Analyze Multitasking Programs in Polyspace
- Interpret Bug Finder Results in Polyspace Desktop User Interface
- Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access)
- Address Results in Polyspace User Interface Through Bug Fixes or Justifications
- Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access)
- Extend Concurrency Defect Checkers to Unsupported Multithreading Environments