Цифровая независимость с обновлением Immich 3.0Стопикосекундный сбой в GNU libunwind

Проблема обнаружилась в инфраструктуре Rockset — высокопроизводительном поисковом движке на C++, который OpenAI интегрировала в экосистему ChatGPT для оптимизации работы с данными и историей переписок. Инженеры столкнулись с феноменом «невозможных» падений: функции завершались некорректно, возвращая управление по нулевому адресу или со смещением указателя стека на 8 байт. В стандартных условиях эксплуатации такой код просто не может упасть подобным образом, что превратило поиск причины в настоящий детектив, где каждая рабочая гипотеза разбивалась о факты.
Долгое время команда пыталась использовать «клинический» метод отладки: детальный анализ одного конкретного дампа памяти (core dump) с целью поставить точный диагноз по имеющимся уликам. Однако этот подход оказался неэффективным, так как случайный характер сбоев скрывал общую закономерность. Перелом наступил, когда стратегия была изменена на «эпидемиологическую». Вместо изучения одного пациента инженеры решили проанализировать всю популяцию крашей за год. Для автоматизации этого процесса — скачивания и разметки огромного массива дампов памяти — был использован ChatGPT, который написал соответствующий скрипт.
Статистический анализ мгновенно выявил, что под маской одного бага скрывались два совершенно разных явления. Первым оказался редкий аппаратный сбой на одном из хостов Azure, где процессор допускал ошибку при чтении данных. Вторым же оказалась глубоко запрятанная гонка потоков (race condition) в GNU libunwind — одной из базовых библиотек для раскрутки стека.
Техническая суть проблемы восходит к 2007–2008 годам, когда в libunwind была реализована поддержка исключений C++ для архитектуры x86_64. Механизм раскрутки стека (stack unwinding) необходим рантайму C++ для восстановления регистров и очистки ресурсов при возникновении исключения. В процессе этой операции библиотека обновляет указатель стека, и ровно на одну процессорную инструкцию — временной интервал примерно в 100 пикосекунд — структура с адресом возврата оказывается вне зоны, которую ядро операционной системы гарантирует не трогать.
Если именно в этот микроскопический зазор попадает системный сигнал, ядро затирает область памяти, и адрес возврата превращается в NULL. Ошибка оставалась незамеченной почти два десятилетия, так как для её проявления требовалось стечение уникальных факторов. В случае с Rockset была создана «идеальная среда»: экстремально высокая частота генерации исключений, интенсивный поток системных сигналов и недавние изменения в обработчике сигналов, увеличившие потребление стека. Эти условия вывели баг из области теоретической возможности в плоскость ежедневных сбоев.
Для устранения проблемы OpenAI перевела свои системы на механизм раскрутки стека из libgcc, а в GNU libunwind был направлен воспроизводимый пример и соответствующий патч. Этот кейс подчеркивает фундаментальный вывод: в сложных распределенных системах качественные данные важнее интуиции или озарений. Когда разрозненные симптомы были объединены в единый массив данных, поиск причины превратился из бесконечного перебора гипотез в простую задачу по поиску корреляций.

