Как программа на C может создать дамп ядра, не прерываясь?

Я хочу, чтобы программа на C создавала дамп ядра при определенных обстоятельствах. Это программа, которая работает в производственной среде, и ее нелегко остановить и перезапустить для настройки других видов отладочного кода. Кроме того, поскольку он находится в производственной среде, я не хочу вызывать abort (). Исследуемые проблемы нелегко воспроизвести в непроизводственной среде. Я бы хотел, чтобы программа при обнаружении определенных проблем самостоятельно создавала дамп ядра, желательно с достаточным количеством информации для переименования файла, а затем продолжала.


person Joshua Swink    schedule 25.09.2008    source источник


Ответы (5)


void create_dump(void)
{
    if(!fork()) {
        // Crash the app in your favorite way here
        *((void*)0) = 42;
    }
}

Разветвите процесс, а затем обрушьте дочерний элемент - он предоставит вам моментальный снимок, когда вы захотите

person Ana Betts    schedule 25.09.2008
comment
Ооооо, это очень здорово - мне всегда приходилось поднимать (6) и перезапускать процесс. - person paxdiablo; 25.09.2008
comment
Это убивает родителя. Потомок возвращает 0 из fork (). - person Martin York; 25.09.2008
comment
Могу ли я использовать этот метод для генерации дампа ядра при однократной обработке сигнала segfault, но не хочу завершать работу? Я хотел бы написать полноэкранную программу и все еще взвешиваю свои варианты того, как обрабатывать возможные ошибки, не выходя из программы, если это возможно. - person Adam L. S.; 31.05.2012
comment
Мое чтение предполагает, что разветвленный дочерний элемент получает только текущий поток, а не какие-либо другие потоки. Это означает, что ваш дамп ядра будет содержать информацию только о текущем потоке, а не о других запущенных вами потоках. Если вам нужны все потоки, вы можете использовать это: code.google.com/p/ google-coredumper - person Michael Anderson; 18.03.2013
comment
Если прерванная доза не возвращается, то почему или - person coder hacker; 06.05.2014
comment
Что означает || (*((void*)0) = 42)? - person hudac; 02.06.2016
comment
@hudac Это просто еще один (более комичный, менее понятный) способ сбить процесс. В частности, это вызывает ошибку сегментации. - person Phlarx; 24.03.2017
comment
Разве разветвление текущего процесса не сбивает с толку другие процессы, которые зависят от его обслуживания? Даже если вы его разбиваете, демон http может получать запросы в дочернем процессе и завершать свою работу, что может привести к сбою некоторых функций? - person XChikuX; 04.06.2018
comment
@MichaelAnderson Не могли бы вы уточнить, какие чтения? Я раздумываю, использовать ли эту технику или искать дальше. p.s. Что касается coredumper, я обеспокоен тем, что на данный момент он не обновлялся годами, по крайней мере, из того, что я смог найти. - person Iurii Vasylenko; 26.02.2020

Другой способ - использовать библиотеку Google Coredumper. Это дает результат, аналогичный методу fork + abort, но лучше работает с многопоточными приложениями (приостанавливает на некоторое время все потоки перед разветвлением, чтобы они не создавали беспорядка в дочернем элементе).

Пример:

    #include <google/coredumper.h>
    ...
    WriteCoreDump('core.myprogram');
    /* Keep going, we generated a core file,
     * but we didn't crash.
     */
person regnarg    schedule 10.07.2014

Sun описывает, как получить файл ядра в Solaris, HP-UX, Redhat и Windows здесь.

В Solaris есть программа gcore. Он может быть у HP-UX. В противном случае используйте gdb и его команду gcore. В Windows есть win-dbg-root \ tlist.exe и win-dbg-root \ adplus.vbs

person mat_geek    schedule 25.09.2008
comment
Procdump также работает в Windows - person Ana Betts; 11.05.2021

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

Я считаю, что некоторый код в проекте gdb также может быть полезен.

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

$ gdb /path/to/exec 1234 # 1234 is the pid of the running process
person njsf    schedule 25.09.2008
comment
Примечание: вопрос о запуске gdb из самого приложения: stackoverflow.com/questions/3151779/ - person Vi.; 16.04.2014

Исходный код для создания дампа ядра находится в gcore, который является частью пакета gdb.

Кроме того, у Sun есть gcore.

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

person Chris    schedule 25.09.2008