OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 23 Октябрь, 2017 16:35

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




Начать новую тему Ответить на тему  [ Сообщений: 11 ] 
Автор Сообщение
 Заголовок сообщения: Проблема с выделением памяти
СообщениеДобавлено: Воскресенье, 01 Ноябрь, 2009 22:12 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 588
Откуда: Казань
Взял за основу пример из DevLinker:
Код:
MODULE MySimple;
(* simple windows application *)

   IMPORT S := SYSTEM, WinApi;

   CONST
      message = "Hello World";
      iconId = 1;

   VAR
      instance: WinApi.HINSTANCE;
      mainWnd: WinApi.HWND;

   PROCEDURE WndHandler (wnd, msg, wParam, lParam: INTEGER): INTEGER;
      VAR res: INTEGER; ps: WinApi.PAINTSTRUCT; dc: WinApi.HDC;
   BEGIN
      IF msg = WinApi.WM_DESTROY THEN
         WinApi.PostQuitMessage(0)
      ELSIF msg = WinApi.WM_PAINT THEN
         dc := WinApi.BeginPaint(wnd, ps);
         res := WinApi.TextOut(dc, 50, 50, message, LEN(message));
         res := WinApi.EndPaint(wnd, ps)
      ELSIF msg = WinApi.WM_CHAR THEN
         res := WinApi.Beep(800, 200)
      ELSE
         RETURN WinApi.DefWindowProc(wnd, msg, wParam, lParam)
      END;
      RETURN 0
   END WndHandler;

   PROCEDURE OpenWindow;
      VAR class: WinApi.WNDCLASS; res: INTEGER;
   BEGIN
      class.hCursor := WinApi.LoadCursor(0, S.VAL(WinApi.PtrSTR,
                                                         WinApi.IDC_ARROW));
      class.hIcon := WinApi.LoadIcon(instance, S.VAL(WinApi.PtrSTR, iconId));
      class.lpszMenuName := NIL;
      class.lpszClassName := "Simple";
      class.hbrBackground := WinApi.GetStockObject(WinApi.WHITE_BRUSH);
      class.style := WinApi.CS_VREDRAW + WinApi.CS_HREDRAW
                  (* + WinApi.CS_OWNDC + WinApi.CS_PARENTDC *);
      class.hInstance := instance;
      class.lpfnWndProc := WndHandler;
      class.cbClsExtra := 0;
      class.cbWndExtra := 0;
      res := WinApi.RegisterClass(class);
      mainWnd := WinApi.CreateWindowEx({}, "Simple", "Simple Application",
                                          WinApi.WS_OVERLAPPEDWINDOW,
                                          WinApi.CW_USEDEFAULT, WinApi.CW_USEDEFAULT,
                                          WinApi.CW_USEDEFAULT, WinApi.CW_USEDEFAULT,
                                          0, 0, instance, 0);
      res := WinApi.ShowWindow(mainWnd, WinApi.SW_SHOWDEFAULT);
      res := WinApi.UpdateWindow(mainWnd);
   END OpenWindow;

   PROCEDURE MainLoop;
      VAR msg: WinApi.MSG; res: INTEGER;
   BEGIN
      WHILE WinApi.GetMessage(msg, 0, 0, 0) # 0 DO
         res := WinApi.TranslateMessage(msg);
         res := WinApi.DispatchMessage(msg);
      END;
      WinApi.ExitProcess(msg.wParam)
   END MainLoop;
   
   PROCEDURE Test;
   VAR
      s: POINTER TO ARRAY OF CHAR;
   BEGIN
      NEW(s, 131055);
   END Test;

BEGIN
   instance := WinApi.GetModuleHandle(NIL);
   OpenWindow;
   Test;
   MainLoop
END MySimple.


Добавил процедуру Test. Собрал exe файл при помощи команды:
DevLinker.LinkExe MySimple.exe := Kernel+ MySimple 1 applogo.Ico ~

