справиться с SIGSEGV в Linux? - PullRequest
1 голос
/ 10 июня 2010

Мне нужно обработать SIGSEGV в моем приложении для Linux.Причина в том, что перед генерацией core-dump необходимо выполнить некоторую очистку (3-компонентная библиотека).Более того, очистка должна выполняться в контексте вызывающего потока, а не в обработчике сигналов.Поэтому я планирую в обработчике сигналов передать управление вызывающему потоку после завершения очистки, а затем использовать повышение (SIGSEGV) для генерации дампа памяти.

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

сигнала (SIGSEGV, signal_handler);

signal_handler () {... post_sem ();...}

вызывающий поток () {wait_sem ();clean_up ();...}

Ответы [ 3 ]

3 голосов
/ 10 июня 2010

Вы хотите выполнить очистку после SIGSEGV (то есть серьезной ошибки) ... Я нахожу это немного странным, потому что: 1) если вы отлаживали приложение, вы должны оставить все нетронутым для сохранения в основном файле, чтобы вы могли точноопределить, что произошло, и 2) если у вас есть приложение для выпуска клиента (скажем), ну ... оно не должно быть SIGSEGV :) (в любом случае, это не моя проблема, просто говорю ..)

По теме,

Я думаю, вы можете попытаться заблокировать SIGSEGV во всех потоках, кроме той, в которой вы пытаетесь выполнить очистку;это должно заставить ОС доставить сигнал этому конкретному потоку.Другое решение, о котором я мог подумать, это что-то вроде setjmp () / longjmp () (хотя я и не проверял ни одного из них).

Будьте осторожны, когда ваша программа получит SEGV, вы попадаете в шаткое положение (т. Е. Ваша очистка может также не сработать и генерирует еще один SEGV и т. Д.), Поэтому вам следует подумать о сбое ядра.

2 голосов
/ 10 июня 2010

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

Чтобы получить надежное решение, я подумал бы, нужно ли вам действительно запускать этот код очистки или есть другой способ справиться с ситуацией (проверьте на нечистое завершение работы при следующем запуске, ...).

1 голос
/ 10 июня 2010

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

Запись некоторой информации о состоянии, если это возможно, может помочь в отладке, но вы не должны полагаться на возможность.

Вместо этого, программа должна после регистрации информации о состоянии либо вернуться к обработчику по умолчанию (и выгрузить ядро ​​и т. Д.), Либо вызвать _exit и выйти без какой-либо очистки.

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

...