Читать дальше →
Егор @Tujh
C & C++ Developer
+228
Here be dragons: Управление памятью в Windows как оно есть [1/3]
8 min
181K
Каталог:
Один
Два
Три
Менеджер памяти (и связанные с ним вопросы контроллера кеша, менеджера ввода/вывода и пр) — одна из вещей, в которой (наряду с медициной и политикой) «разбираются все». Но даже люди «изучившие винду досконально» нет-нет, да и начинают писать чепуху вроде (не говоря уже о другой чепухе, написанной там же):
Грамотная работа с памятью!!! За все время использования у меня своп файл не увеличился ни на Килобайт. По этому Фаерфокс с 10-20 окнами сворачивается / разворачивается в/из трея как пуля. Такого эффекта я на винде добивался с отключенным свопом и с переносом tmp файлов на RAM диск.
Или к примеру μTorrent — у меня нет никаких оснований сомневаться в компетентности его авторов, но вот про работу памяти в Windows они со всей очевидностью знают мало. Не забываем и товарищей, производящих софт для слежения за производительностью и не имеющих ни малейшего понятия об управлении памятью в Windows (и поднявших по этому поводу истерику на пол интернета, на Ars-е даже был разбор полетов). Но самое потрясающее, что я видел всвязи с управлением памятью — это совет переместить pagefile на RAM-диск:
Из моих трех гигабайт под RAM disk был выделен один (на тот момент, когда на лаптопе еще была установлена XP), на котором я создал своп на 768МБ ...
Цель данной статьи — не полное описание работы менеджера памяти (не хватит ни места ни опыта), а попытка пролить хоть немного света на темное царство мифов и суеверий, окружающих вопросы управления памятью в Windows.
+316
Альтернативные аллокаторы памяти
13 min
96KTranslation
Написал Стивен Тови в 2:29 утра по программированию (шутка юмора Google Translate)
Вступление от себя: эта заметка, прорекламированная Алёной C++, предназначена в основном разработчикам игр для консолей, но будет, наверное, полезна и всем, кому приходится сталкиваться с экстремальным аллоцированием динамической памяти. Возможно, любители посравнивать управление памятью в C++ и Java тоже найдут над чем задуматься.
Оригинал с небезынтересной дискуссией в комментариях: altdevblogaday.org/2011/02/12/alternatives-to-malloc-and-new
Обязательная вступительная басня
Мне очень нравятся суши. Это вкусно и удобно. Мне нравится, что можно с бухты-барахты, не тратя целый обеденный час, зайти в суши-ресторан с конвейером, занять место и взять что-то свежее и вкусное с ленты. Но при всём при этом, чего мне реально не хотелось бы, так это быть официантом в суши-ресторане, особенно если бы моей обязанностью было бы рассаживать посетителей по местам.
+69
Простая прокси-DLL своими руками
8 min
16KПонадобилось мне перехватывать вызовы GDS32.DLL. Решил написать прокси-dll.
Первое, что нам нужно — это получить список всех экспортируемых функций из настоящей dll.
Сделаем это следующим кодом:
Здесь трудностей вроде нет. Добираемся последовательно до таблицы экспорта (строка 19) указателей на массив имен(NamesCursor) и массива номеров(OrdinalCursor) и читаем функцию за функцией, имена и номера. Количество функций находится в поле NumberOfNames. Этот код был добыт на просторах интернета, потом доработан и упрощён.
Пишем исследовательский стенд
Первое, что нам нужно — это получить список всех экспортируемых функций из настоящей dll.
Сделаем это следующим кодом:
1. program GetFuncsDll;
2. {$APPTYPE CONSOLE}
3. uses Windows;
4. var
5. ImageBase: DWORD; //адрес образа dll
6. pNtHeaders: PImageNtHeaders; // PE заголовок dll
7. IED: PImageExportDirectory; // адрес таблицы экспорта
8. ExportAddr: TImageDataDirectory; // таблица экспорта
9. I: DWORD; // переменная для цикла
10. NamesCursor: PDWORD; // указатель на адрес имени функции
11. OrdinalCursor: PWORD; // указатель на адрес номера функции
12. LIB_NAME:AnsiString; // имя dll
13. BEGIN
14. LIB_NAME:='MiniLib.dll';
15. loadlibraryA(PAnsiChar(LIB_NAME));
16. ImageBase := GetModuleHandleA(PAnsiChar(LIB_NAME));
17. pNtHeaders := Pointer(ImageBase + DWORD(PImageDosHeader(ImageBase)^._lfanew));
18. ExportAddr := pNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
19. IED := PImageExportDirectory(ImageBase+ExportAddr.VirtualAddress);
20. NamesCursor := Pointer(ImageBase + DWORD(IED^.AddressOfNames));
21. OrdinalCursor := Pointer(ImageBase + DWORD(IED^.AddressOfNameOrdinals));
22. For I:=0 to Integer(IED^.NumberOfNames-1) do begin
23. WriteLn(output,PAnsiChar(ImageBase + PDWORD(NamesCursor)^),'=',OrdinalCursor^ + IED^.Base);
24. Inc(NamesCursor);
25. Inc(OrdinalCursor);
26. end;
27. Readln;
28. end.
Листинг 1
Здесь трудностей вроде нет. Добираемся последовательно до таблицы экспорта (строка 19) указателей на массив имен(NamesCursor) и массива номеров(OrdinalCursor) и читаем функцию за функцией, имена и номера. Количество функций находится в поле NumberOfNames. Этот код был добыт на просторах интернета, потом доработан и упрощён.
+14
Реализация разделяемой памяти между драйвером и приложением
6 min
10KTutorial