При запуске программы возникает ошибка:
---------------------------
BlackBox
---------------------------
illegal memory read [ad = 00000000]
- Kernel.CheckCandidates (pc=00002202, fp=0022FF0C)
- Kernel.MarkLocals (pc=000023F7, fp=0022FF28)
- Kernel.FastCollect (pc=000028E4, fp=0022FF38)
- Kernel.NewBlock (pc=00002BDD, fp=0022FF5C)
- Kernel.NewArr (pc=00000CD9, fp=0022FF88)
- MySimple.Test (pc=000001FD, fp=0022FFA0)
- MySimple.$$ (pc=0000001B, fp=0022FFB0)
---------------------------
OK
---------------------------

Если 131055 уменьшить хотя бы на 1, то ошибка не возникает.

Кто-нибудь знает в чем может быть дело?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Воскресенье, 01 Ноябрь, 2009 22:32 

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 7681
Откуда: Троицк, Москва
Rifat писал(а):
Если 131055 уменьшить хотя бы на 1, то ошибка не возникает.

Кто-нибудь знает в чем может быть дело?
Может быть в том, что 131055 * 2 это очень близко к 256К :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Воскресенье, 01 Ноябрь, 2009 22:43 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 588
Откуда: Казань
Цитата:
Может быть в том, что 131055 * 2 это очень близко к 256К :)


При работе из под Блэкбокса можно выделить память гораздо большего размера, порядка сотен мегабайт и больше. Почему же собранное приложение не может выделить памяти больше 256К ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Воскресенье, 01 Ноябрь, 2009 23:19 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 8825
Откуда: Россия, Орёл
А какой ББ?

Что-то у меня на 1.5-м по адресу pc=00002202 совсем другая процедура (CheckFinalizers). (для расрутки адреса использую приладу, сделанную из DevDebug.ShowSourcePos).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Воскресенье, 01 Ноябрь, 2009 23:25 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 588
Откуда: Казань
Проверял на BlackBox 1.6 rc6.
На BlackBox 1.5 возникает следующая ошибка:
---------------------------
BlackBox
---------------------------
illegal memory read [ad = 00000000]
- Kernel.CheckCandidates (pc=00001F41, fp=0022FF0C)
- Kernel.MarkLocals (pc=00002136, fp=0022FF28)
- Kernel.FastCollect (pc=0000260E, fp=0022FF38)
- Kernel.NewBlock (pc=000028ED, fp=0022FF5C)
- Kernel.NewArr (pc=00000C9D, fp=0022FF88)
- MySimple.Test (pc=000001FD, fp=0022FFA0)
- MySimple.$$ (pc=0000001B, fp=0022FFB0)
---------------------------
OK
---------------------------
Ошибка та же, а адреса другие.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Воскресенье, 01 Ноябрь, 2009 23:41 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 8825
Откуда: Россия, Орёл
Попробуйте не LinkExe, а Link.

Включить Kernel, HostFiles, StdLoader.

А в Init записать эту программу. (его StdLoader затянет динамически). Что будет?

(самому некогда сейчас)

При линковке ББ в режиме динамической загрузки по-другому идёт инициализация. Не помню, может или нет быть такая проблема с виндовским EXE-шником, но с линуксовым DLL-шником мы такую поимели (Линукс инициализирует загружаемый DLL одним потоком, а выполнять начинает другим - стеки разные).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Понедельник, 02 Ноябрь, 2009 00:00 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 588
Откуда: Казань
Илья Ермаков писал(а):
Попробуйте не LinkExe, а Link.

Включить Kernel, HostFiles, StdLoader.

А в Init записать эту программу. (его StdLoader затянет динамически). Что будет?


LinkExe и Link вроде бы роли не играет, и так и так ошибка возникает.

Попробовал сделать как Вы сказали:
1) Переименовал MySimple в Init
2) Добавил модули в команду линковки
DevLinker.LinkExe MySimple.exe := Kernel+ Files HostFiles StdLoader Init 1 applogo.Ico ~

