Кто-нибудь, кто знает, как использовать sigaltstack в реальной программе обработки сигналов, простой, но полный код может быть очень полезной для меня! заранее спасибо!
Как использовать "sigaltstack" в программе обработки сигналов?
Ответ 1
Вот минимальная программа-образец, которая использует sigaltstack
для поиска бесконечной рекурсии. Если вы закомментируете флаг sigaltstack
или SA_ONSTACK
, обработчик сигнала не сможет работать, потому что у него нет стека слева, и программа просто сработает.
#define _XOPEN_SOURCE 700
#include <signal.h>
#include <unistd.h>
void handler(int sig)
{
write(2, "stack overflow\n", 15);
_exit(1);
}
unsigned infinite_recursion(unsigned x) {
return infinite_recursion(x)+1;
}
int main()
{
static char stack[SIGSTKSZ];
stack_t ss = {
.ss_size = SIGSTKSZ,
.ss_sp = stack,
};
struct sigaction sa = {
.sa_handler = handler,
.sa_flags = SA_ONSTACK
};
sigaltstack(&ss, 0);
sigfillset(&sa.sa_mask);
sigaction(SIGSEGV, &sa, 0);
infinite_recursion(0);
}
Более сложное использование может фактически выполнить siglongjmp
, чтобы выскочить из обработчика сигнала и вернуться в точку, где можно избежать бесконечной рекурсии. Это недопустимо, если используются вызовы с использованием небезопасной библиотеки, а также если ваши данные могут быть оставлены в небезопасном/невосстановимом состоянии, но если вы выполняете чистые арифметические вычисления, это может быть действительно.
Возможно, лучшей задачей для обработчика сигнала будет выполнение аварийного дампа любых ценных/критических данных, которые еще не были сохранены на диске. Это может быть затруднено, если вы не можете вызывать небезопасные функции async-signal, но это обычно возможно, если вы приложите к нему какое-то усилие.