−54
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
fstream:=tstreamex.Create(signaturepath,fmShareDenyWrite);
FLock.Enter;
try
while not fstream.EOS do
begin
obj:=tsignature.create;
try
obj.AddingDate:=fstream.ReadDate;
obj.Comment:=fstream.ReadString;
fstream.ReadBuffer(Len, SizeOf(Len));
obj.MStream.SetSize(len);
fstream.ReadBuffer(obj.mstream.memory^, len);
fsignlist.Add(obj);
except
obj.Free;
raise esignatureloadingerror.Create('Signature read error');
end;
Стрим читает из файла сохраненный объект. К сожалению, подобный подход используется даже в серьезных коммерческих проеках, это классика.
Если что-то поменять в файле хоть на 1 байт, стрим промахнётся мимо поля - прога либо съест всю доступную системную память либо обрушится с Access Violation.
В любом случае, память будет испорчена, и дальнейшее выполнение программы чревато UB.
Кстати, а не грозит ли юзание структур порчей памяти? Допустим, хотим определить валидность заголовка, загружаем структуру, а в файле - трешак.
Не будет ли обращения по ложному адресу? UB?
Запостил:
voodoodal16,
24 Сентября 2016
Увижу при встрече, сыпану в глаза тебе горчичный порошок. Пока ты корчишься от боли, я привяжу тебя чтоб не дергался. Досыплю порошка в глаза и перемешаю в глазницах. Возьму связку сосисок и выебу тебя, как анальными бусами. Дальше взглотнешь 2 литра колы и насильно засуну в тебя ментос, чтоб твое ебало посинело. Пока ты синеешь и кричишь (От удовольствия или боли?), вспорю пузо и толстую кишку и вытощу ту связку сосисок с говном, намажу тем самой глазной горчицей и засуну в тебя. Возможно тебя вырвет, но советую этого не делать.
Этот смайл ступорит меня.
писать на дельфях в 2016м это самая что ни на есть анскилябрщина
Настоящая анскилябрщина - считать что год написания имеет какое-то отношение к анскилябрщине.
Вы словно голуби: только "курлы-мурлы", а пользы - 0. Только белье на веревке пачкаете.
http://govnokod.ru/20875
Не будет ли обращения по ложному адресу? UB?
Э, да ты совсем нуб что ли. Если размер файла меньше размера структуры то прочитать не удастся, будет исключение. А если больше - все поля прочитаются. Ну да, в полях может быть мусор, на то он и заголовок что надо будет сигнатуры сравнить, но откуда там ложные адреса и UB?
Если вылетело исключение - разве сие не знак того, что испорчена память? Вдруг код затёр служебные заголовки? Мусор в полях - тоже UB, как мне кажется.
Ну тогда при объявлении любой локальной переменной происходит UB. Это уже потом мы присваиваем ей значение, а до этой строчки с присвоением - полнейшее UB.
Поэтому и советуют инициализировать переменную сразу в объявлении.
Ну типа
char *foo;
*(foo) = 1; //превратились в кирпич или сожгли оборудование
Ну MMIO тебе ось в адресное пространство не замапает просто так. А вот если без оси...
Кстати!! Расскажи мне как работает MMIO и DMA при наличии MMU?
Драйвер как-то умно читает таблицы странц и вычисляет настоящий адрес?
Да там у ядер специальные апишки для трансляции адресов есть, чтобы драйверы не заморачивались. Типа "выдели мне непрерывный кусок физической памяти чтобы до него могла дотянуться вот эта железка и дай адрес, который можно ей скормить" или "замапай мне mmio адреса вот этой железки". И дальше там ядро настраивает все кеши, смещения на мостах, IOMMU если есть и т.п.
Типа драйвер просит у ядра буфер, и скармиливает его адрес DMAшке на борту карты, и карта туда пишет-пишет и потом делает interrupt?
а MMIO как?
Ну вот сидит карта на шине и слушает адреса с FOO по BAR.
Если я сделаю mov [FOO], 42 то FOO через MMU преврарится в черте-чо. Как же драйвер умеет записать ИМЕННО в FOO?
вот я в глаза долблюсь
теперь понятно
типа я говорю едру "пиши по адресу 0x1234", а оно само через таблицы высчитывает реальный адрес
да?
иными словами процессор ВСЕГДА обращение к памяти прогоняет через MMU, но ядро настраивает таблицы так, что MMU мапит такие обращения не абы-куда а в нужное место.
ужасная жесть этот ваш протектед мод
то-ли дело дос:
Так точно.
> ужасная жесть этот ваш протектед мод
Запили свою 64-битную ось с маппингом 1:1 :)
Программ-то больше чем одна)
Ну сделай почти-однозадачную, как DOS.
З.Ы. Первые iOS'ы вроде тоже как китайские телефоны были - в фоне только плейер да будильник. И ничё, пипл хавал...
Вполне себе многозадачненько! Причем если запрограммировать таймеры (там же их было два вроде) то чем не многозадачность?;)
Причем не было гонок, не нужно было делать fence потому что DOS не умел более одного CPU (да?).
у iOS это связано с желанием не тратить батарейку на всяких пидарасов. Технически Darwin @ XNU вполне себе многозадачна, как ты понимаешь:)
Кстати говоря даже сейчас чтобы что-то делать в офне нужно это явно попросить (через plist) и список дел крайне ограничен) Тебя либо "иногда будут будить", либо разрешат быть всегда в фоне если ты плеер или навигатор.
Ну то-есть нельзя невозбранно простые числа искать за счет пользователя в фоне. А в ондроиде можно)
Если есть право на wake lock. Иначе телефон всё-таки забьёт и уснёт.
но сервис-то можно сделать
Один хуй засыпает... Без wake lock у меня не получалось нормально дёргать странички с ГК. Сервис просыпался только с какими-нибудь гугловскими прогами или когда экран включал... Алармы тоже не особо помогают без лока, чуть управление вернёшь - сразу в сон.
ты можешь поклянчить еще, но не факт что дадут
Так что даже если телефон не спит, то тебя могут выкинуть нахуй (если памяти мало) и фиг ты чего сделаешь
Ну это и на андроиде так. Не дрючить же флешку свопом.
https://developer.android.com/guide/components/services.html
А в ios у тебя такого понятия нет. Ты можешь только попросить будить тебя _иногда_.
Ну либо ты особенный (например, плеер)
https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
Ну и как их проверить? Ведь в любом случае будет утечка памяти.
Написание "нормального" сериализатора/десиализатора — задача сама по себе нетривиальная, особенно, если нужно энкодить указатели.
Какую именно проблему решаем-то?
Если хочется не читать гигабайты при случайных повреждениях — добавляем чексуммы + проверяем, что размеры буферов адекватные.
Когда я пилил специализированную штуку для хранения на диске, я вообще ничего в память не копировал: хранил файлы так, чтобы их можно было mmap-ить в память + использовал чексуммы для проверки записей.
Правда, была завязка на 64-разрядные системы — файлы были большие.
Это ещё до яндекса было, но в яндексе тоже любят mmap.
Не столько из-за выигрыша пирфоманса на копировании (который не такой уж и большой, кстати), сколько из возможности быстро начать обрабатывать запросы, не дожидаясь, пока распарсится в память здоровенный индекс.
Я даже больше тебе скажу. При передачи из ядра в память приложения - они копируются ещё раз. С винта читается в буфер через DMA, а он может работать только с данными выравненными на границу параграфа. Да и не гоже читать в чужую память, ибо глядишь пока драйвер "дмашкой" будет выжидать раскручивания цилиндров винта и затем хреначить в буфер юзера - процесс за это время успеет повалится. Так что сначала хуярят в страницу в кернелспейсе, а потом в страницу юзерспейса уже перекопирывают. А там ещё всякие промежуточные менеджеры есть в оси в стеке драйверов, которым нужно поснифать твои буфера для каспера например или что-то ещё сделать, так что и там все копируется в очередной раз. Так что не так страшно будет пару копирований или десятка. С винта все равно на много порядков медленне поднимается. Ну а так да, если мапиш память - там групка страниц сразу переписывается с винта, а потом без копирований эта групка страниц просто ремапится изкернелспейса драйвера в юзерспейс. В целом ммапингчтение обычно медленне обычного чтения, так как префетча обычно нет или он работает адекватно только под некоторые применения в приложениях.
Шта? Я и сказал, что сначала кусок файла вычитывается в страницу пейджкеша, а потом копируется в юзерспейс. Где там "еще раз"?
А так нагрузка на системный своп сильно снижается с юзаньем мапинга, тк по сути замапленный файл становится свопфайлом и можно любую давно не юзанную страницу выгрузить, а вот если ты себе закопировал обычным ридом в буфер приложухи в хип - тут этот буфер только в основной системный своп отправлять, которого может и не хватить
> Я не втыкаю
А я зато втыкнул защеку, проверь
> Я не втыкаю
Да не страшно.
Я это к тому, что копирований больше чем ты думаешь и это на перформанс не особо то влияет из-за латентности винта
Ты же сам сказал что ты думаешь. Или ты говоришь не то, что думаешь? Или ты говоришь не думая?
У обычного рида тоже плюсы свои есть. У него больше троугхпут и лучше работа кешера с точки зрения кешмисов, чем у ммапа, так что ещё бабушка на двое сказала, что лучше для конкретной ситуации. Не чего думать категорями царских оптимизаций экономий на спичках
Покайся, покайся!..
>>Если хочется не читать гигабайты при случайных повреждениях — добавляем чексуммы + проверяем, что размеры буферов адекватные.
У меня так сделано, но почему-то это показалось мне хаком. Оказывается, не ламерство.
BagorCtretora,
huesto,
guestinho,
CrashTesterAnusov,
bagor,
barop
- попадают в список свитка-минусатора. Вы для меня больше не существуете. Прощайте.
Очень сильно рискуешь, за нами большая армия ботов.
Надеюсь, в виме сидишь, не правишь в ide повторяющиеся строки руками?
ахахахаха
и в нотпаде тоже, ага
чтобы копипаст не стал проблемой