OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

Core dump на Linux: systemd-coredump, ulimit, core_pattern и gdb — полное руководство

Дампы памяти — быстрый путь понять, почему сервис упал. Разбираем, как включить и настроить coredump в Linux: что меняет systemd-coredump, чем помогает ulimit и core_pattern, как хранить и чистить дампы, где искать debuginfo и как читать backtrace в gdb, не превращая прод в свалку гигабайт.
Core dump на Linux: systemd-coredump, ulimit, core_pattern и gdb — полное руководство

Core dump — это снимок памяти процесса в момент аварии. Для админов и девопсов это прямой билет к причине crash без угадываний. Но экосистема Linux изменилась: вместо старого привычного файла core в текущем каталоге всё чаще работает systemd-coredump, пишет сжатые дампы в отдельное хранилище и управляет квотами. В статье — практическое руководство по включению и использованию coredump: от ulimit и core_pattern до gdb, дебаг-символов и правил очистки.

Зачем вам core dump в проде

Логи не всегда помогут: при падении из-за гонки потоков, переполнения стека или ошибочного доступа к памяти вы увидите лишь обрывочные сообщения. coredump фиксирует полный контекст: стек всех потоков, регистры, маппинги памяти, аргументы, иногда содержимое строк и структур. Это позволяет в gdb увидеть реальный backtrace и быстро локализовать проблему в коде или в сторонней библиотеке.

Правильно настроенный systemd-coredump не превращает диск в помойку: он умеет сжимать дампы, ограничивать размер, держать свободное место, а при необходимости можно писать дампы в каталог проекта с понятным шаблоном имени через core_pattern.

Как ядро решает, писать ли core dump

На запись дампа влияют несколько факторов:

  • Лимит RLIMIT_CORE процесса (управляется через ulimit -c или prlimit).
  • Глобальная политика kernel.core_pattern — куда и как писать дампы (в файл или в пайп systemd-coredump).
  • Флаг fs.suid_dumpable — что делать с setuid/setgid процессами и безопасностью их дампов.
  • Права на директорию назначения, свободное место и квоты systemd-coredump.

Быстрая диагностика текущих настроек

Проверьте, куда вообще пойдёт дамп и разрешён ли он для вашего процесса:

# Текущий лимит ядра для core (0 — запрещено, unlimited — без лимита)
ulimit -c

# Все лимиты текущей оболочки (строка core file size)
ulimit -a

# Лимиты конкретного PID (например, оболочки)
prlimit -p $$

# Настройка ядра: шаблон пути или пайп
sysctl kernel.core_pattern

# Политика для SUID процессов (0 — запрет, 1 — ядро, 2 — в CWD)
sysctl fs.suid_dumpable

Если kernel.core_pattern начинается с вертикальной черты, например |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %e, значит включён systemd-coredump. Если там путь с %-плейсхолдерами (например, /var/lib/coredumps/core.%e.%p.%t) — дампы будут писаться как файлы по этому шаблону.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

systemd-coredump: как он работает и где лежат файлы

systemd-coredump перехватывает дампы через пайп из kernel.core_pattern, сжимает их и складывает в хранилище, обычно в /var/lib/systemd/coredump, а метаданные пишет в журнал (journald). Доступ к списку и выгрузке обеспечивается командой coredumpctl. По умолчанию ядро современных Debian/Ubuntu и многих других систем уже настроено на такой режим.

Сильные стороны этого подхода: единая точка настроек, автоматическая ротация по дисковым квотам и возможность быстро открыть дамп в gdb без ручных путей. Слабые стороны: не всем удобно, что файлы не лежат рядом с бинарём, и для контейнеров такой режим иногда не подходит (ниже об этом).

Ключевые параметры в coredump.conf

Основной файл настроек: /etc/systemd/coredump.conf (глобально) и /etc/systemd/coredump.conf.d/*.conf (дроп-ин конфигурации). Типичные параметры:

  • Storage=external|journal|none|both — где хранить содержимое дампа. Обычно external (в каталог) плюс метаданные в журнале.
  • ProcessSizeMax= — максимальный размер дампа для одного процесса.
  • ExternalSizeMax= — предел размера для «external» хранения.
  • MaxUse= — общий лимит дискового пространства под дампы.
  • KeepFree= — сколько места оставлять свободным на разделе.

Пример аккуратной политики на продакшене:

[Coredump]
Storage=external
ProcessSizeMax=2G
ExternalSizeMax=2G
MaxUse=8G
KeepFree=2G

После изменения перезапустите сервис обработки дампов:

systemctl restart systemd-coredump

Проверить, что всё работает, можно так:

coredumpctl list
coredumpctl info
coredumpctl gdb

Вывод coredumpctl list и конфигурация coredump.conf на терминале

Политики очистки и квоты

Когда достигаются лимиты MaxUse или KeepFree, старые файлы в /var/lib/systemd/coredump удаляются автоматически. Метаданные в журнале можно дополнительно чистить через политику самого journald. Вручную удалять файлы из каталога допустимо, но лучше полагаться на встроенную ротацию и корректные квоты — это безопаснее и воспроизводимее.

Включаем core dump для юзера, сервиса и всего хоста

Главный источник путаницы — разные уровни, где можно включить/выключить coredump.

Для интерактивной сессии (временный дебаг)

Если нужно поймать дамп от процесса, запущенного из вашей оболочки:

# Разрешить дампы в текущей оболочке
ulimit -c unlimited

# Запустить проблемную программу и дождаться падения
./myapp --debug

Этот способ не влияет на системные сервисы и пропадёт при выходе из shell. Подходит для локальной отладки или воспроизведения бага.

Для системного сервиса systemd

Процессы под управлением systemd берут лимиты из юнита. Добавьте в юнит LimitCORE или настройте по умолчанию:

# Дроп-ин для сервиса, создаёт файл override.conf
systemctl edit myapp.service
[Service]
LimitCORE=infinity
# Применить изменения
systemctl daemon-reload
systemctl restart myapp.service

Аналогично можно задать глобально для всех юнитов в /etc/systemd/system.conf:

# Включить ядровые дампы по умолчанию для сервисов (осторожно)
DefaultLimitCORE=infinity

Перезапустите PID 1 или перезагрузите хост для применения глобального значения. Вариант с дроп-ином на конкретный сервис безопаснее.

Если у вас воркеры и очереди под systemd, посмотрите конфигурационные подходы из материала как запускать и мониторить воркеры под systemd — те же принципы применимы к лимитам и логике перезапуска.

Через PAM и /etc/security/limits.conf

Для пользовательских сессий, создаваемых через PAM, лимиты можно задать в /etc/security/limits.conf:

# Пример: всем пользователям разрешить дампы
* soft core unlimited
* hard core unlimited

Но учтите: для сервисов systemd этот файл часто не применяется — используйте LimitCORE в юните.

Специфика отдельных сервисов

  • PHP-FPM: помимо LimitCORE в юните, включите лимит в пуле: rlimit_core = unlimited в php-fpm.conf или пуле. Перезапустите сервис.
  • Nginx: можно указать worker_rlimit_core и working_directory, если пишете в файлы по core_pattern. С systemd-coredump достаточно LimitCORE в юните.
  • Java: coredump — это дамп JVM-процесса. Полезно сохранить ещё и hs_err_pid*.log. Пакеты дебага для JVM помогут в gdb.
  • Go/Node.js: gdb покажет стек нативных библиотек и рантайма; чем больше символов, тем лучше. Для Go иногда помогает флаг компиляции без агрессивной оптимизации.

Альтернатива: писать core в директорию по core_pattern

Если по организационным причинам удобнее иметь файлы рядом с артефактами релиза, можно отключить пайп в systemd-coredump и задать путь. Например:

# Писать файлы в /var/coredumps с понятным шаблоном
sysctl kernel.core_pattern=/var/coredumps/core.%e.%p.%t

# Включить PID в имя (дополнительно)
sysctl kernel.core_uses_pid=1

Создайте каталог и права заранее, сервисам нужны права на запись. Минусы подхода: нет автоматических квот и сжатия, придётся делать ротацию самостоятельно (tmpfiles.d, cron, logrotate или ansible-роль). На продакшене чаще удобнее управляться через systemd-coredump.

Работа с дампами: coredumpctl и gdb

После падения проверьте список доступных дампов:

coredumpctl list

# Подробности по последнему дампу
coredumpctl info

# Выгрузить в файл для передачи разработчикам
coredumpctl dump -o /tmp/last.core

# Открыть сразу в gdb (если есть бинарь и символы)
coredumpctl gdb

Если вы писали в файлы по core_pattern, запускайте gdb так:

# Бинарь и core-файл
gdb -q /opt/myapp/bin/myapp /var/coredumps/core.myapp.12345.1716280000

# Базовый набор команд в gdb
bt
bt full
thread apply all bt

Минимальный чек-лист в gdb

  • info threads — какие потоки были живы.
  • thread apply all bt — стек каждого потока.
  • bt full — стек активного потока с локальными переменными.
  • frame N — перейти к интересующему фрейму.
  • info registers — регистры, полезно при SIGSEGV.
  • p some_var или p/x ptr — посмотреть значение/указатель.
  • info sharedlibrary — загруженные so и есть ли символы.
  • set pagination off — удобнее читать длинные бэктрейсы.

Символы и debuginfo

Без символов (debug symbols) бэктрейс получится «голым» — адреса вместо имён. Решение — поставить пакеты с символами для самого бинаря и зависимостей. На RPM-базе это обычно -debuginfo пакеты, на DEB — -dbgsym. Если у вас собственные артефакты, собирайте с -g и отделяйте символы в .debug файлы, а в релизный бинарь оставляйте build-id: тогда gdb подтянет символы автоматически по build-id, если положить их в стандартные директории (.build-id дерево) или указать dir/set debug-file-directory в gdb.

Ещё нюансы:

  • Оптимизация компилятора (-O2/-O3) делает бэктрейсы менее «линейными», переменные могут быть оптимизированы. Для воспроизведения сложных багов старайтесь иметь сборку с умеренной оптимизацией или отдельный релиз с символами.
  • Для многих интерпретируемых рантаймов (JVM, Python) дамп нативной памяти помогает лишь частично; ищите их собственные артефакты крашей параллельно.

Анализ core-файла в gdb с backtrace на экране

Контейнеры и неймспейсы: подводные камни

В контейнерах PID 1 часто не systemd, а лёгкий init или сам процесс приложения. Это означает:

  • systemd-coredump обычно недоступен внутри контейнера, а kernel.core_pattern управляется на уровне хоста.
  • Дампы будут пытаться писаться в файловую систему контейнера (часто tmpfs/overlay) и пропадут при пересоздании. Лучше монтировать внешний каталог для дампов или использовать хостовый systemd-coredump.
  • Проверьте ulimit -c в контейнере и параметр --ulimit на уровне оркестратора, чтобы процесс мог писать дампы.

На общем хостинге и в некоторых PaaS функции дампов могут быть ограничены. Для воспроизводимой отладки удобнее поднять отдельный стенд на VDS, где вы полностью контролируете ядровые лимиты и политику хранения.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Безопасность: секреты в памяти

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

  • Ограничьте доступ к каталогу дампов правами файловой системы.
  • Не копируйте дампы на внешние ресурсы без шифрования.
  • Настройте fs.suid_dumpable=0 на бою, если нет сценария, где нужны дампы от SUID.
  • Ограничьте размеры в coredump.conf, чтобы не рисковать исчерпанием диска.

Золотое правило: сначала политика (лимиты, квоты, места хранения), потом отладка. И только самым доверенным людям доступ к полным дампам.

Если вы укрепляете сервисы под systemd, пригодятся техники из статьи sandbox и hardening для systemd сервисов — это напрямую помогает снизить риск утечек через дампы.

Частые проблемы и как их лечить

  • Дамп не создаётся. Проверьте ulimit -c, LimitCORE, права записи в каталог, значение kernel.core_pattern и наличие свободного места. Посмотрите логи systemd-coredump и journald.
  • Создаётся пустой или очень маленький файл. Вероятно, лимит ProcessSizeMax или ExternalSizeMax. Поднимите значения.
  • Нет символов в gdb. Установите -debuginfo/-dbgsym, проверьте build-id, путь к .debug файлам и info sharedlibrary.
  • Не тот бинарь в gdb. Если бинарь к моменту разбора уже обновился, создайте копию соответствующей версии или используйте coredumpctl gdb, который найдёт версию из метаданных, если доступна.
  • Контейнеры не пишут дампы. Проверьте ulimit в оркестраторе и смонтируйте каталог для дампов. Убедитесь, что хост не перенаправляет дампы в systemd-coredump без доступа из контейнера.

Шаблоны и практические пресеты

Минимальный пресет для продакшена с systemd-coredump

# /etc/systemd/coredump.conf.d/10-prod.conf
[Coredump]
Storage=external
ProcessSizeMax=2G
ExternalSizeMax=2G
MaxUse=8G
KeepFree=2G
# В сервисе, где нужен дамп (пример)
# systemctl edit myapp.service
[Service]
LimitCORE=infinity

Пресет для локальной отладки в каталоге проекта

# Писать рядом с артефактами
mkdir -p /var/coredumps
chmod 750 /var/coredumps
sysctl kernel.core_pattern=/var/coredumps/core.%e.%p.%t
sysctl kernel.core_uses_pid=1

# В shell
ulimit -c unlimited

Шпаргалка команд

# Проверить настройки
ulimit -c
ulimit -a
prlimit -p $$
sysctl kernel.core_pattern
sysctl fs.suid_dumpable

# Управление systemd-coredump
systemctl restart systemd-coredump
coredumpctl list
coredumpctl info
coredumpctl dump -o /tmp/last.core
coredumpctl gdb

# Базовый gdb
gdb -q /path/to/bin /path/to/core
thread apply all bt
bt full
info registers
info sharedlibrary

Итог

Чтобы извлечь максимум из coredump и не навредить продакшену: включайте дампы адресно в нужных сервисах (LimitCORE), держите аккуратные квоты в coredump.conf, следите за безопасностью и хранением, и обязательно готовьте символы для gdb. С таким сетапом вы превращаете случайный crash в конкретный отчёт с бэктрейсами и координатами бага.

Поделиться статьей

Вам будет интересно

Unattended-upgrades на Debian/Ubuntu: автообновления без простоев и сюрпризов OpenAI Статья написана AI (GPT 5)

Unattended-upgrades на Debian/Ubuntu: автообновления без простоев и сюрпризов

Как безопасно включить автообновления на Debian/Ubuntu: установка unattended-upgrades и APT::Periodic, настройка Origins-Pattern, ...
Trivy в CI/CD: скан Docker-образов, SBOM и fail‑threshold на практике OpenAI Статья написана AI (GPT 5)

Trivy в CI/CD: скан Docker-образов, SBOM и fail‑threshold на практике

Практическое руководство по внедрению Trivy в CI/CD: как сканировать Docker-образы, генерировать SBOM, настраивать fail-threshold ...
Docker Buildx для multi-arch: amd64/arm64, QEMU и registry-кэш OpenAI Статья написана AI (GPT 5)

Docker Buildx для multi-arch: amd64/arm64, QEMU и registry-кэш

Разбираем, как собирать и публиковать multi-arch Docker-образы под amd64 и arm64 с помощью Buildx и QEMU. Покажу настройку builder ...