OberonCore
https://forum.oberoncore.ru/

ошибка при запуске ООП реализации Подписчики-Рассыльщик
https://forum.oberoncore.ru/viewtopic.php?f=29&t=3572
Страница 1 из 1

Автор:  Роман М. [ Пятница, 23 Сентябрь, 2011 11:24 ]
Заголовок сообщения:  ошибка при запуске ООП реализации Подписчики-Рассыльщик

Решил проверить на КП некоторый упрощённый способ ООП реализации обработки сообщений по модели Подписчики-Рассыльщик и наткнулся на непонятную ошибку при запуске:
Цитата:
illegal memory read
. Что это может значить?
Проверено в BBCB 1.6 rc5.

Код:
MODULE PrivSubscription;

   CONST
      MaxItems = 10;
   
   TYPE
      Object* = EXTENSIBLE RECORD END;
      
      BasicSubscriber* = POINTER TO ABSTRACT RECORD END;
      
      Subscribers* = ARRAY MaxItems OF BasicSubscriber;
      
      SubscriberList = RECORD
         items: Subscribers;
         count: INTEGER
      END;
      
      Message* = RECORD(Object)
         text-: ARRAY 30 OF CHAR
      END;
      Parameter* = RECORD(Object) END;
      
      SubscriberManager* = RECORD
         list: SubscriberList
      END;
      
      PROCEDURE (VAR M: Message) Set* (IN text: ARRAY OF CHAR), NEW;
      BEGIN
         M.text := text$
      END Set;
      
      PROCEDURE (S: BasicSubscriber) InterpretMessage* (VAR m: Message; VAR p: Parameter), NEW, ABSTRACT;
      
      PROCEDURE (VAR L: SubscriberList) New (s: BasicSubscriber), NEW;
      BEGIN
         L.count := 0
      END New;
      
      PROCEDURE (VAR L: SubscriberList) Add (s: BasicSubscriber), NEW;
      BEGIN
         ASSERT(L.count < MaxItems);
         INC(L.count);
         L.items[L.count - 1] := s
      END Add;
      
      PROCEDURE (VAR L: SubscriberList) Each (m: Message; p: Parameter), NEW;
         VAR i: INTEGER; s: BasicSubscriber;
      BEGIN
         FOR i := 0 TO L.count - 1 DO
            s := L.items[i];
            s.InterpretMessage(m, p)
         END
      END Each;
      
      PROCEDURE (VAR M: SubscriberManager) AddSubscriber* (s: BasicSubscriber), NEW;
      BEGIN
         IF M.list.count < MaxItems THEN  M.list.Add(s) END
      END AddSubscriber;
      
      PROCEDURE (VAR M: SubscriberManager) DeliverMessage* (m: Message; p: Parameter), NEW;
      BEGIN
         M.list.Each(m, p)
      END DeliverMessage;

END PrivSubscription.


Код:
MODULE PrivSubscriptionDemo;
   
   IMPORT Subscription := PrivSubscription, StdLog;
   
   TYPE
      MySubscriber = POINTER TO RECORD(Subscription.BasicSubscriber) END;
      
   PROCEDURE (S: MySubscriber) InterpretMessage (VAR m: Subscription.Message; VAR p: Subscription.Parameter);
   BEGIN
      StdLog.String("Interpreter of MySubscriber");
      StdLog.String(m.text)
   END InterpretMessage;
   
   PROCEDURE Do*;
      VAR
         msg: Subscription.Message;
         parameters: Subscription.Parameter;
         mySubscriber: MySubscriber;
         manager: Subscription.SubscriberManager;
   BEGIN
      msg.Set("Message");
      NEW(mySubscriber);
      manager.AddSubscriber(mySubscriber);
      manager.DeliverMessage(msg, parameters)
   END Do;
   
END PrivSubscriptionDemo.


:!: PrivSubscriptionDemo.Do

Автор:  Сергей Губанов [ Пятница, 23 Сентябрь, 2011 11:39 ]
Заголовок сообщения:  Re: ошибка при запуске ООП реализации Подписчики-Рассыльщик

Забавно. Кажись Блэкбокс забыл обнулить первые четыре элемента в массиве указателей размещённом на стеке.

Согласно "стандарту" языка Компонентный Паскаль указательные переменные размещаемые на стеке должны автоматически обнуляться компилятором.

Воспроизвёл ошибку в 1.5.

Могу посоветовать "вручную" обнулять value-значные RECORD размещённые на стэке перед их первым использованием.

Автор:  Евгений Темиргалеев [ Пятница, 23 Сентябрь, 2011 11:40 ]
Заголовок сообщения:  Re: ошибка при запуске ООП реализации Подписчики-Рассыльщик

