Коментари

Копиране на връзка Цитирайте отговор

сегментирането

язд коментира 17 януари 2014 г.

Получих тази грешка при сегментирането при изобразяване на шаблон за диета.

Грешката е възпроизводима всеки път.
Докато се опитвах да го отстраня, регистрирах променливите в AllocAppender put (). И въпреки че m_remaining отчете достатъчно място, достъпът до него създаде segfault.

язд коментира 17 януари 2014 г.

По-нататъшно тестване показва, че m_data сам по себе си е недостъпен.

язд коментира 18 януари 2014 г.

Използването на VibeManualMemoryManagement, по подразбиране не се появява.

etcimon коментира 18 януари 2014 г.

Имах проблеми и с GC режим, мисля, че паметта на vibe трябва да се управлява ръчно по подразбиране.

язд коментира 29 януари 2014 г.

Ще затворя този въпрос, тъй като очевидно е лош доклад без възпроизводим случай.
Ако дойда с малък възпроизводим калъф, ще отворя отново това.

yebblies коментира 1 май 2014г

Мисля, че току-що ударих тази грешка - получих segfault в memcpy и счупена стека.

За съжаление приложението е с затворен код и сривът се е случил само след

Заобиколното решение на VibeManualMemoryManagement изглежда го поправя и за мен.

s-ludwig коментира 12 май 2014г

luismarques коментира 12 май 2014г

@yazd Не разбирам, в първия пост казахте "Грешката е възпроизводима всеки път"; защо това беше закрито по-късно като „лош доклад без възпроизводим случай“? В моя случай, който @ s-ludwig споменава, грешката не може да се възпроизведе детерминирано, така че ако имате детерминиран пример за споделяне, би помогнало.

язд коментира 12 май 2014г

Първоначално беше възпроизводимо за мен, но не беше минимален тест. Смених някои неща и заработи и загубих делото. Ще се опитам да се върна към този проект и да възпроизведа проблема отново. Мисля, че си струва няколко часа от времето ми.

etcimon коментира 12 май 2014г

@luismarques имали ли сте ръчно управление на паметта, когато е възникнала тази грешка?

язд коментира 12 май 2014г

Не, с ръчната версия за управление на паметта всичко работеше правилно.
Редактиране: Опс, току-що забелязах, че въпросът е за luismarques.

etcimon коментира 12 май 2014г

Имах много проблеми без ръчно управление на паметта, затова все още твърдя, че трябва да е включено по подразбиране.

s-ludwig коментира 12 май 2014г

Имах много проблеми без ръчно управление на паметта, затова все още твърдя, че трябва да е включено по подразбиране.

Това е опасно (т.е. не @safe)! Използването на която и да е памет на HTTPServerRequest извън манипулатора на заявки ще доведе до повреда на паметта (напр. Използването на параметър на заявката като AA ключ е достатъчно за това)! Добавянето на обхват към параметрите req/res би било най-малкото, което е необходимо, преди това да може да се счита за настройка по подразбиране. Но това е малко трудно от гледна точка на осигуряването на път за отказ.

На други езици това не би било наистина забележително (особено C и частично C ++), но за D е нещо като норма, че не можете да направите много грешки по отношение на повреда на паметта поради GC, така че това е нещо неочаквано.

etcimon коментира 12 май 2014г

не можете да направите много грешки по отношение на повреда на паметта поради GC, така че това е нещо неочаквано.

Това е смешно, защото мислех, че vibe.utils.memory е настроен за ръчно управление на повечето неща, въпреки че USE_GC е настроен на true.

luismarques коментира 12 май 2014г

@etcimon: Използвам автоматичното управление на паметта по подразбиране.

s-ludwig коментира 12 май 2014г

Да, но HTTP сървърът използва defaultAllocator (), който е чист GC базиран разпределител, ако ръчното управление на паметта не е активирано. manualAllocator () се използва най-вече за вътрешни неща, които не са част от API.

etcimon коментира 12 май 2014г

И така . само едно бързо предположение тук, за да практикувам моите vibe умения, но дали тези случаи на употреба не се отнасят главно до байтове, получени от TCP връзка? Това би било в кръговия буфер и нарушаването на достъпа означава, че кръговият буфер е събран от GC, да?

редактиране: Nvm, което не би било възможно, защото TCPConnection.read (dst) копира данните от буфера

s-ludwig коментира 16 май 2014г

Току-що претърпях срив (невалиден пиши достъп) на това място, което е било възпроизводимо на 100%. След промяна на използването на GC.realloc на GC.extend, сривът изчезна. Така че или правех нещо нередно с GC.realloc, или там има но (или има някаква неясна корупция на купчина, но дано не.).

язд коментира 16 май 2014г

Не успях да възпроизведа случая си, но за щастие вие ​​бяхте. Надяваме се, че това ще го поправи.

s-ludwig коментира 16 май 2014г

Друго емпирично доказателство: Току-що открих, че уебсайтът на vibed.org често се срива поради обща повреда в защитата, но спрях да го правя, откакто възстанових версията с "фиксирана" vibe.d. Така че не е гарантирано, че GPF е причинен от този проблем тук, но поне изглежда вероятно.

s-ludwig коментира 19 май 2014г

Затваряне, докато не се появят нови доказателства. Процесът на vibed.org вече не се срива, тъй като корекцията е включена (работи вече 3 дни).

etcimon коментира 20 май 2014г

Това означава, че GC.realloc може да доведе до повреда на паметта в други случаи на употреба, като асоциативни масиви? Мисля, че това може да е и причината да прибягвате до "магически числа", нали?

etcimon коментира 20 май 2014г

Добре, намерих няколко огромни грешки в рутината на GC.realloc

Очевидно updateCaches се използва в exte и realloc за кеширане на размера на новото разпределение, защото ускорява метода findSize. Обаче никъде не може да се намери в един конкретен клон на метода realloc (когато предишният размер е по-малък от размера на страницата, т.е. 4096 байта)
https://github.com/D-Programming-Language/druntime/blob/master/src/gc/gc.d#L679

Така че, ако направите следното, трябва да получите нарушение на достъпа до запис:
1- Разпределете 2048 байта
2- Преразпределете на нещо по-малко от 1024 байта
3- Преразпределете отново до 2048 байта

Разпределението на 2048 байта ще бъде игнорирано, защото realloc смята, че psize е 2048 байта. Всичко, което е следвало тази логика, ще завърши с нарушение на достъпа до запис. (Ако приемем, че между тях не се е случило друго преразпределение.)

. И ако старите и новите размери на разпределение са по-големи от страница (4096 байта) и последователните блокове от страници не са намерени в таблицата на страниците, тя също пропуска актуализацията на кеша, като преминава по същия маршрут на malloc, както е посочено по-горе

Това също ще предотврати освобождаването на страници и ще доведе до изтичане на памет в GC, което съм изпитвал! (най-накрая го намерих!)