OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 12 Ноябрь, 2019 19:51

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
СообщениеДобавлено: Пятница, 23 Сентябрь, 2011 11:24 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
Решил проверить на КП некоторый упрощённый способ ООП реализации обработки сообщений по модели Подписчики-Рассыльщик и наткнулся на непонятную ошибку при запуске:
Цитата:
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 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Забавно. Кажись Блэкбокс забыл обнулить первые четыре элемента в массиве указателей размещённом на стеке.

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

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 23 Сентябрь, 2011 11:40 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Попробуйте в 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 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Для истории:
Вложение:
trap.png
trap.png [ 29.46 КБ | Просмотров: 5975 ]


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 23 Сентябрь, 2011 11:44 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Сергей Губанов писал(а):
Забавно. Кажись Блэкбокс забыл обнулить первые четыре элемента в массиве указателей размещённом на стеке.
А может и обнулил, но потом запорол чем-то другим. Это ещё страшнее.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 23 Сентябрь, 2011 12:08 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Зануляет. Ср. HALT(0) после manager.AddSubscriber(mySubscriber)
Надо смотреть дальше...
Вложение:
Снимок-1.png
Снимок-1.png [ 46.18 КБ | Просмотров: 5971 ]

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 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Если дело и правда в пустой записи, то, пожалуй, ошибка не критична. Т.к. случай вырожденный и на практике не нужный..


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 23 Сентябрь, 2011 12:24 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
(не по теме)
Евгений Темиргалеев писал(а):
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 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
Евгений Темиргалеев писал(а):
(не по теме)
Евгений Темиргалеев писал(а):
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 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Евгений Темиргалеев писал(а):
Мне даже странным кажется. Неужели КП поддерживает передачу расширяемых записей по значению?
Не поддерживает. Присваивать можно только "финальные" записи. (см. также Record assignment "projection")

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


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB