Файл дампа ядра не генерируется
Каждый раз, когда мое приложение вылетает, файл дампа ядра не генерируется. Я помню, что несколько дней назад на другом сервере сгенерировался . Я запускаю приложение, используя экран в bash следующим образом:
#!/bin/bash
ulimit -c unlimited
while true; do ./server; done
Как вы можете видеть, я использую ulimit -c unlimited
, что важно, если я хочу сгенерировать дамп ядра, но он все еще не генерирует его, когда у меня возникла ошибка сегментации.
Как я могу заставить его работать?
Ответы
Ответ 1
Убедитесь, что ваш текущий каталог (во время сбоя - server
может изменять каталоги) доступен для записи. Если сервер вызывает setuid
, каталог должен быть доступен для записи этим пользователем.
Также проверьте /proc/sys/kernel/core_pattern
. Это может перенаправить исходные дампы в другой каталог, и этот каталог должен быть доступен для записи. Подробнее здесь.
Ответ 2
Эта ссылка содержит хороший контрольный список, почему сальвы ядра не генерируются:
- Ядро было бы больше, чем текущий предел.
- У вас нет необходимых разрешений для дампа ядра (каталог и файл). Обратите внимание, что дампы ядра помещаются в текущую директорию демпинга, которая может отличаться от родительского процесса.
- Убедитесь, что файловая система доступна для записи и имеет достаточное свободное пространство.
- Если подкаталог с именем core существует в рабочем каталоге, ядро не будет сбрасываться.
- Если файл с именем core уже существует, но имеет несколько жестких ссылок, ядро не будет выгружать ядро.
- Проверьте разрешения для исполняемого файла, если исполняемый файл имеет дампы ядра с поддержкой suid или sgid, по умолчанию будут отключены. То же самое будет иметь место, если у вас есть разрешения на выполнение, но нет прав на чтение для файла.
- Убедитесь, что процесс не изменил рабочий каталог, ограничение размера ядра или флаг dumpable.
- Некоторые версии ядра не могут сбрасывать процессы с общим адресным пространством (потоки AKA). Новые версии ядра могут выгружать такие процессы, но добавят pid к имени файла.
- Исполняемый файл может быть в нестандартном формате, не поддерживающем дампы ядра. Каждый исполняемый формат должен реализовывать процедуру дампа ядра.
- Ошибка сегментации на самом деле может быть ядром. Упс, проверьте системные журналы для любых сообщений Oops.
- Приложение с именем
exit()
вместо использования обработчика дампа ядра.
Ответ 3
Check:
$ sysctl kernel.core_pattern
чтобы узнать, как создаются ваши дампы (% e будет именем процесса, а% t будет системным).
Если у вас Ubuntu, ваши дампы создаются apport
в /var/crash
, но в другом формате (отредактируйте файл, чтобы увидеть его).
Вы можете проверить это:
sleep 10 &
killall -SIGSEGV sleep
Если демпинг ядра будет успешным, вы увидите "(сбрасывание ядра)" после индикации неисправности сегментации.
Подробнее:
Как создать файл дампа ядра в Ubuntu
Ubuntu
Пожалуйста, прочитайте больше на:
https://wiki.ubuntu.com/Apport
Ответ 4
Помните, если вы запускаете сервер из службы, он запустит другой сеанс bash, так что ulimit не будет работать там. Попробуйте поместить это в ваш script сам:
ulimit -c unlimited
Ответ 5
Для записи в Debian 9 Stretch (systemd
) мне пришлось установить пакет systemd-coredump
. Впоследствии в папке /var/lib/systemd/coredump
были созданы дампы ядра.
Кроме того, эти исходные коды сжаты в формате lz4
. Для распаковки вы можете использовать пакет liblz4-tool
следующим образом: lz4 -d FILE
.
Чтобы иметь возможность отлаживать распакованный coredump с помощью gdb
, мне также пришлось переименовать полностью длинное имя файла в нечто более короткое...
Ответ 6
Кроме того, убедитесь, что у вас достаточно места на диске /var/core
или везде, где записываются ваши исходные дампы. Если раздел является almos полным или 100% дисковым использованием, то это будет проблемой. Мои основные сваливают в среднем несколько концертов, поэтому вы должны быть уверены, что на этом разделе есть не менее 5-10 гигабайт.
Ответ 7
Ответы, приведенные здесь, довольно хорошо отражают большинство сценариев, для которых основной дамп не создается. Однако, в моем случае, ни одно из них не применялось. Я отправляю этот ответ в дополнение к другим ответам.
Если ваш основной файл не создается по какой-либо причине, я рекомендую посмотреть /var/log/messages. Там может быть намек на то, почему основной файл не создан. В моем случае была строка с основной причиной:
Executable '/path/to/executable' doesn't belong to any package
Чтобы обойти эту проблему, отредактируйте файл /etc/abrt/abrt -action-save-package-data.conf и измените ProcessUnpackaged с 'no' на 'yes'.
ProcessUnpackaged = yes
Этот параметр указывает, следует ли создавать ядро для двоичных файлов, не установленных с диспетчером пакетов.
Ответ 8
Если вы находитесь в дистрибутиве Linux (например, CentOS, Debian), то, возможно, наиболее доступный способ узнать о файлах ядра и связанных с ними условиях находится на странице руководства. Просто запустите следующую команду с терминала:
man 5 core
Ответ 9
Хотя это не будет проблемой для человека, который задал вопрос, потому что они запускали программу, которая должна была создать основной файл в script с помощью команды ulimit, я хотел бы документировать, что команда ulimit специфична для оболочки, в которой вы ее запускаете (например, переменные среды). Я потратил слишком много времени на работу с ulimit и sysctl и все в одной оболочке, а также на команду, которую я хотел сбросить ядро в другой оболочке, и задаюсь вопросом, почему основной файл не был создан.
Я добавлю его в мой bashrc. Sysctl работает для всех процессов, когда он выдается, но ulimit работает только для оболочки, в которой он выпущен (возможно, также и для потомков), но не для других оболочек, которые выполняются.
Ответ 10
Примечание. Если вы сами написали какой-либо обработчик аварии, ядро может не сгенерироваться. Итак, найдите код с чем-то на линии:
signal(SIGSEGV, <handler> );
поэтому SIGSEGV будет обработан обработчиком, и вы не получите дамп ядра.
Ответ 11
Если вы вызываете daemon(), а затем демонизируете процесс, по умолчанию текущий рабочий каталог изменится на /
. Поэтому, если ваша программа является демоном, вы должны искать ядро в каталоге /
, а не в каталоге двоичного файла.
Ответ 12
На всякий случай кто-то наткнется на это. Я запускал код другого пользователя - убедитесь, что они не обрабатывают сигнал, поэтому они могут изящно выйти. Я прокомментировал обработку и получил основной сброс.