This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 7 years ago.
Consider this simple code fragment :
{
if(fork())
{
printf("Parent terminated\n");
}
else
{
char *s = "hello world";
*s = 'H';
printf("child terminated\n");
}
wait(NULL);
return 0;
}
When I compile it I dont get a segmentation fault error as we expect while assigning to *s
The output is :
Parent Terminated ( without printing child terminated)
Now if I remove the two lines char *s=......'H' I get the normal output .Can someone please explain this
First of all, you aren't guarenteed to get a segmentation fault, or any defined behavior, for triggering undefined behavior, such as modifying a string literal. Though on Linux, string literals are put into read-only memory, so modifying them on Linux will usually result in a segmentation fault.
So why doesn't this code trigger a segfault? It does, but you just don't see it, because you forked.
The "Segmentation Fault (core dumped)" message is printed by your shell (ex. bash), when it detects, by calling wait, when the process it spawned terminates with a SIGSEGV (segfault) signal. However, your shell will not receive any notifications about child processes exiting; your parent process will.
Your parent process calls wait to wait and get the exit code when it terminates. If you weren't ignoring the exit code by passing in NULL to wait, you'd probably see that the exit code is -11, or -SIGSEGV.
So it is segfaulting; your parent process is just ignoring the child's notification that it segfaulted.
Firstly, what others said is correct: the behavior is undefined and you cannot depend on any behavior in particular when doing this.
However, I suspect what's happening is that the child actually is having a segmentation fault. However, the familiar "Segmentation fault" message you see in your terminal is actually printed by your shell when something you run seg faults.
But, since this is a child of something you ran, your shell didn't notice. If you have configured core dumps (e.g. ulimit -c unlimited) I expect you will find a core file from the seg faulted child process.
Related
I have written a phone book and my person input like "name-number-type" and if the user give "_" or any other character that is not "-" as seperator the program will crash by seg. fault because i used strtok() to split input. Also if the user gives number that is not proper input like 1232414eree224, my program will crash again. So i just think that if i handle the seg. fault signal in os level may be i can fix this bug. I know that i can write a controller function but i am searching for a new way to deal with like that error. Is there any possible way to do this?
So i just think that if i handle the seg. fault signal in os level may
be i can fix this bug.
It does not seem like a good idea at all, a SIGSEGV handler is not intended to ignore or try to fix the error, they are used to consistently exit your process, e.g. remove the used heap so that there are no memory leaks, to write in a log reporting the error ...
In addition, in the POSIX standard:
The behavior of a process is undefined after it returns normally from
a signal-catching function for a [XSI] SIGBUS, SIGFPE, SIGILL, or
SIGSEGV signal that was not generated by kill(), [RTS] sigqueue(), or
raise().
When I try to do the command "/bin/kill -11 0" on bash, tcsh or zsh, it doesn't segfault but when I try to do it in mine, it does.
So I must have something I didn't handle.
Do you know what it can be ?
Thanks.
Your program doesn't actually segfault when it sends itself signal 11.
If the execution of a programs results in a "segment fault" (that is, the program performs an illegal memory reference), then the operating system sends the program SIGSEGV (signal 11 on Linux). The program cannot distinguish between a SIGSEGV sent by the operating system as the result of a program fault and a SIGSEGV sent by a call to raise or kill, possibly from another process, so it will respond as though there had been a real program error.
If you want to protect your shell from signals sent to pid 0 from a child process, you need to make sure that your child processes are in a different process group by calling setpgid in the child after the fork.
By default, a program is terminated by SIGSEGV. By default, the shell which invoked the program will then report that the program was terminated by SIGSEGV. This is popularly known as "segfaulting", but as indicated above, it might not have been the result of a real program fault.
If you want your program to do something else, you have to catch signal SIGSEGV with a signal handler; for example, if some cleanup needs to be done before the program terminates. Most shells (and databases) do that, but it is rarely necessary in user code.
Note: Signal 11 is SIGSEGV on Linux, but there is no guarantee that SIGSEGV will be signal 11 on a different OS (or even in some future version of Linux). You should always use the name of the signal rather than the number.
When running my code, it crashes and says "Segmentation fault".
However, when I run through it in gdb, it crashes due to a SIGABRT error not a SIGSEGV.
Are there other signals that also "map" to a general Segmentation fault error on the terminal?
abort() sends the calling process the SIGABRT signal, this is how SIGABRT or Signal 6 is generated. Also, most "assert" implementations make use of SIGABRT in case of a failed assert.
abort() is usually called by library functions which detect an internal error or some seriously broken constraint. For example malloc() will call abort() if its internal structures are damaged by a heap overflow.
SIGSEGV or Signal 11, officially know as "segmentation fault", means that the program accessed a memory location that was not assigned. That's usually a bug in the program. So if you're writing your own program, that's the most likely cause. otherwise I do not see any other signal will create segmentation fault in a program.
I am teaching myself to use gdb and am running some random tests. It may be worth mentioning that I am using a portable installation of MinGW on Windows 7 x64. I've created a program which I know results in a stack overflow, and as I run through it in gdb I first get two SIGSEGV signals (no surprise), and then it exits (again no surprise) with code 030000000375.
Program received signal SIGSEGV, Segmentation fault.
Program received signal SIGSEGV, Segmentation fault.
Program exited with code 030000000375.
Curiosity getting the best of me... what the heck is that code? I googled it and found very little.
Thanks!
UPDATE: For reference I tried the same program on Ubuntu, and the results are slightly different:
Program received signal SIGSEGV, Segmentation fault.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
gdb prints out the exit code in octal format. Not obvious, but indicated by the leading 0.
So 030000000375 is 0xC00000FD in hex, which makes the code look much more common to a windows programmer.
0xC00000FD is STATUS_STACK_OVERFLOW and should be defined in ntstatus.h.
What happens when two threads of the same process running on different logical cpu hit a seg fault?
Default action is for the process to exit. If you handle the segfault, I suppose you could try to arrange for just the thread where it happened to terminate. However, since the only things which cause a segfault to occur naturally (as opposed to raise or kill) stem from undefined behavior, the program is in an indeterminate state and you can't rely on being able to recover anything.
Normal handling of a Segmentation Fault involves the termination of the process. That means that both of them are terminated.
I think the default action on all major OSes is to terminate the process. However, you could conceivably install (e.g using signal) an alternate handler that only terminated the thread. Of course, once you have a segmentation fault, behavior typically becomes undefined, and attempting to continue is risky.
Signals generated due to illegal execution are handled synchronously by the kernel. So even if both the threads generate seg fault at the same time, only one gets thru'.
The segfault handler is called for the process. If you don't do anything special, the OS will kill the process and reclaim its resources.