OberonCore https://forum.oberoncore.ru/ |
|
Проблема с выделением памяти https://forum.oberoncore.ru/viewtopic.php?f=2&t=2001 |
Страница 1 из 1 |
Автор: | Rifat [ Воскресенье, 01 Ноябрь, 2009 22:12 ] |
Заголовок сообщения: | Проблема с выделением памяти |
Взял за основу пример из 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, то ошибка не возникает. Кто-нибудь знает в чем может быть дело? |
Автор: | Info21 [ Воскресенье, 01 Ноябрь, 2009 22:32 ] |
Заголовок сообщения: | Re: Проблема с выделением памяти |
Rifat писал(а): Если 131055 уменьшить хотя бы на 1, то ошибка не возникает. Может быть в том, что 131055 * 2 это очень близко к 256К
Кто-нибудь знает в чем может быть дело? |
Автор: | Rifat [ Воскресенье, 01 Ноябрь, 2009 22:43 ] |
Заголовок сообщения: | Re: Проблема с выделением памяти |
Цитата: Может быть в том, что 131055 * 2 это очень близко к 256К При работе из под Блэкбокса можно выделить память гораздо большего размера, порядка сотен мегабайт и больше. Почему же собранное приложение не может выделить памяти больше 256К ? |
Автор: | Илья Ермаков [ Воскресенье, 01 Ноябрь, 2009 23:19 ] |
Заголовок сообщения: | Re: Проблема с выделением памяти |
А какой ББ? Что-то у меня на 1.5-м по адресу pc=00002202 совсем другая процедура (CheckFinalizers). (для расрутки адреса использую приладу, сделанную из DevDebug.ShowSourcePos). |
Автор: | Rifat [ Воскресенье, 01 Ноябрь, 2009 23:25 ] |
Заголовок сообщения: | Re: Проблема с выделением памяти |
Проверял на 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 --------------------------- Ошибка та же, а адреса другие. |
Автор: | Илья Ермаков [ Воскресенье, 01 Ноябрь, 2009 23:41 ] |
Заголовок сообщения: | Re: Проблема с выделением памяти |
Попробуйте не LinkExe, а Link. Включить Kernel, HostFiles, StdLoader. А в Init записать эту программу. (его StdLoader затянет динамически). Что будет? (самому некогда сейчас) При линковке ББ в режиме динамической загрузки по-другому идёт инициализация. Не помню, может или нет быть такая проблема с виндовским EXE-шником, но с линуксовым DLL-шником мы такую поимели (Линукс инициализирует загружаемый DLL одним потоком, а выполнять начинает другим - стеки разные). |
Автор: | Rifat [ Понедельник, 02 Ноябрь, 2009 00:00 ] |
Заголовок сообщения: | Re: Проблема с выделением памяти |
Илья Ермаков писал(а): Попробуйте не 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, что после этого, все нормально работает. |
Автор: | Rifat [ Понедельник, 02 Ноябрь, 2009 00:16 ] |
Заголовок сообщения: | Re: Проблема с выделением памяти |
Нашел минимальное изменение, после которого ошибка исчезает. Добавил тип 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 для массивов первым вызваться не может. У меня такое предположение. |
Автор: | Роман М. [ Пятница, 12 Март, 2010 20:14 ] |
Заголовок сообщения: | Re: Проблема с выделением памяти |
С опозданием, но всё же может быть полезным. По-моему, ошибка закралась из-за того, что не импортирован модуль Kernel, при том, что используется процедура NEW. |
Автор: | Иван Денисов [ Суббота, 30 Апрель, 2011 23:00 ] |
Заголовок сообщения: | Re: Проблема с выделением памяти |
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. |
Автор: | kekc_leader [ Воскресенье, 10 Апрель, 2016 20:31 ] | |||
Заголовок сообщения: | Re: Проблема с выделением памяти | |||
У меня возникает похожая ошибка. Во всяком случае, когда я добавляю в разные места программы следующий код, ошибка исчезает или перебегает на другое место: Код: 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, но я проверял, это не так.
|
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |