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);