Deadlock
Call sequence to lock functions cause two tasks to block each other
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 multiple tasks are stuck in their critical sections (CS) because:
Each CS waits for another CS to end.
The critical sections (CS) form a closed cycle. For example:
CS #1 waits for CS #2 to end, and CS #2 waits for CS #1 to end.
CS #1 waits for CS #2 to end, CS #2 waits for CS #3 to end and CS #3 waits for CS #1 to end.
Polyspace expects critical sections of code to follow a specific format. A critical section lies between a call to a lock function and a call to an unlock function. When a task my_task
calls a lock function my_lock
, other tasks calling my_lock
must wait until my_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
Each task waits for a critical section in another task to end and is unable to proceed. The program can freeze indefinitely.
Fix
The fix depends on the root cause of the defect. You can try to break the cyclic order between the tasks in one of these ways:
Write down all critical sections involved in the deadlock in a certain sequence. Whenever you call the lock functions of the critical sections within a task, respect the order in that sequence. See an example below.
If one of the critical sections involved in a deadlock occurs in an interrupt, try to disable all interrupts during critical sections in all tasks. See
Disabling all interrupts (-routine-disable-interrupts -routine-enable-interrupts)
.
Reviewing this defect is an opportunity to check if all operations in your critical section are really meant to be executed as an atomic block. It is a good practice to keep critical sections at a bare minimum.
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 multithreading functions that are not supported by Polyspace. Extend this checker by mapping the functions of your multithreading functions to their 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: DEADLOCK |
Impact: High |
Version History
Introduced in R2014b
See 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
| Destruction of locked mutex
| Double lock
| 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