Обновить
64K+

Системное программирование *

Обеспечение работы прикладного ПО

98,25
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Таймаут вернул 124, а следующий запуск пропущен: какие фоновые утилиты держат flock

Время на прочтение5 мин
Охват и читатели3.7K

Задача в cron упёрлась в timeout, в логе код 124, а следующий запуск молча пропускается: lock занят. Я проверил в контейнере семь обычных способов оставить что-то работать в фоне — setsid -f, nohup, start-stop-daemon, двойной fork, ssh-agent, gpg-agent — под timeout и subprocess.run(timeout=). Демона не убила ни одна обёртка. Пропустит ли cron следующий запуск, решает сама утилита: gpg-agent держит lock, ssh-agent отпускает, но за пять запусков копится пять агентов. Код 124 у оборванного запуска при этом одинаковый.

Читать далее

Новости

Какая самая старая программа с GUI запускается на Windows 11 без эмуляции

Время на прочтение3 мин
Охват и читатели8K

FREECELL.EXE из комплекта Win32s с датой 22 февраля 1993 года запускается на свежей Windows 11 без правок и эмуляции, и в него можно играть. Можно ли найти программу с графическим интерфейсом ещё старше? 16-битные приложения отпадают сразу: в 64-битной Windows нет NTVDM. Автор перебрал предрелизные сборки Windows NT 3.1 из Internet Archive: самые ранние спотыкаются о черновой формат PE и о соглашение о вызовах cdecl вместо stdcall, из-за которого аргументы снимаются со стека дважды. Но CDPLAYER.EXE, слинкованный 16 ноября 1992 года, запускается: он берёт системную crtdll.dll, которую Windows 11 до сих пор поставляет в SysWOW64.

Читать далее

Как я писал эмуляцию звука для Nintendo Gameboy на C++ целый год

Уровень сложностиПростой
Время на прочтение15 мин
Охват и читатели8.2K

В этой статье я расскажу, как устроена звуковая подсистема Nintendo Gameboy, с какими проблемами я столкнулся, пытаясь в реальном времени генерировать звук и синхронизировать с ним картинку. Статья является продолжением моей прошлой публикации.

Читать далее

Память в GoOS, часть 2. Нативные потоки, горутины и GC на SMP

Уровень сложностиСложный
Время на прочтение18 мин
Охват и читатели5.1K

Как я рассказывал в первой части, реализация работы с памятью - довольно непростое занятие, и в первой части я рассказывал про сравнительно лёгкую область этой работы.

Пока процесс однопоточный, сборщик мусора имеет дело с одним стеком, одним набором регистров и одной точкой выполнения. Как только появляется второй поток, он уже может одновременно менять кучу на другом процессорном ядре. А после появления горутин выполнение Go-кода вообще перестаёт быть жёстко связано с одним стеком нативного потока.

В релизе GoOS 0.2.8 сначала появились нативные потоки пользовательского пространства, а затем поверх них — собственный M:N runtime для горутин. После этого задача сборщика мусора стала заметно неприятнее: перед освобождением объекта нужно быть уверенным, что ссылка на него не осталась в стеке другого потока, в сохранённом контексте горутины, в XMM-регистре или в промежуточном состоянии переключения контекста.

Это уже не только задача GC. Здесь пересекаются планировщик, аллокатор, ABI, TLS, виртуальная память и код сохранения регистров.

Читать далее

Память в GoOS, часть 1. От bump allocator к собственному heap и GC

Уровень сложностиСложный
Время на прочтение21 мин
Охват и читатели7.1K

В первой статье про GoOS я довольно подробно прошёлся по загрузке, SMP, IPC, capabilities, сети, Linux ABI и устройству сервисов. А в комментариях довольно быстро всплыл вопрос, который я тогда сознательно обошёл стороной: что в системе происходит с динамической памятью и сборщиком мусора.

Вопрос был вполне по делу. Я пишу ОС преимущественно на Go, компилирую её TinyGo, но обычный Go runtime мне тут никто не выдаёт. Значит, фраза «Go сам разберётся с памятью» тут совершенно не работает. Кто-то должен дать new, make, слайсам, map, channel и остальным объектам кучу. Кто-то должен вернуть память после того, как объект перестал быть нужен. А если в системе появляется GC, он должен понимать, где искать корни, как останавливаться относительно потоков и что делать с указателями, которые в момент остановки лежат не на стеке, а в регистрах процессора.

