Reputation: 767
I'm writing a program that scans the process memory and creates a memchunk structures to represent the accessibility of a block of memory. A side effect of this process is to learn how to handle signals, as there should be many segfaults over the course of this scan. So, I'm trying to cause many segfaults to learn about signals while also learning a bit about the virtual memory. This is compiled as a 32bit program on a linux platform.
I make use of setjmp
and longjmp
in order to re-enter my program.
My problem is that my segfault handler is only called once, and then the default segfault handler -- the core dumping one -- is called on the next segfault.
Here is my handler:
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");
}
}
Here is where I register it
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");
}
here is where I "test" a memory location:
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");
}
Here is some example output:
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)
It's strange that I can handle one segfault just fine, but then it wont handle again. I would really appreciate any help.
Upvotes: 0
Views: 348
Reputation: 4041
In some of the systems, it does not support the re-assignig of singal handler. we have to re assign the handle after the calling of that 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);
...
}
Upvotes: 2