LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-13-2022, 03:29 AM   #1
yarin0600
LQ Newbie
 
Registered: Apr 2022
Posts: 7

Rep: Reputation: 0
Signal Handler question


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);
}
Thanks alot.
 
Old 04-13-2022, 04:46 AM   #2
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,597
Blog Entries: 19

Rep: Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455
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.
 
Old 04-13-2022, 04:53 AM   #3
yarin0600
LQ Newbie
 
Registered: Apr 2022
Posts: 7

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by hazel View Post
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!
 
Old 04-13-2022, 05:16 AM   #4
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,597
Blog Entries: 19

Rep: Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455
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.
 
Old 04-13-2022, 05:19 AM   #5
yarin0600
LQ Newbie
 
Registered: Apr 2022
Posts: 7

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by hazel View Post
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?
 
Old 04-13-2022, 05:26 AM   #6
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,597
Blog Entries: 19

Rep: Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455
Quote:
Originally Posted by yarin0600 View Post
"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.
 
Old 04-13-2022, 05:33 AM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,901

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
A basic explanation: https://linuxhint.com/signal_handler...ming_language/
 
Old 04-13-2022, 05:33 AM   #8
yarin0600
LQ Newbie
 
Registered: Apr 2022
Posts: 7

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by hazel View Post
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.
Then let me ask you that:
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(){
	a = (int*)malloc(sizeof(int));
	//exit(0);
}
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?
 
Old 04-13-2022, 05:40 AM   #9
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,901

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
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

Last edited by pan64; 04-13-2022 at 05:48 AM.
 
Old 04-13-2022, 06:29 AM   #10
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,868
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
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.
 
Old 04-13-2022, 06:57 AM   #11
yarin0600
LQ Newbie
 
Registered: Apr 2022
Posts: 7

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by NevemTeve View Post
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!
 
Old 04-13-2022, 07:04 AM   #12
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,901

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
Quote:
Originally Posted by yarin0600 View Post
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!
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).
 
Old 04-13-2022, 07:27 AM   #13
yarin0600
LQ Newbie
 
Registered: Apr 2022
Posts: 7

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by pan64 View Post
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...
 
Old 04-13-2022, 07:38 AM   #14
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,901

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
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.
 
Old 04-13-2022, 01:02 PM   #15
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,868
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Might be related: http://www.csl.mtu.edu/cs4411.ck/www...oto/sig-1.html
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
SIGSEGV handler (segmentation fauld handler) myp Programming 8 03-08-2011 02:17 PM
user-define signal handler & coredump for signal 11(SIGSEGV) Alexlun Linux - Software 2 05-24-2009 06:37 AM
How to reinstall a signal handler after exec ( Strange behaviour in signal handling ) lali.p Programming 0 09-20-2008 12:11 PM
<0>Kernel panic: Aiee, killing interrupt handler! In interrupt handler - not syncing mrb Linux - Newbie 2 01-09-2005 09:47 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:30 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration