CWE Rule 765
Description
Rule Description
The product unlocks a critical resource more times than intended, leading to an unexpected state in the system.
Polyspace Implementation
The rule checker checks for Double unlock.
Examples
Double unlock
This checker is deactivated in a default Polyspace® as You Code analysis. See Checkers Deactivated in Polyspace as You Code Analysis (Polyspace Access).
This issue 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)
.
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.
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.
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.
int global_var; void BEGIN_CRITICAL_SECTION(void); void END_CRITICAL_SECTION(void); void task1(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); //Noncompliant } void task2(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); }
In this example, to emulate multitasking behavior, you must specify the following options:
Option | Value | |
---|---|---|
Configure multitasking manually | ||
Tasks (-entry-points) |
| |
Critical section details (-critical-section-begin -critical-section-end) | Starting routine | Ending routine |
BEGIN_CRITICAL_SECTION | END_CRITICAL_SECTION |
On the command-line, you can use the following:
polyspace-bug-finder -entry-points task1,task2 -critical-section-begin BEGIN_CRITICAL_SECTION:cs1 -critical-section-end END_CRITICAL_SECTION:cs1
task1
enters a critical section through the
call BEGIN_CRITICAL_SECTION();
. task1
leaves
the critical section through the call END_CRITICAL_SECTION();
. task1
calls END_CRITICAL_SECTION
again
without an intermediate call to BEGIN_CRITICAL_SECTION
.
If you want the second global_var+=1;
to be outside the critical section,
one possible correction is to remove the second call to
END_CRITICAL_SECTION
. However, if other tasks are using
global_var
, this code can produce a Data race
error.
int global_var; void BEGIN_CRITICAL_SECTION(void); void END_CRITICAL_SECTION(void); void task1(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); global_var += 1; } void task2(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); }
If you want the second global_var+=1;
to
be inside the critical section, one possible correction is to remove
the first call to END_CRITICAL_SECTION
.
int global_var; void BEGIN_CRITICAL_SECTION(void); void END_CRITICAL_SECTION(void); void task1(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; global_var += 1; END_CRITICAL_SECTION(); } void task2(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); }
If you want the second global_var+=1;
to
be inside a critical section, another possible correction is to add
another call to BEGIN_CRITICAL_SECTION
.
int global_var; void BEGIN_CRITICAL_SECTION(void); void END_CRITICAL_SECTION(void); void task1(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); } void task2(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); }
Check Information
Category: Resource Locking Problems |
Version History
Introduced in R2024a
See Also
External Websites
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)