No Unhandled Application-Defined Exceptions (EXU02)
Level \(\rightarrow\) Required
- Category
- Safety:
\(\checkmark\)
- Cyber:
\(\checkmark\)
- Goal
- Maintainability:
\(\checkmark\)
- Reliability:
\(\checkmark\)
- Portability:
\(\checkmark\)
- Performance:
- Security:
Remediation \(\rightarrow\) Low
Verification Method \(\rightarrow\) GNATcheck rule:
Unhandled_Exceptions
(supplied with document)
Reference
N/A
Description
All application-defined exceptions must have at least one corresponding handler that is applicable. Otherwise, if an exception is raised, undesirable behavior is possible. The term applicable means that there is no dynamic call chain that can reach the active exception which does not also include a handler that will be invoked for that exception, somewhere in that chain.
When an unhandled exception occurs in the sequence of statements of an application task and propagates to task's body, the task terminates abnormally. No notification of some sort is required or defined by the language, although some vendors' implementations may print out a log message or provide some other non-standard response. (Note that such a notification implies an external persistent environment, such as an operating system, that may not be present in all platforms.) The task failure does not affect any other tasks unless those other tasks attempt to communicate with it. In short, failure is silent.
Although the language-defined package Ada.Task_Termination
can be used to
provide a response using standard facilities, not all run-time libraries
provide that package. For example, under the Ravenscar profile, application
tasks are not intended to terminate, neither normally nor abnormally, and the
language does not define what happens if they do. A run-time library for a
memory-constrained target, especially a bare-metal target without an operating
system, might not include any support for task termination when the tasking
model is Ravenscar. The effects of task termination in that case are not
defined by the language.
When an unhandled exception occurrence reaches the main subprogram and is not handled there, the exception occurrence is propagated to the environment task, which then completes abnormally. Even if the main subprogram does handle the exception, the environment task still completes (normally in that case).
When the environment task completes (normally or abnormally) it waits for the completion of dependent application tasks, if any. Those dependent tasks continue executing normally, i.e., they do not complete as a result of the environment task completion. Alternatively, however, instead of waiting for them, the implementation has permission to abort the dependent application tasks, per Ada Reference Manual: 10.2 (30) Program Execution The resulting application-specific effect is undefined.
Finally, whether the environment task waited for the dependent tasks or aborted them, the semantics of further execution beyond that point are undefined. There is no concept of a calling environment beyond the environment task (Ada Reference Manual: 10.2 (30) Program Execution). In some systems there is no calling environment, such as bare-metal platforms with only an Ada run-time library and no operating system.
Applicable Vulnerability within ISO TR 24772-2
6.36 Ignored error status and unhandled exceptions [OYB]
Applicable Common Weakness Enumeration
Noncompliant Code Example
procedure Main is
begin
if Argument_Count = 0 then
raise Cli_Exception;
else
begin
Start_Application (Argument (1));
exception
when Application_Exception =>
Put_Line ("Application failed");
end;
end if;
end Main;
Compliant Code Example
procedure Main is
begin
if Argument_Count = 0 then
raise Cli_Exception;
else
begin
Start_Application (Argument (1));
exception
when Application_Exception =>
Put_Line ("Application failed");
end;
end if;
exception
when Cli_Exception =>
Put_Line ("Failure");
end Main;
Notes
SPARK can prove that no exception will be raised (or fail to prove it and indicate the failure).