ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hello,
I am programming at C at linux and I have a questions regarding signals.
In this program I am doing "illegal action by disposition at *a without allocating it any spot on the memory.
Therefore I am supposed to get Segmentation fault signal by the operating system, Knowing that I am supposed to get this signal, I created signal handler named funct.
My questions are:
1. Why do I need the exit command at funct?
2. If I have no exit command at funct, why do I get only "I am at funct" infinity times and no "testy test" once?
3. Who "summons" the funct() function that many times? And how? It reads *a = printf(...) infinity times?
Here is the code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
void funct();
int *a;
void main(){
int pid;
signal(SIGSEGV, &funct);
*a = printf("testy test.\n");
}
void funct(){
printf("I am at funct.\n");
//exit(0);
}
As I understand it, you're not supposed to continue a program which has raised that particular signal. Pointer errors lead to illegal trespass on memory that has not been assigned to you. The kernel won't allow that. Hence the need for your handler to call exit(). If you don't do that, the kernel will keep resending the signal every time you try to execute your print statement. It won't allow you to actually execute it.
As I understand it, you're not supposed to continue a program which has raised that particular signal. Pointer errors lead to illegal trespass on memory that has not been assigned to you. The kernel won't allow that. Hence the need for your handler to call exit(). If you don't do that, the kernel will keep resending the signal every time you try to execute your print statement. It won't allow you to actually execute it.
Thanks for the reply.
But still, if I do the funct() without exit() command.
You claim that the kernel keeps on signaling me non stop the Segmentation Fault? Why nonstop signals?
He keeps on reading the line *a = printf()... ?
Or he signals the process and awaits for the "handling"?
And if it does keep on reading the line *a = printf()...
Why don't I get output: "Testy test\n I am at funct\n Testy test\n I am at funct\n Testy test\n I am at funct\n........."
Thanks alot!
I think it must have something to do with the fact that signals are asynchronous; they're not handled in sequence like the other instructions but whenever they occur. So the print function code was actually interrupted by the signal. Then, after handling it, the cpu has to go back to where it left off. But that means accessing bad memory again so the signal repeats. Something like that anyway.
The reason you never get any output is that producing it would require the illegal act to actually take place and the kernel won't allow that.
I think it must have something to do with the fact that signals are asynchronous; they're not handled in sequence like the other instructions but whenever they occur. So the print function code was actually interrupted by the signal. Then, after handling it, the cpu has to go back to where it left off. But that means accessing bad memory again so the signal repeats. Something like that anyway.
The reason you never get any output is that producing it would require the illegal act to actually take place and the kernel won't allow that.
Thank you for the reply.
Let me unnderstand what you claim.
"the cpu has to go back to where it left off", meaning? He got back to *a = printf("Testy test"); ? And he does the same thing on a loop?
"the cpu has to go back to where it left off", meaning? He got back to *a = printf("Testy test"); ? And he does the same thing on a loop?
There is no "print statement" in the code the cpu is running. This is compiled code that is being executed, remember. Printf() is a libc function and it must be a pretty complicated one too to do what it does. I bet if you looked at the libc code for print.c, you'd see that it contains all sorts of stuff. So it gets interrupted somewhere in this binary code sequence, almost certainly at a different point each time.
There is no "print statement" in the code the cpu is running. This is compiled code that is being executed, remember. Printf() is a libc function and it must be a pretty complicated one too to do what it does. I bet if you looked at the libc code for print.c, you'd see that it contains all sorts of stuff. So it gets interrupted somewhere in this binary code sequence, almost certainly at a different point each time.
Now I "fix" the problem, I allocate to a enough memory to make this "*a = printf("testy test.\n");" command legal, why do I need to exit?
I fixed the problem, what happens now?
you cannot continue after a sigsegv. The process has fallen into an unexpected state, there is no way to continue the regular execution.
see for example here: https://stackoverflow.com/questions/...fault-handling
You could declare `a` as `volatile`, but it still wouldn't help. The compiler-generated machine code is something like this:
Code:
...
CALL _printf ; return value in R1
LD R2,_a
ST R1,[R2] ; this fails as R2==NULL
...
Now if you 'handle' the segmentation fault, and put some legal value into `a` and then restart the problematic machine instruction, it fails again, as register `R2` still contains zero.
You could declare `a` as `volatile`, but it still wouldn't help. The compiler-generated machine code is something like this:
Code:
...
CALL _printf ; return value in R1
LD R2,_a
ST R1,[R2] ; this fails as R2==NULL
...
Now if you 'handle' the segmentation fault, and put some legal value into `a` and then restart the problematic machine instruction, it fails again, as register `R2` still contains zero.
Very helpful man, thanks alot.
Another question:
Code:
void funct();
int a;
int main()
{
signal(SIGFPE, &funct);
a = 1/0;//loads to register R2 therefore I have 1/0 in R2
printf("ddd\n");
return 0;
}
void funct()
{
printf("done\n");
a=900;//does not matter if I have a=900,I still have 1/0 in R2
exit(0);
}
See the comments I made here, did I understand your explanation correct? Thanks a lot!
void funct();
int a;
int main()
{
signal(SIGFPE, &funct);
a = 1/0;//loads to register R2 therefore I have 1/0 in R2
printf("ddd\n");
return 0;
}
void funct()
{
printf("done\n");
a=900;//does not matter if I have a=900,I still have 1/0 in R2
exit(0);
}
See the comments I made here, did I understand your explanation correct? Thanks a lot!
No. 1/0 is not a valid value, it cannot be assigned to any variable or register. From the other hand a=900 may work. The signal will be generated before that assignment (a=1/0).
No. 1/0 is not a valid value, it cannot be assigned to any variable or register. From the other hand a=900 may work. The signal will be generated before that assignment (a=1/0).
Agreed, then why do I have to send exit from funct?
If I do not put exit() in the funct function, I get infinity loop u know...
I don't really know, but I guess: there is an opcode which will cause the signal. Signal handling means a call to a function. After completion (of that signal handler function) the CPU will return to the original code and try to continue. But it will return to the last successfully executed opcode and will [try to] continue with the next one, which will generate a signal again.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.