Перехват Segfault или любых других ошибок / исключений / сигналов в C ++, таких как перехват исключений в Java - PullRequest
8 голосов
/ 15 мая 2011

Я написал программу для Linux на основе глючной библиотеки с открытым исходным кодом.Эта библиотека иногда вызывает segfaults, которые я не могу контролировать.И, конечно же, когда в библиотеке есть ошибки, вся программа умирает.Однако я должен убедиться, что моя программа продолжает работать, даже если в библиотеке есть ошибки segfaults.Это потому, что моя программа выступает в роли «сервера», и ей нужно, по крайней мере, сообщать клиентам, что случилось что-то плохое, и восстанавливаться после ошибок, а не выискивать ... Есть ли способ сделать это?

Я понимаю, что в Java нужно просто поймать исключение.Но как C ++ справляется с этим?

[ОБНОВЛЕНИЕ] Я понимаю, что в C ++ есть также обработка исключений, но Segfault не является исключением, не так ли?Я не думаю, что что-то выбрасывается, когда происходит segfault.Вы должны явно "бросить" что-то, чтобы использовать try .... catch ...., насколько я знаю.

Большое спасибо, я новичок в C ++.

Ответы [ 5 ]

14 голосов
/ 15 мая 2011

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

4 голосов
/ 15 мая 2011

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

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

3 голосов
/ 15 мая 2011

Вы можете использовать обработчики сигналов.Это не очень рекомендуется, потому что вы не можете гарантировать, что устранили причину проблемы.Лучшее, что можно сделать, - это изолировать его в отдельном процессе - таков подход Google Chrome.

Если это FOSS, проще всего будет просто отладить его.

2 голосов
/ 15 мая 2011

Если у вас есть доступ к источнику, может быть полезно запустить программист в отладчике, таком как GDB.GDB останавливается на линии, которая вызывает segfault.

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

РЕДАКТИРОВАТЬ: Поскольку вы пишете, что библиотека segfaults, я просто хотел бы указать первое правило программирования: это всегда ваша ошибка Особенно, если вы новичок в C ++, возможно, произошла ошибка, потому что вы каким-то образом неправильно использовали библиотеку.C ++ - очень тонкий язык, и легко делать то, что вы не собираетесь.

0 голосов
/ 23 мая 2019

Как уже упоминалось выше здесь , вы не можете поймать сигналы segfault с помощью блоков try или «сопоставить» нарушения сегмента с чем-либо. Это действительно плохая идея - обращаться с SIGSEGV самостоятельно. SEGV из кода C ++ является серьезной ошибкой. Вы можете использовать GDB, чтобы выяснить, почему и решить это.

...