运行时详细说明期间的分段错误:Ada
Segmentation Fault during runtime elaboration: Ada
我的程序在包详细说明部分出现段错误。我在正文的一个块中声明了一堆变量。它们都是带有 QLOCK、First ID Number、Last ID Number 和数据数组的记录。所有不同的类型,因为每条记录的数据和 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);
您的类型定义仍然不完整。
我们只能对您的类型做出广泛的假设。
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
范围内的元素数量。根据您报告的错误消息,您的程序似乎没有足够的堆栈 space 来容纳此大小的数组以及堆栈中维护的所有其他数据。
首先,您使用未知的判别式创建并分配您的访问值:
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;
每当判别式不同时,这总是会失败,
EX1
的 First
和 Last
与分配的值匹配完全是运气。
正如@JimRogers 在他的 post 末尾提到的,"It appears that your program has insufficient stack space" 最终成为导致我找到解决方案的问题。
我的库发生了并行变化,其中一个变化是 re-located 一个脚本 "ulimit -Ss 65536" 到另一个脚本,当程序正在 运行.
因为@JimRogers,我开始解决堆栈问题并最终看到上述更改并将其还原到我的沙箱中。这解决了这个问题。感谢大家的帮助!
TLDR
问题:在细化过程中从 space 中堆叠 运行
解决方案:将 "ulimit -Ss 65536"(将软堆栈大小增加到 64KB)添加到 运行 个脚本。
我的程序在包详细说明部分出现段错误。我在正文的一个块中声明了一堆变量。它们都是带有 QLOCK、First ID Number、Last ID Number 和数据数组的记录。所有不同的类型,因为每条记录的数据和 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);
您的类型定义仍然不完整。 我们只能对您的类型做出广泛的假设。
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
范围内的元素数量。根据您报告的错误消息,您的程序似乎没有足够的堆栈 space 来容纳此大小的数组以及堆栈中维护的所有其他数据。
首先,您使用未知的判别式创建并分配您的访问值:
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;
每当判别式不同时,这总是会失败,
EX1
的 First
和 Last
与分配的值匹配完全是运气。
正如@JimRogers 在他的 post 末尾提到的,"It appears that your program has insufficient stack space" 最终成为导致我找到解决方案的问题。
我的库发生了并行变化,其中一个变化是 re-located 一个脚本 "ulimit -Ss 65536" 到另一个脚本,当程序正在 运行.
因为@JimRogers,我开始解决堆栈问题并最终看到上述更改并将其还原到我的沙箱中。这解决了这个问题。感谢大家的帮助!
TLDR 问题:在细化过程中从 space 中堆叠 运行 解决方案:将 "ulimit -Ss 65536"(将软堆栈大小增加到 64KB)添加到 运行 个脚本。