Приветствую всех!
В этой небольшой статье речь пойдет об одном способе создания разделяемой памяти, к которой можно будет обращаться как из режима ядра, так и из пользовательского режима. Приведу примеры функций выделения и освобождения памяти, а также будут ссылки на исходники, чтобы можно было попробовать любому желающему.
+37
Вычисление CRC32 строк в compile-time
5 min
19K
Локализация здесь осуществляется довольно нехитро. Все строки, требующие перевода, оборачиваются в макрос
_TR()
:wprintf(L"%s\n", _TR("Some translating string"));
Макрос возвращает нужную версию текста в зависимости от текущего используемого языка. Определён он следующим образом:
#define _TR(x) g_Translator.Translate(x)
Здесь происходит обращение к глобальному объекту
g_Translator
, который в функции Translate()
считает в рантайме crc32 от указанной строки, ищет в своей xml-базе перевод с совпадающей контрольной суммой и возвращает его.Не буду судить насколько такое решение оправдано, но оно проверено временем и показало себя достаточно надёжным. И всё бы ничего, но такое решение не лишено недостатков: по сути, функция делает лишнюю работу — контрольные суммы можно было бы подсчитать один раз на этапе компиляции, и использовать в дальнейшем уже готовые числовые значения. Это также избавило бы от необходимости хранить в исполняемом образе дублирующиеся строки, ведь они уже есть во внешнем xml-файле с переводами.
Немного погуглив по запросу «compile-time crc32» я быстро понял, что задача это не самая тривиальная, а готовых решений мне найти так и не удалось.
+46
Многозадачность в микроконтроллерах на основе продолжений
8 min
27KПрограммисты C и так не избалованы возможностями языка, а разработчики встроенных систем на микроконтроллерах ограничены еще больше, зачастую их программы работают на голом железе, без поддержки ОС.
Возможность использования в С сопрограмм, генераторов, кооперативной многозадачности часто может сильно упростить программу и сэкономить силы, но эти возможности языка не очевидны и многие про них не знают.
Продолжения (contionuation) позволяют запомнить состояние выполнения программного потока (функции), и вернуться к этому месту в дальнейшем.
Используя продолжения, мы можем получить сопрограммы (coroutine), а это уже практически готовые генераторы, итераторы и кооперативная многозадачность.
Возможность использования в С сопрограмм, генераторов, кооперативной многозадачности часто может сильно упростить программу и сэкономить силы, но эти возможности языка не очевидны и многие про них не знают.
Продолжения (contionuation) позволяют запомнить состояние выполнения программного потока (функции), и вернуться к этому месту в дальнейшем.
Используя продолжения, мы можем получить сопрограммы (coroutine), а это уже практически готовые генераторы, итераторы и кооперативная многозадачность.
+65
Самый правильный безопасный printf
8 min
12KПод катом Вас ждет увлекательная история о том, как я сильно расстроился, познакомившись поближе с пользовательскими литералами (с нового стандарта), но при этом в последствии все же реализовал вышеупомянутую функцию, а также разобрался с constexpr, а позже еще и реабилитировал те самые литералы.
+56
Создание msi-пакетов и установка любого ПО средствами групповых политик Windows
4 min
291KTutorial
Доброго времени суток, Хабр! Хочу представить интересный, по моему мнению, способ создания msi-инсталляторов для любого программного обеспечения и, как следствие, развертывание его средствами GPO. Подчеркну, что описанный метод не подразумевает создание «слепков» системы, а использует нативные инсталляторы софта, при чем для создания msi применяются только бесплатные для коммерческого использования продукты.
+19
Практика работы с сигналами
6 min
113KХочу запечатлеть небольшой опыт работы с сигналами в Linux. Ниже будут представлены примеры использования наиболее значимых конструкций в этой области. Постараюсь разложить все по отдельным полочкам, чтобы всегда было легко глянуть и вспомнить, что и как использовать.
+51
Организация рабочих потоков: синхронизационный канал
7 min
9.4KПредставьте себе архитектуру типичного приложения:
Есть рабочий поток движка, выполняющий какую-то функциональность, допустим копирование файлов (архивирование, поиск простых чисел). В общем что-то длительное.
Данный поток должен периодически сообщать информацию о текущем копируемом файле, а также уметь обрабатывать ошибки, допустим ошибка нехватки места на диске.
Графический интерфейс такого приложения должен позволять запускать процесс копирования файлов, уметь приостановить копирование, а также, в случае ошибки, отобразить соответствующий диалог с вопросом к пользователю.
Казалось бы, как можно допустить ошибку в такой простой ситуации?
Есть рабочий поток движка, выполняющий какую-то функциональность, допустим копирование файлов (архивирование, поиск простых чисел). В общем что-то длительное.
Данный поток должен периодически сообщать информацию о текущем копируемом файле, а также уметь обрабатывать ошибки, допустим ошибка нехватки места на диске.
Графический интерфейс такого приложения должен позволять запускать процесс копирования файлов, уметь приостановить копирование, а также, в случае ошибки, отобразить соответствующий диалог с вопросом к пользователю.
Казалось бы, как можно допустить ошибку в такой простой ситуации?
+4
Использование отладчика GDB по максимуму
4 min
40KВ нашей повседневной работе, как и всем, требуется много пользоваться отладчиком. В силу специфики работы: (разработка ОС, использование технологий виртуализации наподобие Intel-VT, ит.д.) нам часто требуется использовать отладчик для работы со специфическими случаями: отладка кода загрузчика ядра, отладка загрузчиков виртуальных машин, а так же в принципе обеспечение возможности отлаживать ОС собственной разработки. Именно эти особые случаи так пафосно названы в заголовке ”по максимуму”.
Для решения всех этих задач (и конечно, многих других) мы используем gdb. Возможно использование и таких оболочек как DDD, но лично я предпочитаю использовать cgdb как оптимальный выбор, особенно для случая работы с отладчиком по ssh.
В этой статье мы расскажем о том, как можно использовать gdb для отладки кода загрузочных секторов и загрузчиков.
Для решения всех этих задач (и конечно, многих других) мы используем gdb. Возможно использование и таких оболочек как DDD, но лично я предпочитаю использовать cgdb как оптимальный выбор, особенно для случая работы с отладчиком по ssh.
В этой статье мы расскажем о том, как можно использовать gdb для отладки кода загрузочных секторов и загрузчиков.
+27
Власть над демонами или автозапуск в Linux
5 min
365KДля реализации автозапуска в Linux написано уже немало и на разных языках, но приходится искать, потому постарался свести большую часть тут. Здесь не рассказывается полностью весь процесс с нуля, но предоставлено достаточно информации и ссылок, чтобы сделать атоматический запуск программ в Linux реальностью.
+17
На пути к Skein: просто и понятно про Blowfish
9 min
52K
с торчащими шипиками. Шарообразное состояние делает рыб практически неуязвимыми. Если всё же достаточно крупный хищник попытается проглотить такой шар, то он застревает
в глотке у хищника, который впоследствии умирает»
Википедия, свободная энциклопедия.
К концу 1993 года в мире криптографии возникла очень неловкая ситуация. Алгоритм симметричного шифрования DES, со своим слабеньким 56-битным ключом, был близок к фиаско, а существующие
на тот момент альтернативные варианты, такие как Khufu, REDOC II, IDEA были защищены патентами
и не доступны для свободного использования. Алгоритмы RC2 и RC4, разработанные в то время компанией RSA Security, также требовали проведение процедуры лицензирования. И в целом, индустрия криптографии в рамках государственных организаций и крупных корпораций была
обращена в сторону использования секретных алгоритмов, таких как Skipjack.
Возник определенный ваккум. Необходим был алгоритм шифрования, более криптостойкий нежели отмирающий DES, и в то же время без каких-либо ограничений на право своего использования.
И он появился.
+96
Интеграция Python и C++
3 min
57KВсем доброго времени суток!
Недавно при прототипировании одной из частей разрабатываемого нами продукта возникла одна интересная задача: нужно было проверить склейку Python и C++. Связано это было с тем, что основной код был написан на плюсах, и необходимо было подключить внешнюю библиотеку Websockets, написанную на Python (на тот момент не было соответствующей библиотеки на C++). Схема взаимодействия при такой задаче достаточно простая. Из C++ вызывается функция подключения к серверу (на python), в качестве параметра передается его адрес. Соответственно, при получении сообщния Python передавает его обратно в метод C++.
Недавно при прототипировании одной из частей разрабатываемого нами продукта возникла одна интересная задача: нужно было проверить склейку Python и C++. Связано это было с тем, что основной код был написан на плюсах, и необходимо было подключить внешнюю библиотеку Websockets, написанную на Python (на тот момент не было соответствующей библиотеки на C++). Схема взаимодействия при такой задаче достаточно простая. Из C++ вызывается функция подключения к серверу (на python), в качестве параметра передается его адрес. Соответственно, при получении сообщния Python передавает его обратно в метод C++.
+22
Smart pointers для начинающих
6 min
207KЭта небольшая статья в первую очередь предназначена для начинающих C++ программистов, которые либо слышали об умных указателях, но боялись их применять, либо они устали следить за new-delete.
+60
Пишем драйвер для самодельного USB устройства
13 min
179KЦелью этой статьи является пошаговая демонстрация процесса разработки всего набора программного обеспечения необходимого для организации связи самодельного устройства с компьютером посредством USB.
На данный момент, большинство радиолюбителей реализуют такой тип подключения используя чипы переходники USB в RS232 таким образом организуя связь со своим устройством посредством драйвера виртуального COM порта поставляемого с чипом переходником. Минусы такого подхода думаю понятны. Это как минимум лишний чип на плате и ограничения накладываемые этим чипом и его драйвером.
Мне же хочется осветить весь процесс организации такого взаимодействия так как оно и должно быть сделано, и как делается во всех серьезных устройствах.
В конце концов, сейчас 21-й век, модуль USB есть почти во всех микроконтроллерах. Именно о том, как наиболее быстро воспользоваться этим модулем и будет эта статья.
На данный момент, большинство радиолюбителей реализуют такой тип подключения используя чипы переходники USB в RS232 таким образом организуя связь со своим устройством посредством драйвера виртуального COM порта поставляемого с чипом переходником. Минусы такого подхода думаю понятны. Это как минимум лишний чип на плате и ограничения накладываемые этим чипом и его драйвером.
Мне же хочется осветить весь процесс организации такого взаимодействия так как оно и должно быть сделано, и как делается во всех серьезных устройствах.
В конце концов, сейчас 21-й век, модуль USB есть почти во всех микроконтроллерах. Именно о том, как наиболее быстро воспользоваться этим модулем и будет эта статья.
+146
Простой индикатор раскладки клавиатуры в курсоре на С++
2 min
38K
+70
Алгоритм «diamond-square» для построения фрактальных ландшафтов
12 min
119K
Как же автору игры, Notch'у, удалось добиться подобного сходства его случайных «миров» с земными просторами? В этом топике я как раз и рассмотрю один из способов построить искусственный ландшафт такого рода (и вскользь упомяну пару других способов), а также расскажу о моем небольшом усовершенствовании этого алгоритма, позволяющем значительно увеличивать размеры ландшафта без заметных потерь в производительности.
Внутри вас ждет несколько схем и красивых картинок, довольно много букв и ссылка на пример реализации алгоритма.
+146
Information
- Rating
- Does not participate
- Location
- Eindhoven, Noord-Brabant, Нидерланды
- Date of birth
- Registered
- Activity
Specialization
Embedded Software Engineer, Scrum Master
Lead
C++
C
Embedded system
Embedded Linux
Cmake
Bash
Docker
CI/CD
Git
Python