JDiGz
JDiGz

Reputation: 23

Segmentation Fault during runtime elaboration: Ada

My program is seg-faulting in the package elaboration section. I declare a a bunch of variables in a block in the body. They are all records with a QLOCK, First ID Number, Last ID Number, and a data array. All different types because the data and ID range is slightly different for each record.

The types are all defined in the same package spec (SMO_Types) but only one of them causes a seg fault.

Ada catches this segfault and raises a storage error so the output looks like this

raised STORAGE_ERROR : s-intman.adb:136 explicit raise

I tried to force elaboration order by putting Elaborate_All(SMO_Types);

It still had a seg fault during runtime.

When I comment out that declaration and any uses of that single variable it works fine.

begin -- Package Body
EX1_Access := EX_PKG.Object_Access(Read_Only => False);
EX2_Access := EX_PKG.Object_Access(Read_Only => False);
EX3_Access := EX_PKG.Object_Access(Read_Only => False);

IPC_API.Qlock.Init(Lock => EX1_Access.QLock, Name => "EX1_Access.QLock");
IPC_API.Qlock.Init(Lock => EX2_Access.QLock, Name => "EX2_Access.QLock");
IPC_API.Qlock.Init(Lock => EX3_Access.QLock, Name => "EX3_Access.QLock");

declare
  EX1 : constant SMO_Types.EX1_Type
     := (QLock => EX1_Access.QLock,
         First => ACT.EX1_ID_Type'first,
         Last  => ACT.EX1_ID_Type'last,
         Data  => (others => (EX_File => EX_API_Types.NOT_DEFINED)));

--The following EX2_Type causes the elaboration issue, if I comment this
--declaration/init and it's use the code works.
--If I make a random variable of EX2_Type without making it a constant
--and initializing it there is still a seg fault. Therefor it seems
--likely that the issue lies with the EX2_Type.
  EX2 : constant SMO_Types.EX2_Type 
     := (QLock => EX2_Access.QLock,
         First => ACT.EX2_ID_Type'first,
         Last  => ACT.EX2_ID_Type'last,
         Data  => (others => (EX_File => EX_API_Types.NOT_DEFINED)));
  EX3 : constant SMO_Types.EX3_Type
     := (QLock => EX3_Access.QLock,
         First => ACT.EX3_ID_Type'first,
         Last  => ACT.EX3_ID_Type'last,
         Data  => (others => (EX_File => EX_API_Types.NOT_DEFINED)));
begin

EX1_Access.all := EX1;
EX2_Access.all := EX2;
EX3_Access.all := EX3;

end Example_Package;

*** EDIT: Here are the types (Ignore the weird order of EX1 vs EX2 vs EX3, this isn't a retyping typo. It is how they are in the legacy code)

MAX_EX_COUNT : constant := 36367;
MAX_EX1_COUNT : constant := 18947;
MAX_EX2_COUNT : constant := 1000;
MAX_EX3_COUNT : constant := 1000;

type EX_ID_Type is range -1 .. MAX_EX_COUNT;
   for EX_ID_Type'size use 4*8;

subtype EX2_ID_Type is ID_Type
   range 1 .. MAX_EX2_COUNT;
subtype EX1_ID_Type is ID_Type
   range EX2_ID_Type'Last+1 .. EX2_ID_Type'Last+MAX_EX1_COUNT;
subtype EX3_ID_Type is ID_Type
   range EX1_ID_Type'Last+1 .. EX1_ID_Type'Last+MAX_EX3_COUNT;

type Data_Array_Type is array (EX_ID_Type range <>)
   of EX_API_Types.EX_Data_Type;

type EX_Record_Type (First, Last : EX_ID_Type) is
   record
      Qlock : IPC_API.Qlock.Qlock_Type;
      Data  : Data_Array_Type(First .. Last);
   end record;

subtype EX1_Type is
   EX_Record_Type(First => EX1_ID_Type'first,
                  Last  => EX1_ID_Type'last);

subtype EX2_Type is
   EX_Record_Type(First => EX2_ID_Type'first,
                  Last  => EX2_ID_Type'last);

subtype EX3_Type is
   EX_Record_Type(First => EX3_ID_Type'first,
                  Last  => EX3_ID_Type'last);

Upvotes: 0

Views: 774

Answers (3)

JDiGz
JDiGz

Reputation: 23

As @JimRogers mentioned at the end of his post "It appears that your program has insufficient stack space" ended up being the problem leading me to the solution.

There were parallel changes going on to my library changes and one of those changes re-located a scripts "ulimit -Ss 65536" to a different script that didn't end up getting run when the program was being run.

Because of @JimRogers I began troubleshooting stack issues and ended up seeing the above change and reverted it in my sandbox. This fixed the issue. Thanks for everyones help!

TLDR Problem: Stack ran out of space during elaboration Solution: Added "ulimit -Ss 65536" (Increase the soft stack size to 64KB) to run scripts.

Upvotes: 1

egilhh
egilhh

Reputation: 6430

First, you create and allocate your access values, with unknown discriminants:

EX1_Access := EX_PKG.Object_Access(Read_Only => False);

Then you create new objects with other, possibly different discriminants:

 EX1 : constant SMO_Types.EX1_Type
     := (QLock => EX1_Access.QLock,
         First => ACT.EX1_ID_Type'first,
         Last  => ACT.EX1_ID_Type'last,
         Data  => (others => (EX_File => EX_API_Types.NOT_DEFINED)));

Then you try to copy the contents of these new objects into the previously allocated access values:

EX1_Access.all := EX1;

This always will fail whenever the discriminants differ, it was just pure luck that First and Last for EX1 matched the allocated value.

Upvotes: 0

Jim Rogers
Jim Rogers

Reputation: 5021

Your type definitions are still incomplete. We can only make broad assumptions about your types.

type Data_Array_Type is array (EX_ID_Type range <>)
   of EX_API_Types.EX_Data_Type;

type EX_Record_Type (First, Last : EX_ID_Type) is
   record
      Qlock : IPC_API.Qlock.Qlock_Type;
      Data  : Data_Array_Type(First, Last);
   end record;

subtype EX1_Type is
   EX_Record_Type(First => EX1_ID_Type'first,
                  Last  => EX1_ID_Type'last);

subtype EX2_Type is
   EX_Record_Type(First => EX2_ID_Type'first,
                  Last  => EX2_ID_Type'last);

subtype EX3_Type is
   EX_Record_Type(First => EX3_ID_Type'first,
                  Last  => EX3_ID_Type'last);

The definition of your unconstrained array type declares the index to be a range of values within EX_ID_Type. The same type is used for the discriminants for EX_Record_Type. Somewhere you must be defining EX1_ID_Type, EX2_ID_Type, and EX3_ID_Type. I can only assume those are subtypes of EX_ID_Type.

Your definition of the Data field in your record is incorrect Ada syntax. An instance of an unconstrained array must be defined with a range. You do not provide a range, only an upper and lower bounds. The proper notation should be:

type EX_Record_Type (First, Last : EX_ID_Type) is
   record
      Qlock : IPC_API.Qlock.Qlock_Type;
      Data  : Data_Array_Type(First .. Last);
   end record;

You need to look at the number of elements in the range EX2_ID_Type'First..EX2_ID_Type'Last. According to the error message you report it appears that your program has insufficient stack space for an array of this size along with all the other data maintained on the stack.

Upvotes: 1

Related Questions