На момент той дискуссии ответ был сильно проще. Ядро было и остаётся собрано TinyGo с gc: leaking: его Go-куча умеет только выделять. В повторяющихся путях ядра динамические аллокации запрещены архитектурно, а объекты для таких путей заранее выделяются, переиспользуются или живут в специальных таблицах и пулах. В userspace ситуация была хуже: там уже существовал собственный runtime, но runtime.alloc по сути был bump allocator, а runtime.free и runtime.GC были заглушками.

В одном из ответов я тогда написал: «И таки да, следующим релизом я этот вопрос решу».

0.2.8 — как раз этот самый релиз.

Читать далее

Декларативный подход к текстовым протоколам в Embedded на Си. Фреймворк TACT

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели6.3K

Я занимаюсь разработкой встраиваемых систем уже несколько лет и не раз сталкивался с проблемой, когда было необходимо написать UART драйвер или систему для работы с каким-либо внешним модулем, используя текстовый протокол, будь то протокол AT-команд или что-то подобное. Чаще всего это модули GNSS, модуль GSM, ESP или т.п. Набор управляющих команд для таких модулей бесконечно огромен, и каждая из них часто требует отдельной обработки. Итогом получается нужно писать свой обработчик и парсер под каждую команду, через колбэки или некую машину состояний их последовательно вызывать и пытаться как-то организовать цепочку выполнения, а про обработку ошибок я вообще молчу.

Да, существуют библиотеки и готовые решения в рамках какой-либо операционной системы или набора SDK под конкретный чип. Но что делать, когда на столе лежит микроконтроллер с 20кб свободной RAM, где тебе надо не только команды эти обрабатывать, но еще и весь остальной функционал устройства реализовывать? Нужно что-то универсальное, независимое от платформы.....

Читать далее

Управление памятью в контейнерах STL. От абстракций к реализации

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели66K

Каждый разработчик на C++ начинает свой путь с оператора new. Нам объясняют его работу очень просто: «new выделяет память в куче и создает там объект». Мы пишем auto ptr = new MyClass(42); и до поры до времени не задумываемся, что скрывается за этой строчкой.

Читать далее

Удобный SSH клиент на Rust и собственном UI‑движке EvertyUI

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели13K

Я много работаю с серверами. Разрабатываю EvertyDesk Next, экспериментирую с сетевыми протоколами, поднимаю контейнеры, собираю приложения, иногда просто захожу посмотреть, почему опять что-нибудь перестало работать.

Для всего этого нужен SSH.

Много лет для подобных задач существует PuTTY. Программа хорошая, проверенная, выполняет свою работу. Но лично меня она постепенно начала раздражать.

Открываешь одно соединение, потом второе. Где-то ошибка подключения, где-то соединение оборвалось. Где-то требуется вспомнить команду, которую выполнял вчера. Где-то снова заниматься ключами.

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

Мне не нужен комбайн. Я хочу открыть приложение, выбрать сервер и работать.

И если соединение оборвалось, это не должно превращаться в маленькую катастрофу.

В какой-то момент я подумал: а почему бы не написать собственный SSH-клиент?

Тем более что у меня уже есть Rust и собственный интерфейсный движок EvertyUI.

Так появился EvertySSH.

Читать далее

Пишем свой immutable‑логгер на Python: как защитить данные на edge‑устройствах без облаков и SIEM

Уровень сложностиСредний
Время на прочтение3 мин
Охват и читатели5.2K

Привет, Хабр!

Я занимаюсь разработкой архитектуры для автономных робототехнических систем, которые должны работать в экстремальных условиях: без интернета, без облаков и без возможности оперативного вмешательства человека.

Одна из ключевых проблем таких систем — обеспечение целостности логов. Если устройство попало в аварию или было скомпрометировано, традиционный текстовый файл system.log не является доказательством: его можно незаметно отредактировать, удалить строки или изменить порядок событий.

