C 的段错误处理程序只调用一次
segfault handler for C only called once
我正在编写一个程序来扫描进程内存并创建一个 memchunk 结构来表示内存块的可访问性。这个过程的一个副作用是学习如何处理信号,因为在这个扫描过程中应该有很多段错误。所以,我试图引起许多段错误来了解信号,同时也了解一些虚拟内存。这是在 linux 平台上编译为 32 位程序。
我使用 setjmp
和 longjmp
来重新进入我的程序。
我的问题是我的段错误处理程序只被调用一次,然后在下一个段错误时调用默认的段错误处理程序——核心转储处理程序。
这是我的处理程序:
static void hdl (int sig, siginfo_t *siginfo, void *unused){
/* handler is called properly and can read curr_access */
printf("-------------------\n");
printf("handling segfault\n");
printf("curr_access = %d\n", curr_access);
printf("-----------------\n");
switch(curr_access){
case -1:
longjmp(buf, 1);
break;
case 0:
longjmp(buf, 2);
break;
default:
printf("error in hdl\n");
}
}
这是我注册的地方
void set_hndlr(){
printf("------------------\n");
printf("setting handler\n");
printf("-----------------\n");
/* setting up signal handler */
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = hdl;
if (sigaction(SIGSEGV, &sa, NULL) == -1)
printf("error setting segfault hanld");
}
这里是我"test"一个记忆位置:
switch(jmp_code){
/* we haven't gone through testing yet */
case 0:
test_boolean = 1;
break;
/* we've gone through testing and we segfaulted at read */
case 1:
test_boolean = 0;
curr_access = -1;
break;
/* we've gone through testing and we segfaulted at write */
case 2:
test_boolean = 0;
curr_access = 0;
break;
/* if we reach here then there is an error in program logic */
default:
printf("error in programming logic regaurding jmp\n");
exit(-2);
}
if(1 == test_boolean){
/* not accessible */
curr_access = -1;
printf("testing read\n");
/*test read */
curr_cont = *curr_addr;
curr_access = 0;
printf("readable\n");
/*test write */
*curr_addr = curr_cont;
curr_access = 1;
printf("read/write\n");
}
这是一些示例输出:
setting handler
curr_addr = (nil)
jmp_code = 0
testing read
handling segfault
curr_access = -1
jmp_code = 1
base[0].RW = -1
base[0].length = 4096
base[0].start = (nil)
curr_addr = 0x1000
jmp_code = 0
testing read
Segmentation fault (core dumped)
奇怪的是,我可以很好地处理一个段错误,但之后就无法再处理了。如果有任何帮助,我将不胜感激。
在某些系统中,不支持重新分配信号处理程序。我们必须在调用 function_handler.
之后重新分配句柄
Unreliable Signals
One problem with these early versions is that the action for a signal was reset to its default each time the signal occurred.
int sig_int();
...
signal(SIGINT, sig_int);
...
sig_int()
{
signal(SIGINT, sig_int);
...
}
我正在编写一个程序来扫描进程内存并创建一个 memchunk 结构来表示内存块的可访问性。这个过程的一个副作用是学习如何处理信号,因为在这个扫描过程中应该有很多段错误。所以,我试图引起许多段错误来了解信号,同时也了解一些虚拟内存。这是在 linux 平台上编译为 32 位程序。
我使用 setjmp
和 longjmp
来重新进入我的程序。
我的问题是我的段错误处理程序只被调用一次,然后在下一个段错误时调用默认的段错误处理程序——核心转储处理程序。
这是我的处理程序:
static void hdl (int sig, siginfo_t *siginfo, void *unused){
/* handler is called properly and can read curr_access */
printf("-------------------\n");
printf("handling segfault\n");
printf("curr_access = %d\n", curr_access);
printf("-----------------\n");
switch(curr_access){
case -1:
longjmp(buf, 1);
break;
case 0:
longjmp(buf, 2);
break;
default:
printf("error in hdl\n");
}
}
这是我注册的地方
void set_hndlr(){
printf("------------------\n");
printf("setting handler\n");
printf("-----------------\n");
/* setting up signal handler */
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = hdl;
if (sigaction(SIGSEGV, &sa, NULL) == -1)
printf("error setting segfault hanld");
}
这里是我"test"一个记忆位置:
switch(jmp_code){
/* we haven't gone through testing yet */
case 0:
test_boolean = 1;
break;
/* we've gone through testing and we segfaulted at read */
case 1:
test_boolean = 0;
curr_access = -1;
break;
/* we've gone through testing and we segfaulted at write */
case 2:
test_boolean = 0;
curr_access = 0;
break;
/* if we reach here then there is an error in program logic */
default:
printf("error in programming logic regaurding jmp\n");
exit(-2);
}
if(1 == test_boolean){
/* not accessible */
curr_access = -1;
printf("testing read\n");
/*test read */
curr_cont = *curr_addr;
curr_access = 0;
printf("readable\n");
/*test write */
*curr_addr = curr_cont;
curr_access = 1;
printf("read/write\n");
}
这是一些示例输出:
setting handler
curr_addr = (nil)
jmp_code = 0
testing read
handling segfault
curr_access = -1
jmp_code = 1
base[0].RW = -1
base[0].length = 4096
base[0].start = (nil)
curr_addr = 0x1000
jmp_code = 0
testing read
Segmentation fault (core dumped)
奇怪的是,我可以很好地处理一个段错误,但之后就无法再处理了。如果有任何帮助,我将不胜感激。
在某些系统中,不支持重新分配信号处理程序。我们必须在调用 function_handler.
之后重新分配句柄Unreliable Signals
One problem with these early versions is that the action for a signal was reset to its default each time the signal occurred.
int sig_int();
...
signal(SIGINT, sig_int);
...
sig_int()
{
signal(SIGINT, sig_int);
...
}