Ошибка сегментации во время разработки: Ада - PullRequest
0 голосов
/ 20 мая 2019

Моя программа работает с ошибками в разделе разработки пакета. Я объявляю кучу переменных в блоке в теле. Все они представляют собой записи с QLOCK, первым идентификационным номером, последним идентификационным номером и массивом данных. Все разные типы, потому что диапазон данных и идентификаторов немного отличается для каждой записи.

Все типы определены в одной спецификации пакета (SMO_Types), но только один из них вызывает ошибку сегмента.

Ада ловит этот segfault и выдает ошибку хранилища, поэтому вывод выглядит следующим образом

поднято 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 против EX2 против 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 голосов
/ 22 мая 2019

Сначала вы создаете и распределяете свои значения доступа с неизвестными дискриминантами:

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 и Last для EX1 соответствуют выделенному значению.

0 голосов
/ 23 мая 2019

Как @JimRogers упомянул в конце своего поста «Похоже, что вашей программе недостаточно места в стеке», в итоге возникла проблема, которая привела меня к решению.

В моей библиотеке происходили параллельные измененияизменения и одно из этих изменений переместило сценарии "ulimit -Ss 65536" в другой сценарий, который не запустился во время работы программы.

Из-за @JimRogers я начал устранять неполадки стекапроблемы и в конечном итоге увидели вышеуказанные изменения и вернули его в моей песочнице.Это решило проблему.Спасибо всем за помощь!

TLDR Проблема: стеку не хватило места во время разработки Решение: добавлен «ulimit -Ss 65536» (увеличьте размер мягкого стека до 64 КБ) для запуска сценариев.

0 голосов
/ 21 мая 2019

Ваши определения типов все еще неполны.Мы можем только делать широкие предположения о ваших типах.

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.Согласно сообщению об ошибке, которое вы сообщаете, похоже, что вашей программе недостаточно места в стеке для массива такого размера вместе со всеми другими данными, хранящимися в стеке.

...