运行时详细说明期间的分段错误:Ada

时间:2019-05-20 20:18:26

标签: segmentation-fault runtime ada elaboration

我的程序在软件包详细说明部分中存在段错误。我在体内的一个块中声明了一堆变量。它们都是带有QLOCK,第一个ID号,最后一个ID号和一个数据数组的记录。所有类型不同,因为每条记录的数据和ID范围略有不同。

所有类型都在同一程序包规范(SMO_Types)中定义,但只有其中一种会导致段错误。

Ada捕获此段错误并引发存储错误,因此输出看起来像这样

提高了STORAGE_ERROR:s-intman.adb:136明确提高

我试图通过放置Elaborate_All(SMO_Types);来强制制定命令;

在运行时它仍然存在段错误。

当我注释掉该声明以及对该单个变量的任何使用时,它工作正常。

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;

***编辑:这是类型 (忽略EX1 vs EX2 vs EX3的奇怪顺序,这不是重复输入错误。这是它们在旧版代码中的样子)

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

3 个答案:

答案 0 :(得分:0)

您的类型定义仍然不完整。 我们只能对您的类型做出广泛的假设。

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

无约束数组类型的定义将索引声明为EX_ID_Type中的值范围。相同的类型用于EX_Record_Type的判别式。 您必须在某个位置定义EX1_ID_Type,EX2_ID_Type和EX3_ID_Type。我只能假定这些是EX_ID_Type的子类型。

您在记录中的“数据”字段定义不正确的Ada语法。必须使用范围定义无约束数组的实例。您不提供范围,仅提供上限和下限。正确的符号应为:

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;

您需要查看EX2_ID_Type'First..EX2_ID_Type'Last范围内的元素数量。根据您报告的错误消息,您的程序似乎没有足够的堆栈空间来容纳此大小的数组以及所有其他保留在堆栈上的数据。

答案 1 :(得分:0)

首先,创建和分配具有未知判别式的访问值:

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

然后,您可以使用其他可能不同的判别式创建新对象:

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

然后,您尝试将这些新对象的内容复制到先前分配的访问值中:

EX1_Access.all := EX1;

只要判别符不同,这总是会失败的, First的{​​{1}}和Last与分配的值相匹配,真是太幸运了。

答案 2 :(得分:0)

正如@JimRogers在他的文章结尾提到的“您的程序似乎没有足够的堆栈空间”,最终导致了我找到解决方案的问题。

我的库更改正在进行并行更改,其中一项更改将脚本“ ulimit -Ss 65536”重新定位到另一个脚本,该脚本最终在运行程序时未运行。

由于@JimRogers的缘故,我开始对堆栈问题进行故障排除,最终看到了以上更改并将其恢复到我的沙箱中。这解决了问题。谢谢大家的帮助!

TLDR 问题:细化过程中堆栈用完了空间 解决方案:添加了“ ulimit -Ss 65536”(将软件堆栈的大小增加到64KB)来运行脚本。