Попробуйте в 1.6 rc6
Код:
System/Mod/Kernel
- 20080107, bh, full GC included in NewBlock
- 20080107, bh, pointer anchoring bug corrected in NewRec & NewArr
Вдруг в этом дело.

Автор:  Сергей Губанов [ Пятница, 23 Сентябрь, 2011 11:42 ]
Заголовок сообщения:  Re: ошибка при запуске ООП реализации Подписчики-Рассыльщик

Для истории:
Вложение:
trap.png
trap.png [ 29.46 КБ | Просмотров: 5837 ]

Автор:  Сергей Губанов [ Пятница, 23 Сентябрь, 2011 11:44 ]
Заголовок сообщения:  Re: ошибка при запуске ООП реализации Подписчики-Рассыльщик

Сергей Губанов писал(а):
Забавно. Кажись Блэкбокс забыл обнулить первые четыре элемента в массиве указателей размещённом на стеке.
А может и обнулил, но потом запорол чем-то другим. Это ещё страшнее.

Автор:  Евгений Темиргалеев [ Пятница, 23 Сентябрь, 2011 12:08 ]
Заголовок сообщения:  Re: ошибка при запуске ООП реализации Подписчики-Рассыльщик

Зануляет. Ср. HALT(0) после manager.AddSubscriber(mySubscriber)
Надо смотреть дальше...
Вложение:
Снимок-1.png
Снимок-1.png [ 46.18 КБ | Просмотров: 5833 ]

P.S. скриншот из 1.6rc6

upd: запорчены сразу внутри PROCEDURE (VAR M: SubscriberManager) DeliverMessage* (m: Message; p: Parameter), NEW;
Подозрение вызывает параметр-значение p: Parameter, т.к. Parameter --- пустая запись.

upd2: Добавил поле: Parameter* = RECORD(Object) x: INTEGER END;
Ошибка пропала.

Автор:  Евгений Темиргалеев [ Пятница, 23 Сентябрь, 2011 12:18 ]
Заголовок сообщения:  Re: ошибка при запуске ООП реализации Подписчики-Рассыльщик

Если дело и правда в пустой записи, то, пожалуй, ошибка не критична. Т.к. случай вырожденный и на практике не нужный..

Автор:  Евгений Темиргалеев [ Пятница, 23 Сентябрь, 2011 12:24 ]
Заголовок сообщения:  Re: ошибка при запуске ООП реализации Подписчики-Рассыльщик

(не по теме)
Евгений Темиргалеев писал(а):
upd: запрочены уже внутри PROCEDURE (VAR M: SubscriberManager) DeliverMessage* (m: Message; p: Parameter), NEW;
Подозрение вызывает параметр-значение p: Parameter, т.к. Parameter --- пустая запись.
Мне даже странным кажется. Неужели КП поддерживает передачу расширяемых записей по значению?

Роман, Вы считаете допустимым гонять по стэку копии записей сообщения и параметра при каждом вызове DeliverMessage? А если в параметре будет несколько десятков Кб данных?

P.S. Правильно Вирт сделал, избавившись от параметров-значений структурных типов в Oberon-07 (viewtopic.php?p=65477#p65477)...

Автор:  Роман М. [ Пятница, 23 Сентябрь, 2011 14:05 ]
Заголовок сообщения:  Re: ошибка при запуске ООП реализации Подписчики-Рассыльщик

Евгений Темиргалеев писал(а):
(не по теме)
Евгений Темиргалеев писал(а):
upd: запрочены уже внутри PROCEDURE (VAR M: SubscriberManager) DeliverMessage* (m: Message; p: Parameter), NEW;
Подозрение вызывает параметр-значение p: Parameter, т.к. Parameter --- пустая запись.
Мне даже странным кажется. Неужели КП поддерживает передачу расширяемых записей по значению?

Роман, Вы считаете допустимым гонять по стэку копии записей сообщения и параметра при каждом вызове DeliverMessage? А если в параметре будет несколько десятков Кб данных?

P.S. Правильно Вирт сделал, избавившись от параметров-значений структурных типов в Oberon-07 (viewtopic.php?p=65477#p65477)...

Вообще-то в данном случае речь идет не об эффективности, хотя я согласен что не стоит. Я лишь проверял как этот вариант сработает в лабораторных условиях. Ведь языком это не запрещается.

Автор:  Евгений Темиргалеев [ Среда, 28 Сентябрь, 2011 23:42 ]
Заголовок сообщения:  Re: ошибка при запуске ООП реализации Подписчики-Рассыльщик

Евгений Темиргалеев писал(а):
Мне даже странным кажется. Неужели КП поддерживает передачу расширяемых записей по значению?
Не поддерживает. Присваивать можно только "финальные" записи. (см. также Record assignment "projection")

Subscription.Parameter как раз финальная.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/