Signal Handling

S

Sontu

Hi all,

Consider the following code:

#include<signal.h>
#include<stdio.h>
#include<sys/mman.h>

void handler(int sig)
{
printf("abhay: caught SIGSEGV\n\n");
}

void func(char *buffer)
{

unsigned int start=0;
//to make the starting address in mprotect as page aligned
asm("andl $-4096, %esp");
asm("movl %%esp, %0":"=r"(start));


//raise(SIGSEGV);

printf("Mprotect worked:
%d\n\n",mprotect((void*)start,4096,PROT_READ));

buffer[3]='c';

printf("Mprotect worked:
%d\n\n",mprotect((void*)start,4096,PROT_WRITE|PROT_READ|PROT_EXEC));
}

int main(void)
{
char buffer[10];

if( signal(SIGSEGV, handler)== SIG_ERR )
printf("problem installing new signal handler\n\n");

func(buffer);

printf("into main\n\n");

return 0;
}

My program makes the previous frame as write protected, thus when i am
in func() and i will try to write into the buffer that is allocated in
main(), it will generate SIGSEGV signal that is handled by my handler()

There is something wierd going on that i am not able to understand:

1. If both the mprotect functions are uncommented and i try to write
into the buffer[3]='c', SIGSEGV is generated
handler is called and it starts printing "abhay: caught SIGSEGV"
continuously on the screen until stack overflows. But it should have
printed it once and should have returned back into the func()

2. But if i comment both the mprotect and uncomment "raise(SIGSEGV)" to
generate the SIGSEGV signal explicitly, then this doesn't happen.

I am running the program on RedHat linux 8.0 and using GCC compiler.
Can anyone help me out?

Thanks.
 
J

j

Sontu said:
Hi all,

Consider the following code:

#include<signal.h>
#include<stdio.h>
#include<sys/mman.h>

Inclusion of a non-standard header file.
void handler(int sig)
{
printf("abhay: caught SIGSEGV\n\n");
}

Since when can you call printf from a signal handler?
Undefined behaviour!

<snipped the rest of the garbage>

This is all really off-topic for this newsgroup.

You want comp.unix.programmer
 
R

Richard Bos

Sontu said:
Consider the following code:

#include<signal.h>
#include<stdio.h>
#include<sys/mman.h>

I'd rather not. This is quite off-topic.
//to make the starting address in mprotect as page aligned
asm("andl $-4096, %esp");
asm("movl %%esp, %0":"=r"(start));

And so is this (even worse, in fact)...
printf("Mprotect worked:
%d\n\n",mprotect((void*)start,4096,PROT_READ));

....and this.

Note that calling printf() inside a signal handler causes undefined
behaviour.

As for the rest, I cannot tell whether you have a POSIX problem, a Unix
problem, a Linux problem, or a $Distro problem, so I can't tell you
where it _is_ on-topic - but it isn't here.

Richard
 
J

Jens.Toerring

Sontu said:
Consider the following code:
#include<signal.h>
#include<stdio.h>
#include<sys/mman.h>

Non-standard header.
void handler(int sig)
{
printf("abhay: caught SIGSEGV\n\n");
}

You better don't use non-reentrant functions in signal handlers.
In principle not much more than setting a variable of type
sig_atomic_t is guaranteed to work in a signal handler.
void func(char *buffer)
{
unsigned int start=0;
//to make the starting address in mprotect as page aligned
asm("andl $-4096, %esp");
asm("movl %%esp, %0":"=r"(start));

No we get into completely platform dependent stuff. Don't expect
comments here in clc. Take that to a group that deals with the
platform you're using.
//raise(SIGSEGV);
printf("Mprotect worked:
%d\n\n",mprotect((void*)start,4096,PROT_READ));

Non-standard function.
buffer[3]='c';
printf("Mprotect worked:
%d\n\n",mprotect((void*)start,4096,PROT_WRITE|PROT_READ|PROT_EXEC));
}
int main(void)
{
char buffer[10];
if( signal(SIGSEGV, handler)== SIG_ERR )
printf("problem installing new signal handler\n\n");

printf("into main\n\n");
return 0;
}
My program makes the previous frame as write protected, thus when i am

It may on the platform you are using, but that's nothing related to
the C language, which hasn't frames nor functions or to make them
write protected. Since you seem to be using Linux better take that
question to comp.os.linux.development.apps.

<OT>
Actually, when you get a real SIGSEGV signal, i.e. not one that you
faked using raise(), and don't exit() from the signal handler, flow
of control is passed back to instruction that led to the signal
getting raised. Since nothing has changed to remove the reason for
the signal it gets raised again immediately and you end up in an
infinite loop.
</OT>
Regards, Jens
 
C

CBFalconer

Sontu said:
Consider the following code:

#include<signal.h>
#include<stdio.h>
#include<sys/mman.h>

No such header in Standard C, so we can't consider the code here.

.... snip ...
unsigned int start=0;
//to make the starting address in mprotect as page aligned
asm("andl $-4096, %esp");
asm("movl %%esp, %0":"=r"(start));

and these are syntax errors. 3rd strike. So you better look for a
newsgroup that deals with your particular system and compiler.
 
S

Sontu

I am sorry for troubling you people. I will try to do what some of you
have suggested and if the problem persists, i will post it to another
group comp.unix.programmers.

Thanks a lot for giving your time.

Abhay
 
C

CBFalconer

Sontu said:
I am sorry for troubling you people. I will try to do what some
of you have suggested and if the problem persists, i will post it
to another group comp.unix.programmers.

See my sig. for a way to post sanely via google.

Instead, you might take the attitude that you want to program in a
portable manner, by simply avoiding all the undefined constructs.
Then everybody will know what you are talking about, and can offer
help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top