Как собрать core dump Linux и проверить цепочку диагностики

Как собрать core dump Linux и проверить цепочку диагностики

Как собрать core dump Linux и проверить цепочку диагностики

Если рабочий процесс внезапно завершается, перезапуск сервиса лишь возвращает его в работу, но не объясняет причину сбоя. Когда в журнале остаётся только номер сигнала, для диагностики нужны стек вызовов на момент аварии и соответствующая сборка программы. В этой статье мы настроим контролируемый сбор дампов памяти в Ubuntu Server 24.04, проверим всю цепочку на изолированном процессе и только затем решим, включать ли сбор для рабочих сервисов.

Выделенные серверы AMDSSH доступны с 128 ГБ или 256 ГБ памяти ECC, однако это не повод безусловно сохранять дампы процессов размером с всю оперативную память сервера. Файл core может содержать пароли, тела запросов и данные приложения. Область сбора, ограничения объёма и права доступа необходимо настраивать вместе.

1. Определяем тип сбоя и проверяем действующий сборщик

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

cat /etc/os-release
df -h /var/lib
sysctl kernel.core_pattern
sudo journalctl -b -p warning --no-pager

Если значение kernel.core_pattern начинается с вертикальной черты, ядро передаёт дамп обработчику в пользовательском пространстве, а не записывает его непосредственно в текущий каталог. В системе уже может быть установлен другой сборщик аварийных дампов. Зафиксируйте исходное значение и связанные пакеты: нельзя настроить два конкурирующих механизма и считать, что оба будут работать.

Сначала отличите штатное завершение процесса от завершения по сигналу и принудительного завершения из-за нехватки памяти. SIGSEGV и SIGABRT обычно приводят к созданию дампа, а SIGKILL — нет. Сообщение об аварийном завершении в состоянии сервиса ещё не означает, что появился файл, который можно скачать.

Core dump — это содержимое памяти процесса для расследования сбоя, а не обычный журнал работы. Его нельзя размещать в общедоступном каталоге или без проверки прикладывать к обращению в поддержку либо загружать в репозиторий кода.

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

sudo apt-get update
sudo apt-get install systemd-coredump gdb gcc
sysctl kernel.core_pattern
systemctl status systemd-coredump.socket --no-pager

После установки механизм передачи дампов должен указывать на обработчик systemd. Сокет принимает запросы, а сервис обработки запускается по необходимости. Отсутствие постоянно работающего процесса сборщика не означает, что сбор дампов не работает.

2. Задаём ограничения объёма для цепочки сбора

Создайте файл /etc/systemd/coredump.conf.d/60-controlled-capture.conf со следующими настройками:

[Coredump]
Storage=external
Compress=yes
ProcessSizeMax=256M
ExternalSizeMax=256M
MaxUse=512M
KeepFree=2G

Эти лимиты предназначены для проверки на небольшом тестовом процессе, а не для рабочих приложений с большим потреблением памяти. ProcessSizeMax ограничивает размер дампа, допускаемого к обработке, а ExternalSizeMax — размер дампа, сохраняемого во внешнем файле. При превышении лимитов могут остаться только метаданные события, без полного файла памяти.

MaxUse и KeepFree управляют объёмом, занимаемым внешними дампами. Они не гарантируют резервирование места на диске и не ограничивают размер базы журнала. Одновременные сбои всё равно могут привести к нехватке места, поэтому нужно также следить за свободным пространством в соответствующей файловой системе.

Настройки будут прочитаны последующими процессами обработки. Проверить итоговую объединённую конфигурацию можно командой:

systemd-analyze cat-config systemd/coredump.conf

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

3. Проверяем настоящий сбой на изолированном сервисе

Создаём тестовую программу без рабочих данных

Запишите минимальную программу в /tmp/crash-lab.c:

#include <stdlib.h>

int main(void)
{
    abort();
}

Создайте отдельную системную учётную запись и скомпилируйте программу. Параметр -g сохраняет отладочную информацию, а -O0 упрощает просмотр тестового стека вызовов:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin crashlab
sudo install -d -m 0755 /usr/local/libexec
sudo gcc -g -O0 -o /usr/local/libexec/crash-lab /tmp/crash-lab.c

Если учётная запись уже существует, сначала выясните её назначение и не создавайте её повторно. Затем создайте /etc/systemd/system/crash-lab.service:

