How to panic with Ada?

I’m a newbie learning about Ada error handling. I know that Ada has exceptions, but is there anything to abort program execution immediately?

I’m looking for something like panic!() in Rust or exit() / abort() in C.

Thanks in advance.

1 Like

Ada is calm, cool, and collected. She never panics.

Typically, ending a program immediately is done by raising an exception that is not handled. However, the program won’t end if there are running tasks, since the exception won’t affect any tasks except the task in which it is raised. For concurrent programs, you need to implement a mechanism to end the program. Such a mechanism is needed for any concurrent program that needs to end, so you’ll typically be creating it anyway.

2 Likes

In theory (and I haven’t tested it), you could do

Ada.Task_Identification.Abort_Task(Ada.Task_Identification.Environment_Task);

This is however a mean approach and won’t perform cleanup that might be neccessary on some operating systems. Like @JC001 says, you should use a mechanism to end the program. One such mechanism is here

2 Likes

What Jeff said,

however, you can use the GNAT library to do that too:

with Ada.Text_IO; use Ada.Text_IO;
with GNAT.OS_Lib;
procedure Stopping is
   procedure P is
   begin
      GNAT.OS_Lib.OS_Exit (0);
   end P;
begin
   Put_Line ("starting");
   P;
   Put_Line ("shouldn't have got here");
end Stopping;

This answer is taken from Simon’s reply here

Best,
Fer

4 Likes

Thanks for all your answers. I have a lot to learn.

If the program is supposed to panic on some condition (e.g. if is it detected that some data structure is unrecoverably corrupted) it is also an option to check for that condition using a pre- or postcondition (or Pragma Assert) and not handling Assertion_Error. That would be Ada’s equivalent to assert() in C.

For example:

pragma Assertion_Policy (Pre => Check);

procedure Main is
   Must_Be_True : Boolean;
   
   procedure P
     with Pre => Must_Be_True
   is
   begin
      null;
   end P;

begin
   Must_Be_True := False;
   P; -- raises Assertion_Error
end Main;

However, this does not end the program if other tasks are running.

1 Like

We all know that feeling. Feel free to ask for questions or resources! Ada is 40 years old, so most issues, problems or questions that you may have, will have already been considered by the Ada users and designers :slight_smile:

Best,
Fer

3 Likes

I wonder if the Abort_Task has the same semantics as the abort statement?

I believe, with the abort statement the named task will terminate (or more accurately get into an “abnormal” state) when it hits some abort-completion checkpoint (i.e. task activation completion, beginning or end of an entry call and some others) and when it’s not executing some abort-deferred logic like waiting for child tasks to terminate or whilst being inside a protected operation and some others.

Running this:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Task_Identification;

procedure Environment_Task_Termination is
   task Some_Task;
   task body Some_Task is
   begin
      for I in 1 .. 5 loop
         Put_Line ("Alive!");
         delay 1.0;
      end loop;
   end Some_Task;
begin
   Put_Line ("Aborting");
   --  Ada.Task_Identification.Abort_Task (Ada.Task_Identification.Environment_Task);
end Environment_Task_Termination;

prints Alive! five times (intermixed witth one Aborting) and then terminates as expected. However, commenting the Abort_Task call in, the program prints just:

Alive!
Aborting

and then terminates without waiting for the dependent task to terminate.

I wonder if that’s down to how the parent-child hierarchy has been created in this case?