Double lock
Lock function is called twice in a task without an intermediate call to unlock 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
my_lock
again before calling the corresponding unlock function.
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 lock
, other tasks calling lock
must wait until task
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 call to a lock function begins a critical section so that other tasks have to wait to enter the same critical section. If the same lock function is called again within the critical section, the task blocks itself.
Fix
The fix depends on the root cause of the defect. A double lock defect often indicates a coding error. Perhaps you omitted the call to an unlock function to end a previous critical section and started the next critical section. Perhaps you wanted to use a different lock function for the second critical section.
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. Within the critical section, make sure that you do not call the lock function again. At the end of the section, call the unlock function that corresponds to the lock 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 locking functions that are not supported by Polyspace. Extend this checker by mapping your locking 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_LOCK |
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 unlock
| 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