Корпоративные SIEM-системы (вроде ELK) слишком тяжелы для К сожалению, данная публикация не сможет пройти модерацию, в соответствии с п.4 Правил ресурса.в с ограниченной памятью и вычислительной мощностью. Облачные решения неприменимы из-за отсутствия связи.

В этой статье я расскажу, как я реализовал легковесный, не требующий внешних зависимостей модуль на чистом Python, который создает криптографически неизменяемую цепочку записей (по аналогии с блокчейном), и покажу, как он обнаруживает любые попытки подделки.

Читать далее

OptimaOS: продолжаем работу

Уровень сложностиСложный
Время на прочтение11 мин
Охват и читатели6.6K

Полгода назад я показывал ядро OptimaOS — Rust-ядро, которое загружается на реальном x86_64. С тех пор вокруг него появились собственная файловая система (ФС), установщик внутри прошивки, формат исполняемых файлов и модель приёмки, где доказательство можно проверить машинно.

Первая статья собрала много вопросов. Зачем ещё одна операционная система (ОС), чем она отличается от Linux, почему GPL, как относиться к коду, написанному с помощью LLM (large language model, большая языковая модель). Постараюсь ответить на все вопросы.

Читать далее

Шифровать нельзя доверять: как защитить биометрию вен ладони на пути от сенсора до сервера СКУД

Время на прочтение37 мин
Охват и читатели9.9K

Мы не будем рассматривать, как строится вектор вен ладони и как работают алгоритмы компьютерного зрения. Не будет ни слова про длины волн ИК излучения, ни про обработку liveness. Статья про информационную безопасность. Мы возьмем упрощённую, но актуальную модель угроз для биометрических систем контроля и управления доступом (СКУД) и спроектируем сквозную защиту данных на пути от оптического сенсора до сервера. Решение должно выстоять даже в том случае, если сам терминал окажется в руках зловреда. Сразу рассмотрим худшие случаи: нарушитель с физическим доступом к считывателю и инсайдер, который сидит прямо в корпоративной сети потребителя или на предприятии-изготовителе.

Автор, озадачившись риском компрометации биометрических данных, ставит целью спроектировать систему защиты, где вообще не хранятся эти самые биометрические данные. Статья рассматривает авторское техническое решение, но не гарантирует патентную чистоту и не раскрывает никакую конфиденциальную информацию производителей.

Отдельно разберём заблуждение «повесим TLS и всё безопасно».

Читать далее

Русский язык в программировании. РУСИ++

Уровень сложностиСложный
Время на прочтение53 мин
Охват и читатели18K

Статья посвящена системному программированию на русском языке с C-подобным синтаксисом. Компилятор для языков программирования РУСИ, РУСИ++ и объектный-РУСИ создан путём модификации и пересборки компилятора GCC 14й версии с превращением его в полноценный русско-английский билингвальный компилятор. Отдельно дана инструкция модификации русской раскладки клавиатуры для добавления в неё фигурных, угловых и квадратных скобок - дабы не переключаться и не терять поток.

Читать::Далее();

Микроядро seL4, Ada/SPARK и 185 модулей: разбор проекта

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели7.4K

185 модулей ядра, not‑proved: 0. Сеть и хранилище в Ring 3, TCP работает на железе. Разбор проекта Schild TCB: формальная верификация, изоляция периферии и то, где я упёрся. С честными границами — что доказано, что только в QEMU, а что на реальном ноутбуке.

Читать далее

Ближайшие события

Режимы работы x86-процессора

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели5.4K

Я пишу свою ОС и загрузчик для x86_64, параллельно изучая в CS и низкоуровневую разработку. Эта статья — подробный обзор, где я разбираю основу, на которой держится вся архитектура x86: как процессор оперирует битами, механика его работы в 16-битном, 32-битном и 64-битном режимах, с углублением в каждый из них.

Читать далее

Заводим C++ корутины на микроконтроллере

Уровень сложностиСредний
Время на прочтение15 мин
Охват и читатели12K

Мне давно было интересно попробовать запустить корутины на микроконтроллере, но стандарт С++ совершенно не учитывает мир embedded с его ограничениями и не даёт возможности создать корутину в статической памяти.

