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