Почему создаются файлы дампа ядра?

Иногда, когда я запускаю свой код, создается файл дампа ядра, когда я завершаю программу нажатием Ctrl + \. Имя файла имеет вид core.*. Программа не завершается внезапно, и ошибки сегментации отсутствуют. Я считаю, что это SIGQUIT, а не SIGABRT или SIGSEGV. Если я попробую Ctrl + C или Ctrl + Z, то он не будет создан.

Может ли кто-нибудь сказать, почему он генерируется только при нажатии Ctrl + \? Как я могу избежать создания этого файла дампа ядра? Есть ли польза от файла дампа ядра?


person Chaithra    schedule 22.04.2009    source источник
comment
Когда вы говорите «Запустить мой код», вы имеете в виду, когда запускаете make? Или при запуске скомпилированного двоичного файла?   -  person harto    schedule 22.04.2009
comment
Просто лакомый кусочек: по крайней мере, один ответ объясняет, почему SIGINT не создает ядро, но я с первого взгляда не заметил никаких разговоров о SIGTSTP (это то, что ctrl + z делает по умолчанию) - он приостанавливает процесс. Встроенная оболочка jobs покажет вам приостановленные процессы. См. Также help fg (если вы используете bash, по крайней мере, это будет работать). Вы также можете создать его с помощью команды: kill -SIGTSTP <pid>. Также обратите внимание, что вы можете переопределить, какие комбинации элементов управления отправляются по умолчанию (то есть: вы можете определить SIGTSTP как ctrl + j, если хотите). stty -a покажет вам конфигурацию и другую информацию.   -  person Pryftan    schedule 09.09.2019


Ответы (7)


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

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

Что касается того, что на самом деле представляет собой дамп ядра, ознакомьтесь с этой статьей в Википедии:

person JaredPar    schedule 22.04.2009
comment
В Linux Ctrl + \ вызывает дамп ядра, даже если программа не имеет ошибок и работает нормально на момент завершения. - person ely; 13.07.2013
comment
Чтобы быть более конкретным, это когда процесс выходит из своей памяти (чтение / запись). И еще одна причина (хотя я не сбрасываю со счетов предположение, что это, скорее всего, ошибка, связанная с указателем) могут произойти, казалось бы, случайные сбои: процесс перезаписывает память, но не выходит из своего пространства памяти. Затем, спустя много времени после возникновения ошибки, вы получите мусорный стек. Это может вызвать всевозможные проблемы и может быть кошмаром для отслеживания - хотя это то, что контроль версий может помочь выяснить, а также испытать. - person Pryftan; 09.09.2019
comment
@ely Если настроено на SIGQUIT да (по умолчанию). Но это потому, что обработчик по умолчанию для SIGQUIT - это дамп ядра. Iirc он не побуждает UB игнорировать SIGQUIT, что означает, что вы можете предотвратить это. - person Pryftan; 09.09.2019

Как говорили другие ранее, дамп ядра является результатом ошибки в программе.

Вы можете настроить создание дампа ядра с помощью команды ulimit. Вход

ulimit -c 0

отключает создание файла ядра в активной оболочке.

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

gdb <pathto/executable> --core <corefilename>
person lothar    schedule 22.04.2009

Дампы ядра создаются, когда процесс получает определенные сигналы, такие как SIGSEGV, которые ядра отправляют ему, когда он обращается к памяти за пределами своего адресного пространства. Обычно это происходит из-за ошибок в использовании указателей. Это означает, что в программе есть ошибка.

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

Вы можете предотвратить создание дампов ядра с помощью команды ulimit.

person Community    schedule 22.04.2009

ctrl + \ отправляет сигнал SIGQUIT процессу. Согласно стандарту POSIX.1 действие по умолчанию для этого сигнала - создание ядра.

SIGILL, SIGABRT, SIGFPE, SIGSEGV - это другие случаи, когда система сгенерирует ядро.

Пожалуйста, обратитесь к "man 7 signal" в вашей системе для получения более подробной информации.

person Onkar    schedule 04.10.2010
comment
Правда. Следует отметить, что в дополнение к SIGILL, как у вас, есть еще SIGKILL. SIGKILL по умолчанию не генерирует coredump, но, как и SIGSTOP, его нельзя поймать, проигнорировать или заблокировать. Я указываю на это, потому что SIGILL легко читать как SIGKILL, особенно если вы не знаете, что оба существуют. - person Pryftan; 09.09.2019
comment
И в обработчиках сигналов обратите внимание на UB: Согласно POSIX, поведение процесса не определено после того, как он игнорирует сигнал SIGFPE, SIGILL или SIGSEGV, который не был сгенерирован kill (2) или raise (3). Целочисленное деление на ноль дает неопределенный результат. На некоторых архитектурах он генерирует сигнал SIGFPE. (Также деление самого отрицательного целого числа на -1 может сгенерировать SIGFPE.) Игнорирование этого сигнала может привести к бесконечному циклу. - person Pryftan; 09.09.2019

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

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

person Jason Coco    schedule 22.04.2009
comment
Хм ... Он содержит только дамп памяти processus, но все же памяти может быть довольно много. - person Ben; 22.04.2009
comment
'Зло'? Это означало бы, что ошибка - «зло». Может быть, это намеренное преувеличение, но это огромное преувеличение. И размеры зависят от размера процесса (файла). И технически «это» не генерирует segfault как таковое, а скорее запускает его. - person Pryftan; 09.09.2019

Вы можете избежать создания файла дампа ядра, написав код, который не дает сбоев :)

Серьезно, дампы ядра полезны, потому что вы можете видеть состояние программы в момент ее сбоя для «посмертной» отладки. Вы можете открыть их в gdb и проверить состояние вашей программы (особенно если она была построена с отладкой).

Дампы ядра обычно создаются, если в программе есть SIGSEGV (обычно вызванное разыменованием недопустимого указателя), SIGABRT (что произойдет, если вы вызвали abort (), или в C ++ обработчиком terminate () по умолчанию для исключений в деструкторах и т. Д.) Или другая вина. Вы также можете запускать их явно с помощью отладчика или программно.

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

person MarkR    schedule 22.04.2009
comment
На самом деле, даже если вы не перекомпилируете, это происходит потому, что строчная информация исходного файла больше не совпадает. Поэтому, если вы отлаживаете с помощью coredump, если вы меняете источник, это может оказаться очень неправильным. Даже одна строка может все усложнить. - person Pryftan; 09.09.2019

Смысл Ctrl + \ - создать дамп ядра. Это то, что делает SIGQUIT. Если вы не хотите, чтобы он создавался, используйте вместо этого Ctrl + C (SIGINT). Если рассматриваемая программа не отвечает на SIGINT, но вам нужно убить ее из терминала, значит, вы или разработчик что-то делаете неправильно.

Программы, разработанные не для уничтожения из терминала с помощью Ctrl + C, должны по-прежнему корректно реагировать на SIGTERM, который может быть запущен в другом терминале через kill -TERM ... . Если ничего не помогает, SIGKILL принудительно завершает работу.

person Zenexer    schedule 10.05.2014
comment
Или измените поведение SIGQUIT по умолчанию. - person Pryftan; 09.09.2019