После чего ошибка перестала появляться. Видимо HostFiles или StdLoader каким-то образом инициализируют Kernel, что после этого, все нормально работает.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Понедельник, 02 Ноябрь, 2009 00:16 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 588
Откуда: Казань
Нашел минимальное изменение, после которого ошибка исчезает.
Добавил тип dummy и вызвал New для этого типа.
Код:
MODULE Init;
(* simple windows application *)

   IMPORT S := SYSTEM, WinApi;

   CONST
      message = "Hello World";
      iconId = 1;
      
   TYPE
      dummy = POINTER TO RECORD END;

   VAR
      instance: WinApi.HINSTANCE;
      mainWnd: WinApi.HWND;

   PROCEDURE WndHandler (wnd, msg, wParam, lParam: INTEGER): INTEGER;
      VAR res: INTEGER; ps: WinApi.PAINTSTRUCT; dc: WinApi.HDC;
   BEGIN
      IF msg = WinApi.WM_DESTROY THEN
         WinApi.PostQuitMessage(0)
      ELSIF msg = WinApi.WM_PAINT THEN
         dc := WinApi.BeginPaint(wnd, ps);
         res := WinApi.TextOut(dc, 50, 50, message, LEN(message));
         res := WinApi.EndPaint(wnd, ps)
      ELSIF msg = WinApi.WM_CHAR THEN
         res := WinApi.Beep(800, 200)
      ELSE
         RETURN WinApi.DefWindowProc(wnd, msg, wParam, lParam)
      END;
      RETURN 0
   END WndHandler;

   PROCEDURE OpenWindow;
      VAR class: WinApi.WNDCLASS; res: INTEGER;
   BEGIN
      class.hCursor := WinApi.LoadCursor(0, S.VAL(WinApi.PtrSTR,
                                                         WinApi.IDC_ARROW));
      class.hIcon := WinApi.LoadIcon(instance, S.VAL(WinApi.PtrSTR, iconId));
      class.lpszMenuName := NIL;
      class.lpszClassName := "Simple";
      class.hbrBackground := WinApi.GetStockObject(WinApi.WHITE_BRUSH);
      class.style := WinApi.CS_VREDRAW + WinApi.CS_HREDRAW
                  (* + WinApi.CS_OWNDC + WinApi.CS_PARENTDC *);
      class.hInstance := instance;
      class.lpfnWndProc := WndHandler;
      class.cbClsExtra := 0;
      class.cbWndExtra := 0;
      res := WinApi.RegisterClass(class);
      mainWnd := WinApi.CreateWindowEx({}, "Simple", "Simple Application",
                                          WinApi.WS_OVERLAPPEDWINDOW,
                                          WinApi.CW_USEDEFAULT, WinApi.CW_USEDEFAULT,
                                          WinApi.CW_USEDEFAULT, WinApi.CW_USEDEFAULT,
                                          0, 0, instance, 0);
      res := WinApi.ShowWindow(mainWnd, WinApi.SW_SHOWDEFAULT);
      res := WinApi.UpdateWindow(mainWnd);
   END OpenWindow;

   PROCEDURE MainLoop;
      VAR msg: WinApi.MSG; res: INTEGER;
   BEGIN
      WHILE WinApi.GetMessage(msg, 0, 0, 0) # 0 DO
         res := WinApi.TranslateMessage(msg);
         res := WinApi.DispatchMessage(msg);
      END;
      WinApi.ExitProcess(msg.wParam)
   END MainLoop;
   
   PROCEDURE Test;
   VAR
      s: POINTER TO ARRAY OF CHAR;
      d: dummy;
   BEGIN
      NEW(d);
      NEW(s, 131055);
   END Test;

BEGIN
   OpenWindow;
   Test;
   MainLoop
END Init.


Команда линковки (* Init обратно в MySimple не стал переименовывать *):
DevLinker.LinkExe MySimple.exe := Kernel+ Init 1 applogo.Ico ~

После чего все заработало. Видимо первым должен вызываться простой New, чтобы что-то корректно проинициализировалось, а New для массивов первым вызваться не может. У меня такое предположение.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Пятница, 12 Март, 2010 20:14 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1157
Откуда: Tel-Aviv
С опозданием, но всё же может быть полезным. :D

