Сигнал segfault всегда отправляется в приложение
Мое приложение обычно аварийно завершает работу и печатает стек в журнал, если получен сигнал ошибки сегмента.
Но в некоторых средах 'dmesg' показывает сообщения о сбоях, связанных с моим приложением, но время работы приложения намного старше.
Может ли segfault подавляться и приложение не получает сигнал? Или что могут означать ошибки от dmesg?
4 ответа
Это возможно для приложения или для игнорирования или для некоторой специальной обработки для сигнала ошибки сегментации. На странице руководства для сигнальных и связанных страниц есть подробности.
Одна возможная ситуация, которую я вижу, может привести к описанному поведению (dmesg сообщает segfaults, но приложение работает), что приложение разветвляется и дочерние процессы segfaults. Чтобы узнать, так ли это, проверьте, совпадает ли идентификатор процесса, о котором сообщает dmesg, с идентификатором текущего запущенного процесса.
Программы, работающие в фоновом режиме, могут эффективно использовать обработку SIGSEGV, хотя бы для регистрации факта, что это произошло вместе с контекстом до выхода. Это дает не только представление о том, что пошло не так в файле журнала, но и полезную информацию для включения в отчет об ошибках. Да, сигнал можно игнорировать, но это только через преднамеренное действие и почти всегда плохая идея (если вы не тестируете под экспериментальным ядром с известной ошибочной подсистемой vmm).
К сожалению, как только этот сигнал пойман, НИЧЕГО подозрительно. Например, использование всего, что выделяет память в обработчике SEGV, очень плохая идея. То же самое относится и к функциям с переменным значением, таким как printf(). Так что да, хотя приложение обрабатывает сигнал, оно может работать не так эффективно, поэтому вы видите его следы только в dmesg.
В любом случае, да, сигнал отправляется приложению, однако SEGV не является сигналом реального времени и может быть объединен ядром. Т.е., если программа обращается к памяти, у которой нет прав доступа 15 раз, очень велика вероятность того, что на самом деле будет доставлен только один SEGV, в зависимости от времени незаконного доступа к памяти.
В обработчиках SEGV open() write() и close() являются вашими друзьями и используют специальный журнал отладки (т. Е. Не поток регистрации файлов FILE, который, возможно, был открыт ранее).
SIGSEGV автоматически отправляется ядром, если процесс делает что-то с памятью, чего он не должен был делать; но сигнал может быть перехвачен, и процесс может запустить обработчик сигнала, который может попытаться восстановиться после сбоя. В этом случае процесс может продолжаться.
Сигнал также может быть полностью проигнорирован, но этого следует избегать; получение SIGSEGV обычно означает, что происходит что-то действительно неправильное.
Ошибка сегментации обычно означает, что что-то пошло не так с внутренним состоянием приложения. Он может быть настолько сломан, что не сможет запустить обработчик сигнала - обработчик сигнала, который должен печатать дамп стека, тоже может произойти сбой.
Редактировать: я не совсем понял, 'uptime old ' часть, поэтому я пропустил ее. Как теперь я вижу, ваш вопрос был "почему приложение все еще работает", поэтому вот новый ответ:
Да, приложение может выжить SIGSEGV. Иногда SIGSEGV отправляется только в какой-то менее важный поток (он должен уничтожить все приложение, но иногда нет) или даже в дочерний процесс - то, что вы видите как одно приложение, может быть несколькими процессами или потоками.