Недавно я обнаружил что LLM агенты уже могут реализовывать довольно сложные задачи самостоятельно с неплохим качеством кода.

И тут я понял - чего бы не попробовать сделать своё расширение для clang с корутинами, которые гарантированно не используют аллокации и поверх этого реализовать небольшую операционную систему на корутинах для микроконтроллера.

Читать далее

GoOS: от любопытства к собственному ядру

Уровень сложностиСложный
Время на прочтение32 мин
Охват и читатели9.1K

Ещё в школе, когда я впервые начал писать на Pascal, меня заинтересовал вопрос: что именно происходит, когда запускается программа? Программа читает клавиатуру, выводит текст, выделяет память. Но кто её запускает? Кто выделяет ей процессорное время? Почему она не может прочитать память другого процесса? Как нажатие клавиши превращается в событие для приложения? И что происходит между включением компьютера и первым приглашением командной строки? Вместо того чтобы ограничиться прикладным программированием, я полез разбираться в загрузчиках, памяти и работе процессора.

Но теперь у этой истории истории есть своё собственное имя - GoOS. Если вам интересно почитать об этом подробнее - добро пожаловать!

Читать далее

Оптимизация компиляции: как мы приближали производительность кода на PL/I к C

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели4.1K

Можно ли написать программу на PL/I и получить скорость выполнения, сравнимую со скоростью аналогичной программы на C или быстрее? Именно это мы попытались реализовать в нашем компиляторе pli-llvm.

Мы сравнивали 21 небольшую программу - от сортировки и математических вычислений до работы со строками и файлами. Для каждой задачи были реализации на PL/I и C. Итоговая оценка была посчитана как геометрическое среднее отношений времени выполнения PL/I к C на -O2: 1,0x означает паритет, меньше 1,0x - PL/I выполнился быстрее. Результат на свежих сборках и медиане семи запусков - 0,8x на -O2. До начала этой работы компилятор уже примерно сравнялся с C: результат был около 0,9x. Задача состояла в том, чтобы пройти путь от паритета к устойчивому преимуществу - и выяснить, за счёт чего оно достигается.

Читать далее

Make Perl Great Again. Часть 1: Hello World

Уровень сложностиСредний
Время на прочтение19 мин
Охват и читатели9.6K

Все знают, что любая книга по программированию начинается с приведения примера программы hello world. Я тоже не буду оригинальничать и покажу, как надо писать hello world. Но в отличие от других авторов, которые очень быстро переходят от этой программы к каким-то очень высоким материям, философским обоснованиям, паттернам программирования и шаблонам проектирования (чтобы это всё ни значило), я ограничусь только hello world. Кто-то же должен заполнить пробел между hello world и… веб-сервером :-).

Читать далее

Дизассемблер для arm64, x86-64, i386, WebAssembly, .NET и Java — в одном HTML-файле

Уровень сложностиПростой
Время на прочтение2 мин
Охват и читатели8.3K

Всем уже надоели клоны (их есть у меня) и спекуляция на чужом имени — хочется увидеть что-то по-настоящему новое и полезное.

Встречайте дизассемблер для ARM64, 32-битного ARM, x86-64, i386, WebAssembly, .NET (CIL) и байт-кода Java: файлы Mach-O, ELF, PE, APK и IPA из macOS, iOS, Linux, Android и Windows. Один HTML-файл, работает без сети, ничего не отправляет — скачиваете на дискету, и этот инструмент с вами навсегда. Всё уместилось в 1,22 МБ.

Читать далее

Сломанный Ctrl+C — сначала гасла VM, а потом не прерывался sleep: Java, KVM и Linux

Уровень сложностиСложный
Время на прочтение12 мин
Охват и читатели9.3K

Обычный Ctrl+C оказался для моей Java VM неожиданной проблемой: сначала он завершал саму виртуальную машину, а после исправления перестал останавливать команды внутри Linux. Чтобы разобраться, пришлось пройти весь путь от host terminal через UART и KVM до гостевого TTY и Unix-сигналов. В статье разберём не только причину, но и метод диагностики, который пригодится далеко за пределами виртуализации.

Разбираемся, куда пропал Ctrl+C
1
23 ...