По-моему, ошибка закралась из-за того, что не импортирован модуль Kernel, при том, что используется процедура NEW.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Суббота, 30 Апрель, 2011 23:00 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 1922
Откуда: Красноярск
Rifat писал(а):
Видимо первым должен вызываться простой New, чтобы что-то корректно проинициализировалось, а New для массивов первым вызваться не может. У меня такое предположение.

Большое спасибо за ваши эксперименты, помогли сэкономить много нервов и времени!

Прилагаю свой вычищеный от лишних строк пример, тип для инициализации создавать не обязательно, можно просто создать переменную, интересно, что при 7000 все работает без этой инициализации:
Код:
MODULE OglLessonBall;

   TYPE
      Vector = ARRAY 3 OF REAL;
      Ball = RECORD
         pos: Vector;
         r: REAL;
         active: BOOLEAN;
      END;

   VAR
   starter: POINTER TO RECORD END;
      system: POINTER TO ARRAY OF Ball;

   PROCEDURE Main;
   BEGIN
      NEW(system, 14000);
   END Main;
BEGIN
   NEW(starter);
   Main;
END OglLessonBall.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с выделением памяти
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 20:31 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 104
Откуда: г. Рига, Латвийская ССР
У меня возникает похожая ошибка. Во всяком случае, когда я добавляю в разные места программы следующий код, ошибка исчезает или перебегает на другое место:
Код:
TYPE T = POINTER TO RECORD END;
VAR t: T;
BEGIN
  NEW(t);

Ошибка возникает в Линуксовской версии Блэкбокса («BlackBox-Freenix») http://gitlab.molpit.org/oberon/blackbox-freenix. Я уже изложил её суть в другой ветке форума (http://forum.oberoncore.ru/viewtopic.php?f=29&t=5664#p95476). Привожу это сообщение ниже:
kekc_leader писал(а):
У меня с этим SDL_RectFill какая-то чертовщина происходит. Он то работает, то нет. Сейчас перестал совсем.
Точнее, на Виндоусе всё работает, а на Линуксовской сборке Блэкбокса - нет. Выдаёт NIL dereference или вот такой трап:
Код:
illegal memory read (ad = B6......)
08X

<system> (pc=B5......, fp=BF......)
<system> (pc=00000009H, fp=0000000AH)
Происходит это на следующей строке:
Код:
IF SDL.FillRect(s, rr, G.MakeCol(255, 0, 0)) = 0 THEN END;
s - это SDL.Surface (указатель), rr - это SDL.Rect (не указатель)...
Я в тупике. На Виндоусе всё работает прекрасно, а на Линуксе вот такая ошибка и хоть убей.

Прилагаю компоненты к сообщению. Их два:
1) Graph (внутри: Sdl.odc и Lib.odc; Lib использует Sdl) и
2) SDLTest (внутри файл SDLTest.odc; использует GraphLib и GraphSdl).
Линуксовская и Виндоуская версия отличаются только в одном месте - разными ссылками на DLL/SO:
Код:
MODULE GraphSdl ["libSDL2.so"];
MODULE GraphSdl ["SDL2.dll"];

Ещё добавлю, что Виндоусскую версию я тестирую через виртуальную машину, а в ней флаг rendererAccelerated при создании прорисовщика приводит к краху программы, поэтому я его заменяю на rendererSoftware. На Линуксовской версии Блэкбокса - наоборот, renderAccelerated может работать в тех случаях, когда renderSoftware выдаёт ошибку.

Иван Денисов предположил, что проблема в Линуксовской версии SDL2, но я проверял, это не так.


Вложения:
Комментарий к файлу: odc-файлы - компоненты Graph (GraphSdl и GraphLib) и SDLTest.
Components.zip [14.29 КБ]
Скачиваний: 46
Комментарий к файлу: SDL2.dll - положить в каталог с Блэкбоксом
SDL2.zip [377.36 КБ]
Скачиваний: 47
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 

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


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

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


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

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