[Unit]
Description=Isolated core dump capture test

[Service]
Type=oneshot
User=crashlab
ExecStart=/usr/local/libexec/crash-lab
LimitCORE=infinity
Restart=no

Значение infinity здесь снимает ограничение только для процессов тестового сервиса. Сам сборщик по-прежнему подчиняется лимитам из предыдущего раздела. Не устанавливайте это значение как глобальный параметр по умолчанию для всех сервисов.

sudo systemctl daemon-reload
sudo systemctl start crash-lab.service
sudo systemctl status crash-lab.service --no-pager
sudo coredumpctl --no-pager list /usr/local/libexec/crash-lab

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

4. Проверяем файл дампа и материалы для отладки

Запишите PID этого теста из списка, введите его в одной и той же административной оболочке и экспортируйте дамп в отдельный закрытый каталог:

sudo -i
read -r -p 'Crash PID: ' CRASH_PID
umask 077
install -d -m 0700 /root/crash-evidence
coredumpctl info "$CRASH_PID"
coredumpctl dump "$CRASH_PID" --output=/root/crash-evidence/test.core
gdb -q -batch \
  -ex 'set pagination off' \
  -ex 'thread apply all bt' \
  /usr/local/libexec/crash-lab /root/crash-evidence/test.core
exit

Сначала сверьте время события, исполняемый файл, сигнал и состояние хранения, чтобы не выбрать чужую запись при повторном использовании PID. В результате проверки должен быть указан SIGABRT, а стек вызовов должен позволять связать сбой с main тестовой программы. Отсутствие исходного кода для кадров системных библиотек не мешает проверить тестовую цепочку.

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

Для реального приложения необходимо также архивировать исполняемый файл на момент сбоя, разделяемые библиотеки и соответствующие отладочные символы. Обновлённый бинарный файл с тем же именем — не та же сборка. Build ID можно сверить с помощью readelf -n; также следует записать версии пакетов и идентификаторы сборки.

Не начинайте с bt full, поскольку эта команда выводит локальные переменные. Сначала просмотрите обычный стек вызовов. Если переменные действительно нужно исследовать, делайте это в среде с ограниченным доступом и проверяйте весь экспортируемый текст на наличие чувствительных данных. При копировании бинарных файлов также сохраняйте их хеши, чтобы исключить подмену материалов во время анализа.

5. Подключаем рабочие сервисы и проверяем отмену настройки

При включении сбора для рабочего сервиса задайте LimitCORE в его собственном файле drop-in, выполните daemon-reload и перезапустите сервис в рамках контролируемого изменения. Уже запущенные процессы не получают новые ограничения автоматически после изменения конфигурации. Проверьте фактические лимиты процесса в /proc/PID/limits.

Проверка подключения должна включать как минимум четыре пункта:

После теста удалите файл тестового сервиса, программу и исходный код, затем выполните daemon-reload и reset-failed. Удаляйте тестовый дамп отдельно, используя фактический путь из coredumpctl info. Не очищайте весь каталог дампов с помощью подстановочных знаков.

Чтобы отменить политику сбора, удалите добавленный в этой статье файл конфигурации. Если нужно вернуть исходный сборщик, восстановите его через настройку пакетов и снова проверьте kernel.core_pattern; не составляйте строку обработчика по памяти. В завершение зафиксируйте полный результат проверки: событие сбоя доступно для поиска, файл можно экспортировать, стек вызовов соответствует нужной сборке, доступ к материалам ограничен. Так вы получите проверяемые свидетельства сбоя, а не просто включённую, но никем не проверенную настройку.

Часто задаваемые вопросы

При любом аварийном завершении появляется core dump?

Нет. Обычный выход программы и SIGKILL обычно не создают дамп. Даже для подходящего сигнала сбор зависит от лимитов процесса, настроек обработчика и свободного места.

Достаточно ли того, что GDB открывает дамп?

Нет. Нужны исполняемый файл, библиотеки и отладочные символы именно той сборки, которая завершилась аварийно. Также следует убедиться, что дамп не усечён.

Выделенный сервер EPYC 7543Pот $450.2/мес.

От выбора ресурсов до настройки сервера

Стоимость модели и дополнительных опций рассчитывается за месяц; полный перечень компонентов указан на странице конфигурации. Данные для подключения доступны в консоли после выдачи сервера.