我想知道在多線程環境中是否有可能/推薦捕獲SIGSEGV信號。我特別感興趣的是處理由'*((int *)0)= 0'之類的東西引發的SIGSEGV。關於在多線程環境中捕獲SIGSEGV
關於此主題的一些閱讀讓我看到了signal()和sigaction(),它們安裝了一個信號處理程序。雖然在多線程環境中看起來並不樂觀。然後我嘗試了sigwaitinfo(),它在一個線程中接收到信號,而之前的pthread_sigmask()調用阻止了其他信號。它在SIGSEGV信號被引發的程度上使用raise(),在線程內部或當它通過類似'kill -SIGSEGV'的方式發送到進程時。然而,*((int *)0)= 0'仍然會殺死進程。我的測試程序如下
void block_signal()
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGSEGV);
sigprocmask(SIG_BLOCK, &set, NULL);
if (pthread_sigmask(SIG_BLOCK, &set, NULL)) {
fprintf(stderr, "pthread_sigmask failed\n");
exit(EXIT_FAILURE);
}
}
void *buggy_thread(void *param)
{
char *ptr = NULL;
block_signal();
printf("Thread %lu created\n", pthread_self());
// Sleep for some random time
{ ... }
printf("About to raise from %lu\n", pthread_self());
// Raise a SIGSEGV
*ptr = 0;
pthread_exit(NULL);
}
void *dispatcher(void *param)
{
sigset_t set;
siginfo_t info;
int sig;
sigemptyset(&set);
sigaddset(&set, SIGSEGV);
for (;;) {
sig = sigwaitinfo(&set, &info);
if (sig == -1)
fprintf(stderr, "sigwaitinfo failed\n");
else
printf("Received signal SIGSEGV from %u\n", info.si_pid);
}
}
int main()
{
int i;
pthread_t tid;
pthread_t disp_tid;
block_signal();
if (pthread_create(&disp_tid, NULL, dispatcher, NULL)) {
fprintf(stderr, "Cannot create dispatcher\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < 10; ++i) {
if (pthread_create(&tid, NULL, buggy_thread, NULL) {
fprintf(stderr, "Cannot create thread\n");
exit(EXIT_FAILURE);
}
}
pause();
}
不料,程序分段錯誤而不是打印的專業戶的線程ID死亡。
爲什麼要捕獲'SIGSEGV'?抓到它後你會做什麼? – 2013-04-25 05:40:15