1
我寫了一個分段錯誤處理程序,使用sigsetjmp和siglongjmp。一旦它進入信號處理程序,我調用siglongjmp,以便跳過錯誤的指令。我們可以重置sigsetjmp以再次返回「0」(Reset sigsetjmp)嗎?
問題是,我想再次引起SIGSEGV並轉到相同的處理,但現在sigsetjmp將返回1
如何重置sigsetjmp?
這裏是我的代碼:
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h>
#include <setjmp.h>
sigjmp_buf env, env1;
void SIGSEGV_handler(int signal)
{
printf("Segmentation fault caught\n");
siglongjmp(env, 1);
}
int main()
{
void * allocation;
size_t size;
static int devZerofd = -1;
struct sigaction sa, sa1;
sa.sa_handler=(void*)SIGSEGV_handler;
sigaction(SIGSEGV, &sa, NULL);
if (devZerofd == -1) {
devZerofd = open("/dev/zero", O_RDWR);
if (devZerofd < 0)
perror("open() on /dev/zero failed");
}
allocation = (caddr_t) mmap(0, 5000, PROT_READ|PROT_NONE, MAP_PRIVATE, devZerofd, 0);
if (allocation == (caddr_t)-1)
fprintf(stderr, "mmap() failed ");
if (mprotect((caddr_t)allocation, 5000, PROT_NONE) < 0)
fprintf(stderr, "mprotect failed");
else
printf("mprotect done: memory allocated at address %u\n",allocation);
if(sigsetjmp(env, 1)==0) {
printf("Causing SIGSEGV: 1\n");
strcpy(allocation,"Hello, how are you");
}
/****** This can't be done again as sigsetjmp won't return 0*****/
/*
if(sigsetjmp(env, 1)==0) {
printf("Causing SIGSEGV: 1\n");
strcpy(allocation,"Hello, how are you");
}
*/
}
setjmp從longjmp返回時返回1,對不對?所以你的意思是,如果後續調用,它再次返回0? – kingsmasher1
SA_RESTART你的意思是因爲它是可中斷的功能?但它的工作原理也沒有:) – kingsmasher1
或多或少,是的。請記住,每次調用'setjmp'時,如果控件第一次到達'setjmp',則返回_twice_:first;如果調用'setjmp'調用時使用了相同的'jmp_buf'調用'longjmp',則返回秒。第一個返回總是返回零。第二個返回返回'longjmp'的第二個參數,除非它是零,在這種情況下它返回一個。但是,當你再次調用setjmp時,它將設置一對新的return,並且第一個將再次返回零。 – zwol