Я знаю, что при наличии достаточного контекста можно надеяться на конструктивное использование (т. е. восстановление) из условия segfault.
Но стоит ли усилий? Если да, то в какой ситуации?
Я знаю, что при наличии достаточного контекста можно надеяться на конструктивное использование (т. е. восстановление) из условия segfault.
Но стоит ли усилий? Если да, то в какой ситуации?
Вы не можете действительно надеяться оправиться от segfault. Вы можете определить, что это произошло, и, если возможно, выгрузить соответствующее состояние конкретного приложения, но вы не можете продолжить процесс. Это потому, что (среди прочего)
Так что в целом нет смысла перехватывать его и делать что-либо, КРОМЕ того, чтобы завершить процесс довольно резко. Нет смысла пытаться записать (важные) данные обратно на диск или продолжать выполнять другую полезную работу. Есть определенный смысл выгружать состояние в журналы, что делают многие приложения, а затем завершать работу.
Возможно, полезным может быть выполнение exec() вашего собственного процесса или наличие сторожевого процесса, который перезапускает его в случае сбоя. (NB: exec не всегда имеет четко определенное поведение, если ваш процесс имеет> 1 поток)
Ряд причин:
Ошибка сегментации действительно обращается к памяти, на доступ к которой у вас нет разрешения (либо потому, что она не отображается , у вас нет разрешений, неверный виртуальный адрес и т. д.).
В зависимости от основной причины вы можете захотеть перехватить и обработать ошибку сегментации. Например, если вашей программе передан недопустимый виртуальный адрес, она может зарегистрировать этот segfault, а затем выполнить некоторый контроль повреждений.
Segfault не обязательно означает, что куча программы повреждена. Чтение неверного адреса (например, нулевого указателя) может привести к segfault, но это не означает, что куча повреждена. Кроме того, приложение может иметь несколько куч в зависимости от среды выполнения C.
Существуют очень продвинутые методы, которые можно реализовать, перехватив ошибку сегментации, если вы знаете, что ошибка сегментации не является ошибкой. Например, вы можете защитить страницы, чтобы вы не могли их читать, а затем перехватить SIGSEGV, чтобы выполнить «волшебное» поведение до завершения чтения. (См. Tomasz Węgrzanowski "Segfaulting собственные программы для развлечения и прибыль" в качестве примера того, что вы могли бы сделать, но обычно накладные расходы довольно высоки, поэтому это не стоит делать.)
Аналогичный принцип применяется к перехвату исключения недопустимой инструкции (обычно в ядре) для эмуляции инструкции, которая не реализована на вашем процессоре.
Например, для регистрации трассировки стека сбоя.
Нет. Я думаю, что это пустая трата времени - ошибка сегмента указывает на то, что в вашем коде что-то не так, и вам будет лучше найти это, изучив дамп памяти и/или ваш исходный код. Один раз, когда я попытался отловить ошибку seg, я попал в зеркальный зал, которого я мог бы избежать, просто подумав об исходном коде. Никогда больше.